@@ -78,22 +78,164 @@ function makeNodeError(Base) {
78
78
} ;
79
79
}
80
80
81
+ function createErrDiff ( actual , expected , operator ) {
82
+ var other = '' ;
83
+ var res = '' ;
84
+ var lastPos = 0 ;
85
+ var end = '' ;
86
+ var skipped = false ;
87
+ const util = lazyUtil ( ) ;
88
+ const actualLines = util
89
+ . inspect ( actual , { compact : false } ) . split ( '\n' ) ;
90
+ const expectedLines = util
91
+ . inspect ( expected , { compact : false } ) . split ( '\n' ) ;
92
+ const msg = `Input A expected to ${ operator } input B:\n` +
93
+ '\u001b[32m+ expected\u001b[39m \u001b[31m- actual\u001b[39m' ;
94
+ const skippedMsg = ' ... Lines skipped' ;
95
+
96
+ // Remove all ending lines that match (this optimizes the output for
97
+ // readability by reducing the number of total changed lines).
98
+ var a = actualLines [ actualLines . length - 1 ] ;
99
+ var b = expectedLines [ expectedLines . length - 1 ] ;
100
+ var i = 0 ;
101
+ while ( a === b ) {
102
+ if ( i ++ < 2 ) {
103
+ end = `\n ${ a } ${ end } ` ;
104
+ } else {
105
+ other = a ;
106
+ }
107
+ actualLines . pop ( ) ;
108
+ expectedLines . pop ( ) ;
109
+ a = actualLines [ actualLines . length - 1 ] ;
110
+ b = expectedLines [ expectedLines . length - 1 ] ;
111
+ }
112
+ if ( i > 3 ) {
113
+ end = `\n...${ end } ` ;
114
+ skipped = true ;
115
+ }
116
+ if ( other !== '' ) {
117
+ end = `\n ${ other } ${ end } ` ;
118
+ other = '' ;
119
+ }
120
+
121
+ const maxLines = Math . max ( actualLines . length , expectedLines . length ) ;
122
+ var printedLines = 0 ;
123
+ for ( i = 0 ; i < maxLines ; i ++ ) {
124
+ // Only extra expected lines exist
125
+ const cur = i - lastPos ;
126
+ if ( actualLines . length < i + 1 ) {
127
+ if ( cur > 1 && i > 2 ) {
128
+ if ( cur > 4 ) {
129
+ res += '\n...' ;
130
+ skipped = true ;
131
+ } else if ( cur > 3 ) {
132
+ res += `\n ${ expectedLines [ i - 2 ] } ` ;
133
+ printedLines ++ ;
134
+ }
135
+ res += `\n ${ expectedLines [ i - 1 ] } ` ;
136
+ printedLines ++ ;
137
+ }
138
+ lastPos = i ;
139
+ other += `\n\u001b[32m+\u001b[39m ${ expectedLines [ i ] } ` ;
140
+ printedLines ++ ;
141
+ // Only extra actual lines exist
142
+ } else if ( expectedLines . length < i + 1 ) {
143
+ if ( cur > 1 && i > 2 ) {
144
+ if ( cur > 4 ) {
145
+ res += '\n...' ;
146
+ skipped = true ;
147
+ } else if ( cur > 3 ) {
148
+ res += `\n ${ actualLines [ i - 2 ] } ` ;
149
+ printedLines ++ ;
150
+ }
151
+ res += `\n ${ actualLines [ i - 1 ] } ` ;
152
+ printedLines ++ ;
153
+ }
154
+ lastPos = i ;
155
+ res += `\n\u001b[31m-\u001b[39m ${ actualLines [ i ] } ` ;
156
+ printedLines ++ ;
157
+ // Lines diverge
158
+ } else if ( actualLines [ i ] !== expectedLines [ i ] ) {
159
+ if ( cur > 1 && i > 2 ) {
160
+ if ( cur > 4 ) {
161
+ res += '\n...' ;
162
+ skipped = true ;
163
+ } else if ( cur > 3 ) {
164
+ res += `\n ${ actualLines [ i - 2 ] } ` ;
165
+ printedLines ++ ;
166
+ }
167
+ res += `\n ${ actualLines [ i - 1 ] } ` ;
168
+ printedLines ++ ;
169
+ }
170
+ lastPos = i ;
171
+ res += `\n\u001b[31m-\u001b[39m ${ actualLines [ i ] } ` ;
172
+ other += `\n\u001b[32m+\u001b[39m ${ expectedLines [ i ] } ` ;
173
+ printedLines += 2 ;
174
+ // Lines are identical
175
+ } else {
176
+ res += other ;
177
+ other = '' ;
178
+ if ( cur === 1 || i === 0 ) {
179
+ res += `\n ${ actualLines [ i ] } ` ;
180
+ printedLines ++ ;
181
+ }
182
+ }
183
+ // Inspected object to big (Show ~20 rows max)
184
+ if ( printedLines > 20 && i < maxLines - 2 ) {
185
+ return `${ msg } ${ skippedMsg } \n${ res } \n...${ other } \n...` ;
186
+ }
187
+ }
188
+ return `${ msg } ${ skipped ? skippedMsg : '' } \n${ res } ${ other } ${ end } ` ;
189
+ }
190
+
81
191
class AssertionError extends Error {
82
192
constructor ( options ) {
83
193
if ( typeof options !== 'object' || options === null ) {
84
194
throw new exports . TypeError ( 'ERR_INVALID_ARG_TYPE' , 'options' , 'Object' ) ;
85
195
}
86
- var { actual, expected, message, operator, stackStartFn } = options ;
87
- if ( message ) {
196
+ var {
197
+ actual,
198
+ expected,
199
+ message,
200
+ operator,
201
+ stackStartFn,
202
+ errorDiff = 0
203
+ } = options ;
204
+
205
+ if ( message != null ) {
88
206
super ( message ) ;
89
207
} else {
90
208
const util = lazyUtil ( ) ;
91
209
if ( actual && actual . stack && actual instanceof Error )
92
210
actual = `${ actual . name } : ${ actual . message } ` ;
93
211
if ( expected && expected . stack && expected instanceof Error )
94
212
expected = `${ expected . name } : ${ expected . message } ` ;
95
- super ( `${ util . inspect ( actual ) . slice ( 0 , 128 ) } ` +
96
- `${ operator } ${ util . inspect ( expected ) . slice ( 0 , 128 ) } ` ) ;
213
+
214
+ if ( errorDiff === 0 ) {
215
+ let res = util . inspect ( actual ) ;
216
+ let other = util . inspect ( expected ) ;
217
+ if ( res . length > 128 )
218
+ res = `${ res . slice ( 0 , 125 ) } ...` ;
219
+ if ( other . length > 128 )
220
+ other = `${ other . slice ( 0 , 125 ) } ...` ;
221
+ super ( `${ res } ${ operator } ${ other } ` ) ;
222
+ } else if ( errorDiff === 1 ) {
223
+ // In case the objects are equal but the operator requires unequal, show
224
+ // the first object and say A equals B
225
+ const res = util
226
+ . inspect ( actual , { compact : false } ) . split ( '\n' ) ;
227
+
228
+ if ( res . length > 20 ) {
229
+ res [ 19 ] = '...' ;
230
+ while ( res . length > 20 ) {
231
+ res . pop ( ) ;
232
+ }
233
+ }
234
+ // Only print a single object.
235
+ super ( `Identical input passed to ${ operator } :\n${ res . join ( '\n' ) } ` ) ;
236
+ } else {
237
+ super ( createErrDiff ( actual , expected , operator ) ) ;
238
+ }
97
239
}
98
240
99
241
this . generatedMessage = ! message ;
0 commit comments