@@ -15,59 +15,76 @@ assert.deepEqual = function(actual, expected, message) {
15
15
} ;
16
16
17
17
assert . deepEqual . format = ( function ( ) {
18
+ function lazyStringFactory ( strings , ...subs ) {
19
+ return function ( ...mappers ) {
20
+ assert ( mappers . length === subs . length , 'mappers must be paired with substitutions' ) ;
21
+ let toString = ( ) => {
22
+ let mappedSubs = subs . map ( ( sub , i ) => mappers [ i ] ( sub ) ) ;
23
+ return strings . map ( ( str , i ) => `${ i === 0 ? '' : mappedSubs [ i - 1 ] } ${ str } ` ) . join ( '' ) ;
24
+ } ;
25
+ return { toString } ;
26
+ } ;
27
+ }
28
+ let renderUsage = usage => usage . used ? ` as #${ usage . id } ` : '' ;
29
+
18
30
return function format ( value , seen ) {
19
31
switch ( typeof value ) {
20
32
case 'string' :
21
33
return typeof JSON !== "undefined" ? JSON . stringify ( value ) : `"${ value } "` ;
22
34
case 'bigint' :
23
35
return `${ value } n` ;
24
36
case 'boolean' :
25
- case 'symbol' :
26
37
case 'undefined' :
27
38
case 'number' :
28
39
return value === 0 && 1 / value === - Infinity ? '-0' : String ( value ) ;
40
+ case 'symbol' :
29
41
case 'function' :
30
- return `function${ value . name ? ` ${ String ( value . name ) } ` : '' } ` ;
31
42
case 'object' :
32
43
if ( value === null ) return 'null' ;
33
- if ( value instanceof Date ) return `Date("${ value . toISOString ( ) } ")` ;
34
- if ( value instanceof Error ) return `${ value . name || 'Error' } ("${ value . message } ")` ;
35
- if ( value instanceof RegExp ) return value . toString ( ) ;
36
- if ( ! seen ) {
37
- seen = {
38
- counter : 0 ,
39
- map : new Map ( )
40
- } ;
41
- }
42
-
43
- let usage = seen . map . get ( value ) ;
44
- if ( usage ) {
45
- usage . used = true ;
46
- return `ref #${ usage . id } ` ;
47
- }
48
-
49
- usage = { id : ++ seen . counter , used : false } ;
50
- seen . map . set ( value , usage ) ;
51
-
52
- if ( typeof Set !== "undefined" && value instanceof Set ) {
53
- return `Set {${ Array . from ( value ) . map ( value => assert . deepEqual . format ( value , seen ) ) . join ( ', ' ) } }${ usage . used ? ` as #${ usage . id } ` : '' } ` ;
54
- }
55
- if ( typeof Map !== "undefined" && value instanceof Map ) {
56
- return `Map {${ Array . from ( value ) . map ( pair => `${ assert . deepEqual . format ( pair [ 0 ] , seen ) } => ${ assert . deepEqual . format ( pair [ 1 ] , seen ) } ` ) . join ( ', ' ) } }${ usage . used ? ` as #${ usage . id } ` : '' } ` ;
57
- }
58
- if ( Array . isArray ? Array . isArray ( value ) : value instanceof Array ) {
59
- return `[${ value . map ( value => assert . deepEqual . format ( value , seen ) ) . join ( ', ' ) } ]${ usage . used ? ` as #${ usage . id } ` : '' } ` ;
60
- }
61
- let tag = Symbol . toStringTag && Symbol . toStringTag in value
62
- ? value [ Symbol . toStringTag ]
63
- : 'Object' ;
64
- if ( tag === 'Object' && Object . getPrototypeOf ( value ) === null ) {
65
- tag = '[Object: null prototype]' ;
66
- }
67
- return `${ tag ? `${ tag } ` : '' } {${ Object . keys ( value ) . map ( key => `${ key . toString ( ) } : ${ assert . deepEqual . format ( value [ key ] , seen ) } ` ) . join ( ', ' ) } }${ usage . used ? ` as #${ usage . id } ` : '' } ` ;
44
+ break ;
68
45
default :
69
46
return typeof value ;
70
47
}
48
+
49
+ if ( ! seen ) {
50
+ seen = {
51
+ counter : 0 ,
52
+ map : new Map ( )
53
+ } ;
54
+ }
55
+ let usage = seen . map . get ( value ) ;
56
+ if ( usage ) {
57
+ usage . used = true ;
58
+ return `ref #${ usage . id } ` ;
59
+ }
60
+ usage = { id : ++ seen . counter , used : false } ;
61
+ seen . map . set ( value , usage ) ;
62
+
63
+ if ( typeof value === 'function' ) {
64
+ return lazyStringFactory `function${ value . name ? ` ${ String ( value . name ) } ` : '' } ${ usage } ` ( String , renderUsage ) ;
65
+ } else if ( typeof value !== 'object' ) {
66
+ return lazyStringFactory `${ value } ${ usage } ` ( String , renderUsage ) ;
67
+ } else if ( Array . isArray ? Array . isArray ( value ) : value instanceof Array ) {
68
+ return lazyStringFactory `[${ value . map ( value => assert . deepEqual . format ( value , seen ) ) } ]${ usage } ` ( arr => arr . join ( ', ' ) , renderUsage ) ;
69
+ } else if ( value instanceof Date ) {
70
+ return lazyStringFactory `Date(${ assert . deepEqual . format ( value . toISOString ( ) , seen ) } )${ usage } ` ( String , renderUsage ) ;
71
+ } else if ( value instanceof Error ) {
72
+ return lazyStringFactory `${ value . name || 'Error' } (${ assert . deepEqual . format ( value . message , seen ) } )${ usage } ` ( String , String , renderUsage ) ;
73
+ } else if ( value instanceof RegExp ) {
74
+ return lazyStringFactory `${ value } ${ usage } ` ( String , renderUsage ) ;
75
+ } else if ( typeof Map !== "undefined" && value instanceof Map ) {
76
+ return lazyStringFactory `Map {${ Array . from ( value ) . map ( pair => `${ assert . deepEqual . format ( pair [ 0 ] , seen ) } => ${ assert . deepEqual . format ( pair [ 1 ] , seen ) } ` ) } }${ usage } ` ( arr => arr . join ( ', ' ) , renderUsage ) ;
77
+ } else if ( typeof Set !== "undefined" && value instanceof Set ) {
78
+ return lazyStringFactory `Set {${ Array . from ( value ) . map ( value => assert . deepEqual . format ( value , seen ) ) } }${ usage } ` ( arr => arr . join ( ', ' ) , renderUsage ) ;
79
+ }
80
+
81
+ let tag = Symbol . toStringTag && Symbol . toStringTag in value
82
+ ? value [ Symbol . toStringTag ]
83
+ : 'Object' ;
84
+ if ( tag === 'Object' && Object . getPrototypeOf ( value ) === null ) {
85
+ tag = '[Object: null prototype]' ;
86
+ }
87
+ return lazyStringFactory `${ tag ? `${ tag } ` : '' } {${ Object . keys ( value ) . map ( key => `${ key . toString ( ) } : ${ assert . deepEqual . format ( value [ key ] , seen ) } ` ) } }${ usage } ` ( String , arr => arr . join ( ', ' ) , renderUsage ) ;
71
88
} ;
72
89
} ) ( ) ;
73
90
0 commit comments