Tests: show any and all actual/expected values
[jquery.git] / test / runner / reporter.js
blobc70c6d80c17be4cb03827cd94548d33ebb92971f
1 import chalk from "chalk";
2 import { getBrowserString } from "./lib/getBrowserString.js";
3 import { prettyMs } from "./lib/prettyMs.js";
4 import * as Diff from "diff";
6 export function reportTest( test, reportId, { browser, headless } ) {
7         if ( test.status === "passed" ) {
9                 // Write to console without newlines
10                 process.stdout.write( "." );
11                 return;
12         }
14         let message = `${ chalk.bold( `${ test.suiteName }: ${ test.name }` ) }`;
15         message += `\nTest ${ test.status } on ${ chalk.yellow(
16                 getBrowserString( browser, headless )
17         ) } (${ chalk.bold( reportId ) }).`;
19         // test.assertions only contains passed assertions;
20         // test.errors contains all failed asssertions
21         if ( test.errors.length ) {
22                 for ( const error of test.errors ) {
23                         message += "\n";
24                         if ( error.message ) {
25                                 message += `\n${ error.message }`;
26                         }
27                         message += `\n${ chalk.gray( error.stack ) }`;
28                         if ( "expected" in error && "actual" in error ) {
29                                 message += `\nexpected: ${ JSON.stringify( error.expected ) }`;
30                                 message += `\nactual: ${ JSON.stringify( error.actual ) }`;
31                                 let diff;
33                                 if (
34                                         Array.isArray( error.expected ) &&
35                                         Array.isArray( error.actual )
36                                 ) {
38                                         // Diff arrays
39                                         diff = Diff.diffArrays( error.expected, error.actual );
40                                 } else if (
41                                         typeof error.expected === "object" &&
42                                         typeof error.actual === "object"
43                                 ) {
45                                         // Diff objects
46                                         diff = Diff.diffJson( error.expected, error.actual );
47                                 } else if (
48                                         typeof error.expected === "number" &&
49                                         typeof error.expected === "number"
50                                 ) {
52                                         // Diff numbers directly
53                                         const value = error.actual - error.expected;
54                                         if ( value > 0 ) {
55                                                 diff = [ { added: true, value: `+${ value }` } ];
56                                         } else {
57                                                 diff = [ { removed: true, value: `${ value }` } ];
58                                         }
59                                 } else if (
60                                         typeof error.expected === "boolean" &&
61                                         typeof error.actual === "boolean"
62                                 ) {
64                                         // Show the actual boolean in red
65                                         diff = [ { removed: true, value: `${ error.actual }` } ];
66                                 } else {
68                                         // Diff everything else as characters
69                                         diff = Diff.diffChars( `${ error.expected }`, `${ error.actual }` );
70                                 }
72                                 message += "\n";
73                                 message += diff
74                                         .map( ( part ) => {
75                                                 if ( part.added ) {
76                                                         return chalk.green( part.value );
77                                                 }
78                                                 if ( part.removed ) {
79                                                         return chalk.red( part.value );
80                                                 }
81                                                 return chalk.gray( part.value );
82                                         } )
83                                         .join( "" );
84                         }
85                 }
86         }
88         console.log( `\n\n${ message }` );
90         // Only return failed messages
91         if ( test.status === "failed" ) {
92                 return message;
93         }
96 export function reportEnd( result, reportId, { browser, headless, modules } ) {
97         console.log(
98                 `\n\nTests for ${ chalk.yellow( modules.join( ", " ) ) } on ${ chalk.yellow(
99                         getBrowserString( browser, headless )
100                 ) } finished in ${ prettyMs( result.runtime ) } (${ chalk.bold( reportId ) }).`
101         );
102         console.log(
103                 ( result.status !== "passed" ?
104                         `${ chalk.red( result.testCounts.failed ) } failed. ` :
105                         "" ) +
106                         `${ chalk.green( result.testCounts.total ) } passed. ` +
107                         `${ chalk.gray( result.testCounts.skipped ) } skipped.`
108         );
109         return result.testCounts;