1 | var utils = require('./utils');
|
2 | var isRegExp = utils.isRegExp;
|
3 | var leftPad = utils.leftPad;
|
4 | var arrayChanges = require('array-changes');
|
5 | var leven = require('leven');
|
6 | var detectIndent = require('detect-indent');
|
7 | var defaultDepth = require('./defaultDepth');
|
8 | var AssertionString = require('./AssertionString');
|
9 |
|
10 | module.exports = function(expect) {
|
11 | expect.addType({
|
12 | name: 'wrapperObject',
|
13 | identify: false,
|
14 | equal: function equal(a, b, equal$1) {
|
15 | return a === b || equal$1(this.unwrap(a), this.unwrap(b));
|
16 | },
|
17 | inspect: function inspect(value, depth, output, inspect$1) {
|
18 | output.append(this.prefix(output.clone(), value));
|
19 | output.append(inspect$1(this.unwrap(value), depth));
|
20 | output.append(this.suffix(output.clone(), value));
|
21 | return output;
|
22 | },
|
23 | diff: function diff(actual, expected, output, diff$1, inspect) {
|
24 | output.inline = true;
|
25 | actual = this.unwrap(actual);
|
26 | expected = this.unwrap(expected);
|
27 | var comparison = diff$1(actual, expected);
|
28 | var prefixOutput = this.prefix(output.clone(), actual);
|
29 | var suffixOutput = this.suffix(output.clone(), actual);
|
30 | if (comparison && comparison.inline) {
|
31 | return output
|
32 | .append(prefixOutput)
|
33 | .append(comparison)
|
34 | .append(suffixOutput);
|
35 | } else {
|
36 | return output
|
37 | .append(prefixOutput)
|
38 | .nl()
|
39 | .indentLines()
|
40 | .i()
|
41 | .block(function() {
|
42 | this.append(inspect(actual))
|
43 | .sp()
|
44 | .annotationBlock(function() {
|
45 | this.shouldEqualError(expected, inspect);
|
46 | if (comparison) {
|
47 | this.nl(2).append(comparison);
|
48 | }
|
49 | });
|
50 | })
|
51 | .nl()
|
52 | .outdentLines()
|
53 | .append(suffixOutput);
|
54 | }
|
55 | }
|
56 | });
|
57 |
|
58 | if (typeof Symbol === 'function') {
|
59 | expect.addType({
|
60 | name: 'Symbol',
|
61 | identify: function identify(obj) {
|
62 | return typeof obj === 'symbol';
|
63 | },
|
64 | inspect: function inspect(obj, depth, output, inspect$1) {
|
65 | return output
|
66 | .jsKeyword('Symbol')
|
67 | .text('(')
|
68 | .singleQuotedString(obj.toString().replace(/^Symbol\(|\)$/g, ''))
|
69 | .text(')');
|
70 | }
|
71 | });
|
72 | }
|
73 |
|
74 | expect.addType({
|
75 | name: 'object',
|
76 | indent: true,
|
77 | forceMultipleLines: false,
|
78 | identify: function identify(obj) {
|
79 | return obj && typeof obj === 'object';
|
80 | },
|
81 | prefix: function prefix(output, obj) {
|
82 | var constructor = obj.constructor;
|
83 | var constructorName =
|
84 | constructor &&
|
85 | typeof constructor === 'function' &&
|
86 | constructor !== Object &&
|
87 | utils.getFunctionName(constructor);
|
88 | if (constructorName && constructorName !== 'Object') {
|
89 | output.text((constructorName + "("));
|
90 | }
|
91 | return output.text('{');
|
92 | },
|
93 | property: function property(output, key, inspectedValue, isArrayLike) {
|
94 | return output.propertyForObject(key, inspectedValue, isArrayLike);
|
95 | },
|
96 | suffix: function suffix(output, obj) {
|
97 | output.text('}');
|
98 | var constructor = obj.constructor;
|
99 | var constructorName =
|
100 | constructor &&
|
101 | typeof constructor === 'function' &&
|
102 | constructor !== Object &&
|
103 | utils.getFunctionName(constructor);
|
104 | if (constructorName && constructorName !== 'Object') {
|
105 | output.text(')');
|
106 | }
|
107 | return output;
|
108 | },
|
109 | delimiter: function delimiter(output, i, length) {
|
110 | if (i < length - 1) {
|
111 | output.text(',');
|
112 | }
|
113 | return output;
|
114 | },
|
115 | getKeys: Object.getOwnPropertySymbols
|
116 | ? function (obj) {
|
117 | var keys = Object.getOwnPropertyNames(obj);
|
118 | var symbols = Object.getOwnPropertySymbols(obj);
|
119 | if (symbols.length > 0) {
|
120 | return keys.concat(symbols);
|
121 | } else {
|
122 | return keys;
|
123 | }
|
124 | }
|
125 | : Object.getOwnPropertyNames,
|
126 |
|
127 |
|
128 | keyComparator:
|
129 | typeof Symbol === 'function'
|
130 | ? function (a, b) {
|
131 | var aIsSymbol, bIsSymbol;
|
132 | var aString = a;
|
133 | var bString = b;
|
134 | aIsSymbol = typeof a === 'symbol';
|
135 | bIsSymbol = typeof b === 'symbol';
|
136 | if (aIsSymbol) {
|
137 | if (bIsSymbol) {
|
138 | aString = a.toString();
|
139 | bString = b.toString();
|
140 | } else {
|
141 | return 1;
|
142 | }
|
143 | } else if (bIsSymbol) {
|
144 | return -1;
|
145 | }
|
146 |
|
147 | if (aString < bString) {
|
148 | return -1;
|
149 | } else if (aString > bString) {
|
150 | return 1;
|
151 | }
|
152 |
|
153 | return 0;
|
154 | }
|
155 | : undefined,
|
156 | equal: function equal(a, b, equal$1) {
|
157 | return utils.checkObjectEqualityUsingType(a, b, this, equal$1);
|
158 | },
|
159 | hasKey: function hasKey(obj, key, own) {
|
160 | if (own) {
|
161 | return Object.prototype.hasOwnProperty.call(obj, key);
|
162 | } else {
|
163 | return key in obj;
|
164 | }
|
165 | },
|
166 | inspect: function inspect(obj, depth, output, inspect$1) {
|
167 | var keys = this.getKeys(obj);
|
168 | if (keys.length === 0) {
|
169 | this.prefix(output, obj);
|
170 | this.suffix(output, obj);
|
171 | return output;
|
172 | }
|
173 | var type = this;
|
174 | var inspectedItems = keys.map(function (key, index) {
|
175 | var propertyDescriptor =
|
176 | Object.getOwnPropertyDescriptor &&
|
177 | Object.getOwnPropertyDescriptor(obj, key);
|
178 | var hasGetter = propertyDescriptor && propertyDescriptor.get;
|
179 | var hasSetter = propertyDescriptor && propertyDescriptor.set;
|
180 | var propertyOutput = output.clone();
|
181 | if (hasSetter && !hasGetter) {
|
182 | propertyOutput.text('set').sp();
|
183 | }
|
184 |
|
185 | var value;
|
186 | if (hasSetter && !hasGetter) {
|
187 | value = hasSetter;
|
188 | } else {
|
189 | value = type.valueForKey(obj, key);
|
190 | }
|
191 |
|
192 | var inspectedValue = inspect$1(value);
|
193 | if (value && value._expectIt) {
|
194 | inspectedValue = output.clone().block(inspectedValue);
|
195 | }
|
196 | type.property(propertyOutput, key, inspectedValue);
|
197 |
|
198 | propertyOutput.amend(
|
199 | type.delimiter(output.clone(), index, keys.length)
|
200 | );
|
201 |
|
202 | if (hasGetter && hasSetter) {
|
203 | propertyOutput.sp().jsComment('/* getter/setter */');
|
204 | } else if (hasGetter) {
|
205 | propertyOutput.sp().jsComment('/* getter */');
|
206 | }
|
207 |
|
208 | return propertyOutput;
|
209 | });
|
210 |
|
211 | var maxLineLength =
|
212 | output.preferredWidth - (depth === Infinity ? 0 : depth) * 2 - 2;
|
213 | var width = 0;
|
214 | var compact =
|
215 | inspectedItems.length > 5 ||
|
216 | inspectedItems.every(function (inspectedItem) {
|
217 | if (inspectedItem.isMultiline()) {
|
218 | return false;
|
219 | }
|
220 | width += inspectedItem.size().width;
|
221 | return width < maxLineLength;
|
222 | });
|
223 |
|
224 | var itemsOutput = output.clone();
|
225 | if (compact) {
|
226 | var currentLineLength = 0;
|
227 | inspectedItems.forEach(function (inspectedItem, index) {
|
228 | var size = inspectedItem.size();
|
229 | currentLineLength += size.width + 1;
|
230 | if (index > 0) {
|
231 | if (size.height === 1 && currentLineLength < maxLineLength) {
|
232 | itemsOutput.sp();
|
233 | } else {
|
234 | itemsOutput.nl();
|
235 | currentLineLength = size.width;
|
236 | }
|
237 |
|
238 | if (size.height > 1) {
|
239 |
|
240 | currentLineLength = maxLineLength;
|
241 | }
|
242 | }
|
243 | itemsOutput.append(inspectedItem);
|
244 | });
|
245 | } else {
|
246 | inspectedItems.forEach(function (inspectedItem, index) {
|
247 | if (index > 0) {
|
248 | itemsOutput.nl();
|
249 | }
|
250 | itemsOutput.append(inspectedItem);
|
251 | });
|
252 | }
|
253 |
|
254 | var prefixOutput = this.prefix(output.clone(), obj);
|
255 | var suffixOutput = this.suffix(output.clone(), obj);
|
256 | output.append(prefixOutput);
|
257 | if (this.forceMultipleLines || itemsOutput.isMultiline()) {
|
258 | if (!prefixOutput.isEmpty()) {
|
259 | output.nl();
|
260 | }
|
261 | if (this.indent) {
|
262 | output.indentLines().i();
|
263 | }
|
264 | output.block(itemsOutput);
|
265 | if (this.indent) {
|
266 | output.outdentLines();
|
267 | }
|
268 | if (!suffixOutput.isEmpty()) {
|
269 | output.nl();
|
270 | }
|
271 | } else {
|
272 | output
|
273 | .sp(prefixOutput.isEmpty() ? 0 : 1)
|
274 | .append(itemsOutput)
|
275 | .sp(suffixOutput.isEmpty() ? 0 : 1);
|
276 | }
|
277 | return output.append(suffixOutput);
|
278 | },
|
279 | diff: function diff(actual, expected, output, diff$1, inspect, equal) {
|
280 | if (actual.constructor !== expected.constructor) {
|
281 | return output
|
282 | .text('Mismatching constructors ')
|
283 | .text(
|
284 | (actual.constructor && utils.getFunctionName(actual.constructor)) ||
|
285 | actual.constructor
|
286 | )
|
287 | .text(' should be ')
|
288 | .text(
|
289 | (expected.constructor &&
|
290 | utils.getFunctionName(expected.constructor)) ||
|
291 | expected.constructor
|
292 | );
|
293 | }
|
294 |
|
295 | output.inline = true;
|
296 | var actualKeys = this.getKeys(actual);
|
297 | var expectedKeys = this.getKeys(expected);
|
298 | var keys = this.uniqueKeys(actualKeys, expectedKeys);
|
299 | var prefixOutput = this.prefix(output.clone(), actual);
|
300 | output.append(prefixOutput).nl(prefixOutput.isEmpty() ? 0 : 1);
|
301 |
|
302 | if (this.indent) {
|
303 | output.indentLines();
|
304 | }
|
305 | var type = this;
|
306 | keys.forEach(function (key, index) {
|
307 | output
|
308 | .nl(index > 0 ? 1 : 0)
|
309 | .i()
|
310 | .block(function() {
|
311 | var valueActual = type.valueForKey(actual, key);
|
312 | var valueExpected = type.valueForKey(expected, key);
|
313 | var annotation = output.clone();
|
314 | var conflicting = !equal(valueActual, valueExpected);
|
315 | var isInlineDiff = false;
|
316 | var valueOutput;
|
317 | if (conflicting) {
|
318 | if (!type.hasKey(expected, key)) {
|
319 | annotation.error('should be removed');
|
320 | isInlineDiff = true;
|
321 | } else if (!type.hasKey(actual, key)) {
|
322 | this.error('// missing').sp();
|
323 | valueOutput = output.clone().appendInspected(valueExpected);
|
324 | isInlineDiff = true;
|
325 | } else {
|
326 | var keyDiff = diff$1(valueActual, valueExpected);
|
327 | if (!keyDiff || (keyDiff && !keyDiff.inline)) {
|
328 | annotation.shouldEqualError(valueExpected);
|
329 | if (keyDiff) {
|
330 | annotation.nl(2).append(keyDiff);
|
331 | }
|
332 | } else {
|
333 | isInlineDiff = true;
|
334 | valueOutput = keyDiff;
|
335 | }
|
336 | }
|
337 | } else {
|
338 | isInlineDiff = true;
|
339 | }
|
340 |
|
341 | if (!valueOutput) {
|
342 | valueOutput = inspect(valueActual, conflicting ? Infinity : null);
|
343 | }
|
344 |
|
345 | valueOutput.amend(
|
346 | type.delimiter(output.clone(), index, actualKeys.length)
|
347 | );
|
348 | if (!isInlineDiff) {
|
349 | valueOutput = output.clone().block(valueOutput);
|
350 | }
|
351 | type.property(this, key, valueOutput);
|
352 | if (!annotation.isEmpty()) {
|
353 | this.sp().annotationBlock(annotation);
|
354 | }
|
355 | });
|
356 | });
|
357 |
|
358 | if (this.indent) {
|
359 | output.outdentLines();
|
360 | }
|
361 | var suffixOutput = this.suffix(output.clone(), actual);
|
362 | return output.nl(suffixOutput.isEmpty() ? 0 : 1).append(suffixOutput);
|
363 | },
|
364 | similar: function similar(a, b) {
|
365 | var this$1 = this;
|
366 |
|
367 | if (a === null || b === null) {
|
368 | return false;
|
369 | }
|
370 |
|
371 | var typeA = typeof a;
|
372 | var typeB = typeof b;
|
373 |
|
374 | if (typeA !== typeB) {
|
375 | return false;
|
376 | }
|
377 |
|
378 | if (typeA === 'string') {
|
379 | return leven(a, b) < a.length / 2;
|
380 | }
|
381 |
|
382 | if (typeA !== 'object' || !a) {
|
383 | return false;
|
384 | }
|
385 |
|
386 | if (utils.isArray(a) && utils.isArray(b)) {
|
387 | return true;
|
388 | }
|
389 |
|
390 | var aKeys = this.getKeys(a);
|
391 | var bKeys = this.getKeys(b);
|
392 | var numberOfSimilarKeys = 0;
|
393 | var requiredSimilarKeys = Math.round(
|
394 | Math.max(aKeys.length, bKeys.length) / 2
|
395 | );
|
396 | return aKeys.concat(bKeys).some(function (key) {
|
397 | if (this$1.hasKey(a, key) && this$1.hasKey(b, key)) {
|
398 | numberOfSimilarKeys += 1;
|
399 | }
|
400 | return numberOfSimilarKeys >= requiredSimilarKeys;
|
401 | });
|
402 | },
|
403 | uniqueKeys: utils.uniqueStringsAndSymbols,
|
404 | valueForKey: function valueForKey(obj, key) {
|
405 | return obj[key];
|
406 | }
|
407 | });
|
408 |
|
409 | expect.addType({
|
410 | name: 'type',
|
411 | base: 'object',
|
412 | identify: function identify(value) {
|
413 | return value && value._unexpectedType;
|
414 | },
|
415 | inspect: function inspect(ref, depth, output) {
|
416 | var name = ref.name;
|
417 |
|
418 | return output.text('type: ').jsKeyword(name);
|
419 | }
|
420 | });
|
421 |
|
422 | expect.addType({
|
423 | name: 'array-like',
|
424 | base: 'object',
|
425 | identify: false,
|
426 | numericalPropertiesOnly: true,
|
427 | getKeys: function getKeys(obj) {
|
428 | var keys = new Array(obj.length);
|
429 | for (var i = 0; i < obj.length; i += 1) {
|
430 | keys[i] = i;
|
431 | }
|
432 | if (!this.numericalPropertiesOnly) {
|
433 | keys.push.apply(keys, this.getKeysNonNumerical(obj));
|
434 | }
|
435 | return keys;
|
436 | },
|
437 | getKeysNonNumerical: Object.getOwnPropertySymbols
|
438 | ? function (obj) {
|
439 | var keys = [];
|
440 | Object.keys(obj).forEach(function (key) {
|
441 | if (!utils.numericalRegExp.test(key)) {
|
442 | keys.push(key);
|
443 | }
|
444 | });
|
445 | var symbols = Object.getOwnPropertySymbols(obj);
|
446 | if (symbols.length > 0) {
|
447 | keys.push.apply(keys, symbols);
|
448 | }
|
449 | return keys;
|
450 | }
|
451 | : function (obj) {
|
452 | var keys = [];
|
453 | Object.keys(obj).forEach(function (key) {
|
454 | if (!utils.numericalRegExp.test(key)) {
|
455 | keys.push(key);
|
456 | }
|
457 | });
|
458 | return keys;
|
459 | },
|
460 | equal: function equal(a, b, equal$1) {
|
461 | var this$1 = this;
|
462 |
|
463 | if (a === b) {
|
464 | return true;
|
465 | } else if (a.constructor === b.constructor && a.length === b.length) {
|
466 | var i;
|
467 |
|
468 |
|
469 | for (i = 0; i < a.length; i += 1) {
|
470 | if (!equal$1(this.valueForKey(a, i), this.valueForKey(b, i))) {
|
471 | return false;
|
472 | }
|
473 | }
|
474 |
|
475 |
|
476 | if (!this.numericalPropertiesOnly) {
|
477 | var aKeys = this.getKeysNonNumerical(a).filter(function (key) {
|
478 |
|
479 | return typeof this$1.valueForKey(a, key) !== 'undefined';
|
480 | });
|
481 | var bKeys = this.getKeysNonNumerical(b).filter(function (key) {
|
482 |
|
483 | return (
|
484 | typeof this$1.valueForKey(b, key) !== 'undefined' ||
|
485 | typeof this$1.valueForKey(a, key) !== 'undefined'
|
486 | );
|
487 | });
|
488 |
|
489 | if (aKeys.length !== bKeys.length) {
|
490 | return false;
|
491 | }
|
492 |
|
493 | for (i = 0; i < aKeys.length; i += 1) {
|
494 | if (
|
495 | !equal$1(
|
496 | this.valueForKey(a, aKeys[i]),
|
497 | this.valueForKey(b, bKeys[i])
|
498 | )
|
499 | ) {
|
500 | return false;
|
501 | }
|
502 | }
|
503 | }
|
504 |
|
505 | return true;
|
506 | } else {
|
507 | return false;
|
508 | }
|
509 | },
|
510 | prefix: function prefix(output) {
|
511 | return output.text('[');
|
512 | },
|
513 | suffix: function suffix(output) {
|
514 | return output.text(']');
|
515 | },
|
516 | inspect: function inspect(arr, depth, output, inspect$1) {
|
517 | var this$1 = this;
|
518 |
|
519 | var prefixOutput = this.prefix(output.clone(), arr);
|
520 | var suffixOutput = this.suffix(output.clone(), arr);
|
521 | var keys = this.getKeys(arr);
|
522 | if (keys.length === 0) {
|
523 | return output.append(prefixOutput).append(suffixOutput);
|
524 | }
|
525 |
|
526 | if (depth === 1 && arr.length > 10) {
|
527 | return output
|
528 | .append(prefixOutput)
|
529 | .text('...')
|
530 | .append(suffixOutput);
|
531 | }
|
532 |
|
533 | var inspectedItems = keys.map(function (key) {
|
534 | var inspectedValue;
|
535 | if (this$1.hasKey(arr, key)) {
|
536 | inspectedValue = inspect$1(this$1.valueForKey(arr, key));
|
537 | } else if (utils.numericalRegExp.test(key)) {
|
538 |
|
539 | inspectedValue = output.clone();
|
540 | } else {
|
541 |
|
542 | inspectedValue = inspect$1(undefined);
|
543 | }
|
544 | return this$1.property(output.clone(), key, inspectedValue, true);
|
545 | });
|
546 |
|
547 | var currentDepth = defaultDepth - Math.min(defaultDepth, depth);
|
548 | var maxLineLength =
|
549 | output.preferredWidth - 20 - currentDepth * output.indentationWidth - 2;
|
550 | var width = 0;
|
551 | var multipleLines =
|
552 | this.forceMultipleLines ||
|
553 | inspectedItems.some(function (o) {
|
554 | if (o.isMultiline()) {
|
555 | return true;
|
556 | }
|
557 |
|
558 | var size = o.size();
|
559 | width += size.width;
|
560 | return width > maxLineLength;
|
561 | });
|
562 | inspectedItems.forEach(function (inspectedItem, index) {
|
563 | inspectedItem.amend(this$1.delimiter(output.clone(), index, keys.length));
|
564 | });
|
565 | if (multipleLines) {
|
566 | output.append(prefixOutput);
|
567 | if (!prefixOutput.isEmpty()) {
|
568 | output.nl();
|
569 | }
|
570 | if (this.indent) {
|
571 | output.indentLines();
|
572 | }
|
573 | inspectedItems.forEach(function (inspectedItem, index) {
|
574 | output
|
575 | .nl(index > 0 ? 1 : 0)
|
576 | .i()
|
577 | .block(inspectedItem);
|
578 | });
|
579 |
|
580 | if (this.indent) {
|
581 | output.outdentLines();
|
582 | }
|
583 |
|
584 | if (!suffixOutput.isEmpty()) {
|
585 | output.nl();
|
586 | }
|
587 |
|
588 | return output.append(suffixOutput);
|
589 | } else {
|
590 | output.append(prefixOutput).sp(prefixOutput.isEmpty() ? 0 : 1);
|
591 | inspectedItems.forEach(function (inspectedItem, index) {
|
592 | output.append(inspectedItem);
|
593 | var lastIndex = index === inspectedItems.length - 1;
|
594 | if (!lastIndex) {
|
595 | output.sp();
|
596 | }
|
597 | });
|
598 | return output.sp(suffixOutput.isEmpty() ? 0 : 1).append(suffixOutput);
|
599 | }
|
600 | },
|
601 | diffLimit: 512,
|
602 | diff: function diff(actual, expected, output, diff$1, inspect, equal) {
|
603 | output.inline = true;
|
604 |
|
605 | if (Math.max(actual.length, expected.length) > this.diffLimit) {
|
606 | output.jsComment(("Diff suppressed due to size > " + (this.diffLimit)));
|
607 | return output;
|
608 | }
|
609 |
|
610 | if (actual.constructor !== expected.constructor) {
|
611 | return this.baseType.diff(actual, expected, output);
|
612 | }
|
613 |
|
614 | var prefixOutput = this.prefix(output.clone(), actual);
|
615 | output.append(prefixOutput).nl(prefixOutput.isEmpty() ? 0 : 1);
|
616 |
|
617 | if (this.indent) {
|
618 | output.indentLines();
|
619 | }
|
620 |
|
621 | var actualElements = utils.duplicateArrayLikeUsingType(actual, this);
|
622 | var actualKeys = this.getKeys(actual);
|
623 | var expectedElements = utils.duplicateArrayLikeUsingType(expected, this);
|
624 | var expectedKeys = this.getKeys(expected);
|
625 | var nonNumericalKeysAndSymbols =
|
626 | !this.numericalPropertiesOnly &&
|
627 | utils.uniqueNonNumericalStringsAndSymbols(actualKeys, expectedKeys);
|
628 |
|
629 | var type = this;
|
630 | var changes = arrayChanges(
|
631 | actualElements,
|
632 | expectedElements,
|
633 | equal,
|
634 | function (a, b) { return type.similar(a, b); },
|
635 | {
|
636 | includeNonNumericalProperties: nonNumericalKeysAndSymbols
|
637 | }
|
638 | );
|
639 | var indexOfLastNonInsert = changes.reduce(
|
640 | function (previousValue, diffItem, index) { return diffItem.type === 'insert' ? previousValue : index; },
|
641 | -1
|
642 | );
|
643 | var packing = utils.packArrows(changes);
|
644 | output.arrowsAlongsideChangeOutputs(
|
645 | packing,
|
646 | changes.map(function (diffItem, index) {
|
647 | var delimiterOutput = type.delimiter(
|
648 | output.clone(),
|
649 | index,
|
650 | indexOfLastNonInsert + 1
|
651 | );
|
652 | if (diffItem.type === 'moveTarget') {
|
653 | return output.clone();
|
654 | } else {
|
655 | return output.clone().block(function() {
|
656 | if (diffItem.type === 'moveSource') {
|
657 | var propertyOutput = type.property(
|
658 | output.clone(),
|
659 | diffItem.actualIndex,
|
660 | inspect(diffItem.value),
|
661 | true
|
662 | );
|
663 | this.amend(propertyOutput)
|
664 | .amend(delimiterOutput)
|
665 | .sp()
|
666 | .error('// should be moved');
|
667 | } else if (diffItem.type === 'insert') {
|
668 | this.annotationBlock(function() {
|
669 | this.error('missing ').block(function() {
|
670 | var index =
|
671 | typeof diffItem.actualIndex !== 'undefined'
|
672 | ? diffItem.actualIndex
|
673 | : diffItem.expectedIndex;
|
674 | var propertyOutput = type.property(
|
675 | output.clone(),
|
676 | index,
|
677 | inspect(diffItem.value),
|
678 | true
|
679 | );
|
680 | this.amend(propertyOutput);
|
681 | });
|
682 | });
|
683 | } else if (diffItem.type === 'remove') {
|
684 | this.block(function() {
|
685 | var propertyOutput = type.property(
|
686 | output.clone(),
|
687 | diffItem.actualIndex,
|
688 | inspect(diffItem.value),
|
689 | true
|
690 | );
|
691 | this.amend(propertyOutput)
|
692 | .amend(delimiterOutput)
|
693 | .sp()
|
694 | .error('// should be removed');
|
695 | });
|
696 | } else if (diffItem.type === 'equal') {
|
697 | this.block(function() {
|
698 | var propertyOutput = type.property(
|
699 | output.clone(),
|
700 | diffItem.actualIndex,
|
701 | inspect(diffItem.value),
|
702 | true
|
703 | );
|
704 | this.amend(propertyOutput).amend(delimiterOutput);
|
705 | });
|
706 | } else {
|
707 | this.block(function() {
|
708 | var valueDiff = diff$1(diffItem.value, diffItem.expected);
|
709 | if (valueDiff && valueDiff.inline) {
|
710 | this.append(valueDiff).append(delimiterOutput);
|
711 | } else {
|
712 | var propertyOutput = type.property(
|
713 | output.clone(),
|
714 | diffItem.actualIndex,
|
715 | inspect(diffItem.value),
|
716 | true
|
717 | );
|
718 | this.append(propertyOutput)
|
719 | .append(delimiterOutput)
|
720 | .sp()
|
721 | .annotationBlock(function() {
|
722 | this.shouldEqualError(diffItem.expected, inspect);
|
723 | if (valueDiff) {
|
724 | this.nl(2).append(valueDiff);
|
725 | }
|
726 | });
|
727 | }
|
728 | });
|
729 | }
|
730 | });
|
731 | }
|
732 | })
|
733 | );
|
734 |
|
735 | if (this.indent) {
|
736 | output.outdentLines();
|
737 | }
|
738 |
|
739 | var suffixOutput = this.suffix(output.clone(), actual);
|
740 | return output.nl(suffixOutput.isEmpty() ? 0 : 1).append(suffixOutput);
|
741 | }
|
742 | });
|
743 |
|
744 | expect.addType({
|
745 | name: 'array',
|
746 | base: 'array-like',
|
747 | numericalPropertiesOnly: false,
|
748 | identify: function identify(arr) {
|
749 | return utils.isArray(arr);
|
750 | }
|
751 | });
|
752 |
|
753 | expect.addType({
|
754 | name: 'arguments',
|
755 | base: 'array-like',
|
756 | prefix: function prefix(output) {
|
757 | return output.text('arguments(', 'cyan');
|
758 | },
|
759 | suffix: function suffix(output) {
|
760 | return output.text(')', 'cyan');
|
761 | },
|
762 | identify: function identify(obj) {
|
763 | return Object.prototype.toString.call(obj) === '[object Arguments]';
|
764 | }
|
765 | });
|
766 |
|
767 | var errorMethodBlacklist = [
|
768 | 'message',
|
769 | 'name',
|
770 | 'description',
|
771 | 'line',
|
772 | 'number',
|
773 | 'column',
|
774 | 'sourceId',
|
775 | 'sourceURL',
|
776 | 'stack',
|
777 | 'stackArray',
|
778 | '__stackCleaned__',
|
779 | 'isOperational'
|
780 | ].reduce(function (result, prop) {
|
781 | result[prop] = true;
|
782 | return result;
|
783 | }, {});
|
784 |
|
785 | if (new Error().hasOwnProperty('arguments')) {
|
786 |
|
787 | errorMethodBlacklist.arguments = true;
|
788 | errorMethodBlacklist.type = true;
|
789 | }
|
790 |
|
791 | expect.addType({
|
792 | base: 'object',
|
793 | name: 'Error',
|
794 | identify: function identify(value) {
|
795 | return utils.isError(value);
|
796 | },
|
797 | getKeys: function getKeys(value) {
|
798 | var keys = this.baseType
|
799 | .getKeys(value)
|
800 | .filter(function (key) { return !errorMethodBlacklist[key]; });
|
801 | keys.unshift('message');
|
802 | return keys;
|
803 | },
|
804 | unwrap: function unwrap(value) {
|
805 | return this.getKeys(value).reduce(function (result, key) {
|
806 | result[key] = value[key];
|
807 | return result;
|
808 | }, {});
|
809 | },
|
810 | equal: function equal(a, b, equal$1) {
|
811 | return (
|
812 | a === b ||
|
813 | (equal$1(a.message, b.message) &&
|
814 | utils.checkObjectEqualityUsingType(a, b, this, equal$1))
|
815 | );
|
816 | },
|
817 | inspect: function inspect(value, depth, output, inspect$1) {
|
818 | output.errorName(value).text('(');
|
819 | var keys = this.getKeys(value);
|
820 | if (keys.length === 1 && keys[0] === 'message') {
|
821 | if (value.message !== '') {
|
822 | output.append(inspect$1(value.message));
|
823 | }
|
824 | } else {
|
825 | output.append(inspect$1(this.unwrap(value), depth));
|
826 | }
|
827 | return output.text(')');
|
828 | },
|
829 | diff: function diff(actual, expected, output, diff$1) {
|
830 | if (actual.constructor !== expected.constructor) {
|
831 | return output
|
832 | .text('Mismatching constructors ')
|
833 | .errorName(actual)
|
834 | .text(' should be ')
|
835 | .errorName(expected);
|
836 | }
|
837 |
|
838 | output = diff$1(this.unwrap(actual), this.unwrap(expected));
|
839 | if (output) {
|
840 | output = output
|
841 | .clone()
|
842 | .errorName(actual)
|
843 | .text('(')
|
844 | .append(output)
|
845 | .text(')');
|
846 | output.inline = false;
|
847 | }
|
848 | return output;
|
849 | }
|
850 | });
|
851 |
|
852 | var unexpectedErrorMethodBlacklist = [
|
853 | 'output',
|
854 | '_isUnexpected',
|
855 | 'htmlMessage',
|
856 | '_hasSerializedErrorMessage',
|
857 | 'expect',
|
858 | 'assertion',
|
859 | 'originalError'
|
860 | ].reduce(function (result, prop) {
|
861 | result[prop] = true;
|
862 | return result;
|
863 | }, {});
|
864 | expect.addType({
|
865 | base: 'Error',
|
866 | name: 'UnexpectedError',
|
867 | identify: function identify(value) {
|
868 | return (
|
869 | value &&
|
870 | typeof value === 'object' &&
|
871 | value._isUnexpected &&
|
872 | this.baseType.identify(value)
|
873 | );
|
874 | },
|
875 | getKeys: function getKeys(value) {
|
876 | return this.baseType
|
877 | .getKeys(value)
|
878 | .filter(function (key) { return !unexpectedErrorMethodBlacklist[key]; });
|
879 | },
|
880 | inspect: function inspect(value, depth, output) {
|
881 | output.jsFunctionName(this.name).text('(');
|
882 | var errorMessage = value.getErrorMessage(output);
|
883 | if (errorMessage.isMultiline()) {
|
884 | output
|
885 | .nl()
|
886 | .indentLines()
|
887 | .i()
|
888 | .block(errorMessage)
|
889 | .nl();
|
890 | } else {
|
891 | output.append(errorMessage);
|
892 | }
|
893 | return output.text(')');
|
894 | }
|
895 | });
|
896 |
|
897 | expect.addType({
|
898 | name: 'date',
|
899 | identify: function identify(obj) {
|
900 | return Object.prototype.toString.call(obj) === '[object Date]';
|
901 | },
|
902 | equal: function equal(a, b) {
|
903 | return a.getTime() === b.getTime();
|
904 | },
|
905 | inspect: function inspect(date, depth, output, inspect$1) {
|
906 |
|
907 | var dateStr = date.toUTCString().replace(/UTC/, 'GMT');
|
908 | var milliseconds = date.getUTCMilliseconds();
|
909 | if (milliseconds > 0) {
|
910 | var millisecondsStr = String(milliseconds);
|
911 | while (millisecondsStr.length < 3) {
|
912 | millisecondsStr = "0" + millisecondsStr;
|
913 | }
|
914 | dateStr = dateStr.replace(' GMT', ("." + millisecondsStr + " GMT"));
|
915 | }
|
916 |
|
917 | return output
|
918 | .jsKeyword('new')
|
919 | .sp()
|
920 | .text('Date(')
|
921 | .append(inspect$1(dateStr).text(')'));
|
922 | }
|
923 | });
|
924 |
|
925 | expect.addType({
|
926 | base: 'object',
|
927 | name: 'function',
|
928 | identify: function identify(f) {
|
929 | return typeof f === 'function';
|
930 | },
|
931 | getKeys: Object.keys,
|
932 | equal: function equal(a, b) {
|
933 | return a === b;
|
934 | },
|
935 | inspect: function inspect(f, depth, output, inspect$1) {
|
936 |
|
937 | var source = Function.prototype.toString
|
938 | .call(f)
|
939 | .replace(/\r\n?|\n\r?/g, '\n');
|
940 | var name = utils.getFunctionName(f) || '';
|
941 | var preamble;
|
942 | var body;
|
943 | var bodyIndent;
|
944 | var matchSource = source.match(
|
945 | /^\s*((?:async )?\s*(?:\S+\s*=>|\([^)]*\)\s*=>|class|function\s?(?:\*\s*)?\w*\s*\([^)]*\)))([\s\S]*)$/
|
946 | );
|
947 | if (matchSource) {
|
948 |
|
949 | preamble = matchSource[1]
|
950 | .replace(/function(\S)/, 'function $1')
|
951 | .replace(/\* /, '*');
|
952 | if (preamble === 'function ()' && name) {
|
953 |
|
954 | preamble = "function " + name + "()";
|
955 | }
|
956 | body = matchSource[2];
|
957 | var matchBodyAndIndent = body.match(/^(\s*\{)([\s\S]*?)([ ]*)\}\s*$/);
|
958 | var openingBrace;
|
959 | var isWrappedInBraces = true;
|
960 | var closingBrace = '}';
|
961 | var reindentBodyLevel = 0;
|
962 | if (matchBodyAndIndent) {
|
963 | openingBrace = matchBodyAndIndent[1];
|
964 | body = matchBodyAndIndent[2];
|
965 | bodyIndent = matchBodyAndIndent[3] || '';
|
966 | if (bodyIndent.length === 1) {
|
967 | closingBrace = ' }';
|
968 | }
|
969 | } else {
|
970 |
|
971 | matchBodyAndIndent = body.match(/^(\s*)([\s\S]*?)([ ]*)\s*$/);
|
972 |
|
973 | if (matchBodyAndIndent) {
|
974 | openingBrace = matchBodyAndIndent[1];
|
975 | isWrappedInBraces = false;
|
976 | body = matchBodyAndIndent[2];
|
977 | var matchInitialNewline = openingBrace.match(/^\n( +)/);
|
978 | if (matchInitialNewline) {
|
979 | openingBrace = '\n';
|
980 | if (/\n/.test(body)) {
|
981 |
|
982 |
|
983 |
|
984 |
|
985 |
|
986 |
|
987 | bodyIndent = matchInitialNewline[1];
|
988 | reindentBodyLevel = 1;
|
989 | } else {
|
990 | body = body.replace(/^\s*/, ' ');
|
991 | }
|
992 | } else {
|
993 | bodyIndent = matchBodyAndIndent[3] || '';
|
994 | }
|
995 | closingBrace = '';
|
996 | }
|
997 | }
|
998 |
|
999 |
|
1000 | if (/\n/.test(body) && !/\\\n/.test(body)) {
|
1001 | body = body.replace(new RegExp(("^ {" + (bodyIndent.length) + "}"), 'mg'), '');
|
1002 | var indent = detectIndent(body);
|
1003 | body = body.replace(
|
1004 | new RegExp(("^(?:" + (indent.indent) + ")*"), 'mg'),
|
1005 | function (ref) {
|
1006 | var length = ref.length;
|
1007 |
|
1008 | return utils.leftPad(
|
1009 | '',
|
1010 | (length / indent.amount + reindentBodyLevel) *
|
1011 | output.indentationWidth,
|
1012 | ' '
|
1013 | );
|
1014 | }
|
1015 | );
|
1016 | }
|
1017 | if (!name || name === 'anonymous') {
|
1018 | name = '';
|
1019 | }
|
1020 | if (/^\s*\[native code\]\s*$/.test(body)) {
|
1021 | body = ' /* native code */ ';
|
1022 | closingBrace = '}';
|
1023 | } else if (/^\s*$/.test(body)) {
|
1024 | body = '';
|
1025 | } else if (
|
1026 | /^\s*[^\r\n]{1,30}\s*$/.test(body) &&
|
1027 | body.indexOf('//') === -1 &&
|
1028 | isWrappedInBraces
|
1029 | ) {
|
1030 | body = " " + (body.trim()) + " ";
|
1031 | closingBrace = '}';
|
1032 | } else {
|
1033 | body = body.replace(
|
1034 | /^((?:.*\n){3}( *).*\n)[\s\S]*?\n[\s\S]*?\n((?:.*\n){3})$/,
|
1035 | '$1$2// ... lines removed ...\n$3'
|
1036 | );
|
1037 | }
|
1038 | if (matchBodyAndIndent) {
|
1039 | body = openingBrace + body + closingBrace;
|
1040 | } else {
|
1041 |
|
1042 | body = body.replace(/[ ]*$/, '');
|
1043 | }
|
1044 | } else {
|
1045 | preamble = "function " + name + "( /*...*/ ) ";
|
1046 | body = '{ /*...*/ }';
|
1047 | }
|
1048 | return output.code(preamble + body, 'javascript');
|
1049 | },
|
1050 | diff: function diff(actual, expected, output) {
|
1051 |
|
1052 | if (typeof actual !== 'function' || typeof expected !== 'function') {
|
1053 | return this.baseType.diff(actual, expected, output);
|
1054 | }
|
1055 | }
|
1056 | });
|
1057 |
|
1058 | expect.addType({
|
1059 | base: 'function',
|
1060 | name: 'expect.it',
|
1061 | identify: function identify(f) {
|
1062 | return typeof f === 'function' && f._expectIt;
|
1063 | },
|
1064 | inspect: function inspect(ref, depth, output, inspect$1) {
|
1065 | var _expectations = ref._expectations;
|
1066 | var _OR = ref._OR;
|
1067 |
|
1068 | output.text('expect.it(');
|
1069 | var orBranch = false;
|
1070 | _expectations.forEach(function (expectation, index) {
|
1071 | if (expectation === _OR) {
|
1072 | orBranch = true;
|
1073 | return;
|
1074 | }
|
1075 |
|
1076 | if (orBranch) {
|
1077 | output.text(')\n .or(');
|
1078 | } else if (index > 0) {
|
1079 | output.text(')\n .and(');
|
1080 | }
|
1081 |
|
1082 | var args = Array.prototype.slice.call(expectation);
|
1083 | args.forEach(function (arg, i) {
|
1084 | if (i > 0) {
|
1085 | output.text(', ');
|
1086 | }
|
1087 | output.append(inspect$1(arg));
|
1088 | });
|
1089 | orBranch = false;
|
1090 | });
|
1091 |
|
1092 | return output.amend(')');
|
1093 | }
|
1094 | });
|
1095 |
|
1096 | expect.addType({
|
1097 | name: 'Promise',
|
1098 | base: 'object',
|
1099 | identify: function identify(obj) {
|
1100 | return (
|
1101 | obj && this.baseType.identify(obj) && typeof obj.then === 'function'
|
1102 | );
|
1103 | },
|
1104 | inspect: function inspect(promise, depth, output, inspect$1) {
|
1105 | output.jsFunctionName('Promise');
|
1106 | if (promise.isPending && promise.isPending()) {
|
1107 | output.sp().yellow('(pending)');
|
1108 | } else if (promise.isFulfilled && promise.isFulfilled()) {
|
1109 | output.sp().green('(fulfilled)');
|
1110 | if (promise.value) {
|
1111 | var value = promise.value();
|
1112 | if (typeof value !== 'undefined') {
|
1113 | output
|
1114 | .sp()
|
1115 | .text('=>')
|
1116 | .sp()
|
1117 | .append(inspect$1(value));
|
1118 | }
|
1119 | }
|
1120 | } else if (promise.isRejected && promise.isRejected()) {
|
1121 | output.sp().red('(rejected)');
|
1122 | var reason = promise.reason();
|
1123 | if (typeof reason !== 'undefined') {
|
1124 | output
|
1125 | .sp()
|
1126 | .text('=>')
|
1127 | .sp()
|
1128 | .append(inspect$1(promise.reason()));
|
1129 | }
|
1130 | }
|
1131 | return output;
|
1132 | }
|
1133 | });
|
1134 |
|
1135 | expect.addType({
|
1136 | name: 'regexp',
|
1137 | base: 'object',
|
1138 | identify: isRegExp,
|
1139 | equal: function equal(a, b) {
|
1140 | return (
|
1141 | a === b ||
|
1142 | (a.source === b.source &&
|
1143 | a.global === b.global &&
|
1144 | a.ignoreCase === b.ignoreCase &&
|
1145 | a.multiline === b.multiline)
|
1146 | );
|
1147 | },
|
1148 | inspect: function inspect(regExp, depth, output) {
|
1149 | return output.jsRegexp(regExp);
|
1150 | },
|
1151 | diff: function diff(actual, expected, output, diff$1, inspect) {
|
1152 | output.inline = false;
|
1153 | return output.stringDiff(String(actual), String(expected), {
|
1154 | type: 'Chars',
|
1155 | markUpSpecialCharacters: true
|
1156 | });
|
1157 | }
|
1158 | });
|
1159 |
|
1160 | expect.addType({
|
1161 | name: 'binaryArray',
|
1162 | base: 'array-like',
|
1163 | digitWidth: 2,
|
1164 | hexDumpWidth: 16,
|
1165 | identify: false,
|
1166 | prefix: function prefix(output) {
|
1167 | return output.code(((this.name) + "(["), 'javascript');
|
1168 | },
|
1169 | suffix: function suffix(output) {
|
1170 | return output.code('])', 'javascript');
|
1171 | },
|
1172 | equal: function equal(a, b) {
|
1173 | if (a === b) {
|
1174 | return true;
|
1175 | }
|
1176 |
|
1177 | if (a.length !== b.length) {
|
1178 | return false;
|
1179 | }
|
1180 |
|
1181 | for (var i = 0; i < a.length; i += 1) {
|
1182 | if (a[i] !== b[i]) {
|
1183 | return false;
|
1184 | }
|
1185 | }
|
1186 |
|
1187 | return true;
|
1188 | },
|
1189 | hexDump: function hexDump(obj, maxLength) {
|
1190 | var hexDump = '';
|
1191 | if (typeof maxLength !== 'number' || maxLength === 0) {
|
1192 | maxLength = obj.length;
|
1193 | }
|
1194 | for (var i = 0; i < maxLength; i += this.hexDumpWidth) {
|
1195 | if (hexDump.length > 0) {
|
1196 | hexDump += '\n';
|
1197 | }
|
1198 | var hexChars = '';
|
1199 | var asciiChars = ' │';
|
1200 |
|
1201 | for (var j = 0; j < this.hexDumpWidth; j += 1) {
|
1202 | if (i + j < maxLength) {
|
1203 | var octet = obj[i + j];
|
1204 | hexChars += (leftPad(
|
1205 | octet.toString(16).toUpperCase(),
|
1206 | this.digitWidth,
|
1207 | '0'
|
1208 | )) + " ";
|
1209 | asciiChars += String.fromCharCode(octet)
|
1210 | .replace(/\n/g, '␊')
|
1211 | .replace(/\r/g, '␍');
|
1212 | } else if (this.digitWidth === 2) {
|
1213 | hexChars += ' ';
|
1214 | }
|
1215 | }
|
1216 |
|
1217 | if (this.digitWidth === 2) {
|
1218 | hexDump += (hexChars + asciiChars) + "│";
|
1219 | } else {
|
1220 | hexDump += hexChars.replace(/\s+$/, '');
|
1221 | }
|
1222 | }
|
1223 | return hexDump;
|
1224 | },
|
1225 | inspect: function inspect(obj, depth, output) {
|
1226 | this.prefix(output, obj);
|
1227 | var codeStr = '';
|
1228 | for (var i = 0; i < Math.min(this.hexDumpWidth, obj.length); i += 1) {
|
1229 | if (i > 0) {
|
1230 | codeStr += ', ';
|
1231 | }
|
1232 | var octet = obj[i];
|
1233 | codeStr += "0x" + (leftPad(
|
1234 | octet.toString(16).toUpperCase(),
|
1235 | this.digitWidth,
|
1236 | '0'
|
1237 | ));
|
1238 | }
|
1239 | if (obj.length > this.hexDumpWidth) {
|
1240 | codeStr += " /* " + (obj.length - this.hexDumpWidth) + " more */ ";
|
1241 | }
|
1242 | output.code(codeStr, 'javascript');
|
1243 | this.suffix(output, obj);
|
1244 | return output;
|
1245 | },
|
1246 | diffLimit: 512,
|
1247 | diff: function diff(actual, expected, output, diff$1, inspect) {
|
1248 | output.inline = false;
|
1249 | if (Math.max(actual.length, expected.length) > this.diffLimit) {
|
1250 | output.jsComment(("Diff suppressed due to size > " + (this.diffLimit)));
|
1251 | } else {
|
1252 | output
|
1253 | .stringDiff(this.hexDump(actual), this.hexDump(expected), {
|
1254 | type: 'Chars',
|
1255 | markUpSpecialCharacters: false
|
1256 | })
|
1257 |
|
1258 | .replaceText(/[\x00-\x1f\x7f-\xff␊␍]/g, '.')
|
1259 | .replaceText(/[│ ]/g, function(styles, content) {
|
1260 | this.text(content);
|
1261 | });
|
1262 | }
|
1263 | return output;
|
1264 | }
|
1265 | });
|
1266 |
|
1267 | [8, 16, 32].forEach(function(numBits) {
|
1268 | ['Int', 'Uint'].forEach(function (intOrUint) {
|
1269 | var constructorName = (intOrUint + numBits) + "Array";
|
1270 | var Constructor = global[constructorName];
|
1271 | if (typeof Constructor !== 'undefined') {
|
1272 | expect.addType({
|
1273 | name: constructorName,
|
1274 | base: 'binaryArray',
|
1275 | hexDumpWidth: 128 / numBits,
|
1276 | digitWidth: numBits / 4,
|
1277 | identify: function identify(obj) {
|
1278 | return obj instanceof Constructor;
|
1279 | }
|
1280 | });
|
1281 | }
|
1282 | }, this);
|
1283 | }, this);
|
1284 |
|
1285 | if (typeof Buffer !== 'undefined') {
|
1286 | expect.addType({
|
1287 | name: 'Buffer',
|
1288 | base: 'binaryArray',
|
1289 | identify: Buffer.isBuffer
|
1290 | });
|
1291 | }
|
1292 |
|
1293 | expect.addType({
|
1294 | name: 'string',
|
1295 | identify: function identify(value) {
|
1296 | return typeof value === 'string';
|
1297 | },
|
1298 | inspect: function inspect(value, depth, output) {
|
1299 | return output.singleQuotedString(value);
|
1300 | },
|
1301 | diffLimit: 65536,
|
1302 | diff: function diff(actual, expected, output, diff$1, inspect) {
|
1303 | if (Math.max(actual.length, expected.length) > this.diffLimit) {
|
1304 | output.jsComment(("Diff suppressed due to size > " + (this.diffLimit)));
|
1305 | return output;
|
1306 | }
|
1307 | output.stringDiff(actual, expected, {
|
1308 | type: 'WordsWithSpace',
|
1309 | markUpSpecialCharacters: true
|
1310 | });
|
1311 | output.inline = false;
|
1312 | return output;
|
1313 | }
|
1314 | });
|
1315 |
|
1316 | expect.addType({
|
1317 | name: 'number',
|
1318 | identify: function identify(value) {
|
1319 | return typeof value === 'number' && !isNaN(value);
|
1320 | },
|
1321 | inspect: function inspect(value, depth, output) {
|
1322 | if (value === 0 && 1 / value === -Infinity) {
|
1323 | value = '-0';
|
1324 | } else {
|
1325 | value = String(value);
|
1326 | }
|
1327 | return output.jsNumber(String(value));
|
1328 | }
|
1329 | });
|
1330 |
|
1331 | expect.addType({
|
1332 | name: 'NaN',
|
1333 | identify: function identify(value) {
|
1334 | return typeof value === 'number' && isNaN(value);
|
1335 | },
|
1336 | inspect: function inspect(value, depth, output) {
|
1337 | return output.jsPrimitive(value);
|
1338 | }
|
1339 | });
|
1340 |
|
1341 | expect.addType({
|
1342 | name: 'boolean',
|
1343 | identify: function identify(value) {
|
1344 | return typeof value === 'boolean';
|
1345 | },
|
1346 | inspect: function inspect(value, depth, output) {
|
1347 | return output.jsPrimitive(value);
|
1348 | }
|
1349 | });
|
1350 |
|
1351 | expect.addType({
|
1352 | name: 'undefined',
|
1353 | identify: function identify(value) {
|
1354 | return typeof value === 'undefined';
|
1355 | },
|
1356 | inspect: function inspect(value, depth, output) {
|
1357 | return output.jsPrimitive(value);
|
1358 | }
|
1359 | });
|
1360 |
|
1361 | expect.addType({
|
1362 | name: 'null',
|
1363 | identify: function identify(value) {
|
1364 | return value === null;
|
1365 | },
|
1366 | inspect: function inspect(value, depth, output) {
|
1367 | return output.jsPrimitive(value);
|
1368 | }
|
1369 | });
|
1370 |
|
1371 | expect.addType({
|
1372 | name: 'assertion',
|
1373 | identify: function identify(value) {
|
1374 | return value instanceof AssertionString;
|
1375 | }
|
1376 | });
|
1377 | };
|