1 | 'use strict';
|
2 |
|
3 | var test = require('tape');
|
4 | require('./_tape');
|
5 | var assign = require('object.assign');
|
6 | var gOPDs = require('object.getownpropertydescriptors');
|
7 | var hasSymbols = require('has-symbols')();
|
8 | var hasTypedArrays = require('has-typed-arrays')();
|
9 | var semver = require('semver');
|
10 |
|
11 | var safeBuffer = typeof Buffer === 'function' ? Buffer.from && Buffer.from.length > 1 ? Buffer.from : Buffer : null;
|
12 | var buffersAreTypedArrays = typeof Buffer === 'function' && new Buffer(0) instanceof Uint8Array;
|
13 |
|
14 | var isNode = typeof process === 'object' && typeof process.version === 'string';
|
15 |
|
16 | function tag(obj, value) {
|
17 | if (hasSymbols && Symbol.toStringTag && Object.defineProperty) {
|
18 | Object.defineProperty(obj, Symbol.toStringTag, {
|
19 | value: value
|
20 | });
|
21 | }
|
22 | return obj;
|
23 | }
|
24 |
|
25 |
|
26 | var hasDunderProto = [].__proto__ === Array.prototype;
|
27 |
|
28 | test('equal', function (t) {
|
29 | t.deepEqualTest(
|
30 | { a: [2, 3], b: [4] },
|
31 | { a: [2, 3], b: [4] },
|
32 | 'two equal objects',
|
33 | true,
|
34 | true,
|
35 | false
|
36 | );
|
37 |
|
38 | t.deepEqualTest(
|
39 | { a: 2, b: '4' },
|
40 | { a: 2, b: 4 },
|
41 | 'two loosely equal, strictly inequal objects',
|
42 | true,
|
43 | false
|
44 | );
|
45 |
|
46 | t.deepEqualTest(
|
47 | { a: 2, b: 4 },
|
48 | { a: 2, B: 4 },
|
49 | 'two inequal objects',
|
50 | false,
|
51 | false
|
52 | );
|
53 |
|
54 | t.deepEqualTest(
|
55 | '-000',
|
56 | false,
|
57 | '`false` and `"-000"`',
|
58 | true,
|
59 | false
|
60 | );
|
61 |
|
62 | t.end();
|
63 | });
|
64 |
|
65 | test('Maps', { skip: typeof Map !== 'function' }, function (t) {
|
66 | t.deepEqualTest(
|
67 | new Map([['a', 1], ['b', 2]]),
|
68 | new Map([['b', 2], ['a', 1]]),
|
69 | 'two equal Maps',
|
70 | true,
|
71 | true
|
72 | );
|
73 |
|
74 | t.deepEqualTest(
|
75 | new Map([['a', [1, 2]]]),
|
76 | new Map([['a', [2, 1]]]),
|
77 | 'two Maps with inequal values on the same key',
|
78 | false,
|
79 | false
|
80 | );
|
81 |
|
82 | t.deepEqualTest(
|
83 | new Map([['a', 1]]),
|
84 | new Map([['b', 1]]),
|
85 | 'two inequal Maps',
|
86 | false,
|
87 | false
|
88 | );
|
89 |
|
90 | t.deepEqualTest(
|
91 | new Map([[{}, 3], [{}, 2], [{}, 1]]),
|
92 | new Map([[{}, 1], [{}, 2], [{}, 3]]),
|
93 | 'two equal Maps in different orders with object keys',
|
94 | true,
|
95 | true
|
96 | );
|
97 |
|
98 | t.deepEqualTest(
|
99 | new Map([[undefined, undefined]]),
|
100 | new Map([[undefined, null]]),
|
101 | 'undefined keys, nullish values, loosely equal, strictly inequal',
|
102 | true,
|
103 | false
|
104 | );
|
105 |
|
106 | t.deepEqualTest(
|
107 | new Map([[{}, null], [true, 2], [{}, 1], [undefined, {}]]),
|
108 | new Map([[{}, 1], [true, 2], [{}, null], [undefined, {}]]),
|
109 | 'two equal Maps in different orders with primitive keys',
|
110 | true,
|
111 | true
|
112 | );
|
113 |
|
114 | t.deepEqualTest(
|
115 | new Map([[false, 3], [{}, 2], [{}, 1]]),
|
116 | new Map([[{}, 1], [{}, 2], [false, 3]]),
|
117 | 'two equal Maps in different orders with a mix of keys',
|
118 | true,
|
119 | true
|
120 | );
|
121 |
|
122 | t.deepEqualTest(
|
123 | new Map([[null, undefined]]),
|
124 | new Map([[null, null]]),
|
125 | 'null keys, nullish values, loosely equal, strictly inequal',
|
126 | true,
|
127 | false
|
128 | );
|
129 |
|
130 | t.deepEqualTest(
|
131 | new Map([[undefined, 3]]),
|
132 | new Map([[null, 3]]),
|
133 | 'nullish keys, loosely equal, strictly inequal',
|
134 | true,
|
135 | false
|
136 | );
|
137 |
|
138 | t.deepEqualTest(
|
139 | new Map([[{}, null], [true, 2], [{}, 1], [undefined, {}]]),
|
140 | new Map([[{}, 1], [true, 2], [{}, null], [undefined, {}]]),
|
141 | 'two equal Maps in different orders with primitive keys',
|
142 | true,
|
143 | true
|
144 | );
|
145 |
|
146 | t.deepEqualTest(
|
147 | new Map([[false, 3], [{}, 2], [{}, 1]]),
|
148 | new Map([[{}, 1], [{}, 2], [false, 3]]),
|
149 | 'two equal Maps in different orders with a mix of keys',
|
150 | true,
|
151 | true
|
152 | );
|
153 |
|
154 | t.deepEqualTest(
|
155 | new Map(),
|
156 | new Map([[{}, 1]]),
|
157 | 'two inequal Maps',
|
158 | false,
|
159 | false
|
160 | );
|
161 |
|
162 | t.deepEqualTest(
|
163 | new Map([[{}, null], [false, 3]]),
|
164 | new Map([[{}, null], [true, 2]]),
|
165 | 'two inequal maps, same size, primitive key, start with object key',
|
166 | false,
|
167 | false
|
168 | );
|
169 |
|
170 | t.deepEqualTest(
|
171 | new Map([[false, 3], [{}, null]]),
|
172 | new Map([[true, 2], [{}, null]]),
|
173 | 'two inequal maps, same size, primitive key, start with primitive key',
|
174 | false,
|
175 | false
|
176 | );
|
177 |
|
178 | t.deepEqualTest(
|
179 | new Map([[undefined, null], ['+000', 2]]),
|
180 | new Map([[null, undefined], [false, '2']]),
|
181 | 'primitive comparisons',
|
182 | true,
|
183 | false
|
184 | );
|
185 |
|
186 | t.end();
|
187 | });
|
188 |
|
189 | test('WeakMaps', { skip: typeof WeakMap !== 'function' }, function (t) {
|
190 | t.deepEqualTest(
|
191 | new WeakMap([[Object, null], [Function, true]]),
|
192 | new WeakMap([[Function, true], [Object, null]]),
|
193 | 'two equal WeakMaps',
|
194 | true,
|
195 | true
|
196 | );
|
197 |
|
198 | t.deepEqualTest(
|
199 | new WeakMap([[Object, null]]),
|
200 | new WeakMap([[Object, true]]),
|
201 | 'two WeakMaps with inequal values on the same key',
|
202 | true,
|
203 | true
|
204 | );
|
205 |
|
206 | t.deepEqualTest(
|
207 | new WeakMap([[Object, null], [Function, true]]),
|
208 | new WeakMap([[Object, null]]),
|
209 | 'two inequal WeakMaps',
|
210 | true,
|
211 | true
|
212 | );
|
213 |
|
214 | t.end();
|
215 | });
|
216 |
|
217 | test('Sets', { skip: typeof Set !== 'function' }, function (t) {
|
218 | t.deepEqualTest(
|
219 | new Set(['a', 1, 'b', 2]),
|
220 | new Set(['b', 2, 'a', 1]),
|
221 | 'two equal Sets',
|
222 | true,
|
223 | true
|
224 | );
|
225 |
|
226 | t.deepEqualTest(
|
227 | new Set(['a', 1]),
|
228 | new Set(['b', 1]),
|
229 | 'two inequal Sets',
|
230 | false,
|
231 | false
|
232 | );
|
233 |
|
234 | t.deepEqualTest(
|
235 | new Set([{}, 1, {}, {}, 2]),
|
236 | new Set([{}, 1, {}, 2, {}]),
|
237 | 'two equal Sets in different orders',
|
238 | true,
|
239 | true
|
240 | );
|
241 |
|
242 | t.deepEqualTest(
|
243 | new Set(),
|
244 | new Set([1]),
|
245 | 'two inequally sized Sets',
|
246 | false,
|
247 | false
|
248 | );
|
249 |
|
250 | t.deepEqualTest(
|
251 | new Set([{ a: 1 }, 2]),
|
252 | new Set(['2', { a: '1' }]),
|
253 | 'two loosely equal, strictly inequal Sets',
|
254 | true,
|
255 | false
|
256 | );
|
257 |
|
258 | t.deepEqualTest(
|
259 | new Set([{ a: 1 }, 2]),
|
260 | new Set(['2', { a: 2 }]),
|
261 | 'two inequal Sets',
|
262 | false,
|
263 | false
|
264 | );
|
265 |
|
266 | t.deepEqualTest(
|
267 | new Set([null, '', 1, 5, 2, false]),
|
268 | new Set([undefined, 0, '5', true, '2', '-000']),
|
269 | 'more primitive comparisons',
|
270 | true,
|
271 | false
|
272 | );
|
273 |
|
274 | t.end();
|
275 | });
|
276 |
|
277 | test('Set and Map', { skip: !Object.defineProperty || typeof Set !== 'function' || typeof Map !== 'function' }, function (t) {
|
278 | t.deepEqualTest(
|
279 | new Set(),
|
280 | new Map(),
|
281 | 'Map and Set',
|
282 | false,
|
283 | false
|
284 | );
|
285 |
|
286 | var maplikeSet = new Set();
|
287 | Object.defineProperty(maplikeSet, 'constructor', { enumerable: false, value: Map });
|
288 | maplikeSet.__proto__ = Map.prototype;
|
289 | t.deepEqualTest(
|
290 | maplikeSet,
|
291 | new Map(),
|
292 | 'Map-like Set, and Map',
|
293 | false,
|
294 | false
|
295 | );
|
296 |
|
297 | t.end();
|
298 | });
|
299 |
|
300 | test('WeakSets', { skip: typeof WeakSet !== 'function' }, function (t) {
|
301 | t.deepEqualTest(
|
302 | new WeakSet([Object, Function]),
|
303 | new WeakSet([Function, Object]),
|
304 | 'two equal WeakSets',
|
305 | true,
|
306 | true
|
307 | );
|
308 |
|
309 | t.deepEqualTest(
|
310 | new WeakSet([Object, Function]),
|
311 | new WeakSet([Object]),
|
312 | 'two inequal WeakSets',
|
313 | true,
|
314 | true
|
315 | );
|
316 |
|
317 | t.end();
|
318 | });
|
319 |
|
320 | test('not equal', function (t) {
|
321 | t.deepEqualTest(
|
322 | { x: 5, y: [6] },
|
323 | { x: 5, y: 6 },
|
324 | 'two inequal objects are',
|
325 | false,
|
326 | false
|
327 | );
|
328 |
|
329 | t.end();
|
330 | });
|
331 |
|
332 | test('nested nulls', function (t) {
|
333 | t.deepEqualTest(
|
334 | [null, null, null],
|
335 | [null, null, null],
|
336 | 'same-length arrays of nulls',
|
337 | true,
|
338 | true,
|
339 | true
|
340 | );
|
341 | t.end();
|
342 | });
|
343 |
|
344 | test('objects with strings vs numbers', function (t) {
|
345 | t.deepEqualTest(
|
346 | [{ a: 3 }, { b: 4 }],
|
347 | [{ a: '3' }, { b: '4' }],
|
348 | 'objects with equivalent string/number values',
|
349 | true,
|
350 | false
|
351 | );
|
352 | t.end();
|
353 | });
|
354 |
|
355 | test('non-objects', function (t) {
|
356 | t.deepEqualTest(3, 3, 'same numbers', true, true, true);
|
357 | t.deepEqualTest('beep', 'beep', 'same strings', true, true, true);
|
358 | t.deepEqualTest('3', 3, 'numeric string and number', true, false);
|
359 | t.deepEqualTest('3', [3], 'numeric string and array containing number', false, false);
|
360 | t.deepEqualTest(3, [3], 'number and array containing number', false, false);
|
361 |
|
362 | t.end();
|
363 | });
|
364 |
|
365 | test('infinities', function (t) {
|
366 | t.deepEqualTest(Infinity, Infinity, '∞ and ∞', true, true, true);
|
367 | t.deepEqualTest(-Infinity, -Infinity, '-∞ and -∞', true, true, true);
|
368 | t.deepEqualTest(Infinity, -Infinity, '∞ and -∞', false, false);
|
369 |
|
370 | t.end();
|
371 | });
|
372 |
|
373 | test('arguments class', function (t) {
|
374 | function getArgs() {
|
375 | return arguments;
|
376 | }
|
377 |
|
378 | t.deepEqualTest(
|
379 | getArgs(1, 2, 3),
|
380 | getArgs(1, 2, 3),
|
381 | 'equivalent arguments objects are equal',
|
382 | true,
|
383 | true,
|
384 | true
|
385 | );
|
386 |
|
387 | t.deepEqualTest(
|
388 | getArgs(1, 2, 3),
|
389 | [1, 2, 3],
|
390 | 'array and arguments with same contents',
|
391 | false,
|
392 | false
|
393 | );
|
394 |
|
395 | var args = getArgs();
|
396 | var notArgs = tag({ length: 0 }, 'Arguments');
|
397 | t.deepEqualTest(
|
398 | args,
|
399 | notArgs,
|
400 | 'args and similar arraylike object',
|
401 | false,
|
402 | false
|
403 | );
|
404 |
|
405 | t.end();
|
406 | });
|
407 |
|
408 | test('Dates', function (t) {
|
409 | var d0 = new Date(1387585278000);
|
410 | var d1 = new Date('Fri Dec 20 2013 16:21:18 GMT-0800 (PST)');
|
411 |
|
412 | t.deepEqualTest(d0, d1, 'two Dates with the same timestamp', true, true);
|
413 |
|
414 | d1.a = true;
|
415 |
|
416 | t.deepEqualTest(d0, d1, 'two Dates with the same timestamp but different own properties', false, false);
|
417 |
|
418 | t.test('overriding `getTime`', { skip: !Object.defineProperty }, function (st) {
|
419 | var a = new Date('2000');
|
420 | var b = new Date('2000');
|
421 | Object.defineProperty(a, 'getTime', { value: function () { return 5; } });
|
422 | st.deepEqualTest(a, b, 'two Dates with the same timestamp but one has overridden `getTime`', true, true);
|
423 | st.end();
|
424 | });
|
425 |
|
426 | t.test('fake Date', { skip: !hasDunderProto }, function (st) {
|
427 | var a = new Date(2000);
|
428 | var b = tag(Object.create(
|
429 | a.__proto__,
|
430 | gOPDs(a)
|
431 | ), 'Date');
|
432 |
|
433 | st.deepEqualTest(
|
434 | a,
|
435 | b,
|
436 | 'Date, and fake Date',
|
437 | false,
|
438 | false
|
439 | );
|
440 |
|
441 | st.end();
|
442 | });
|
443 |
|
444 | var a = new Date('2000');
|
445 | var b = new Date('2000');
|
446 | b.foo = true;
|
447 | t.deepEqualTest(
|
448 | a,
|
449 | b,
|
450 | 'two identical Dates, one with an extra property',
|
451 | false,
|
452 | false
|
453 | );
|
454 |
|
455 | t.deepEqualTest(
|
456 | new Date('2000'),
|
457 | new Date('2001'),
|
458 | 'two inequal Dates',
|
459 | false,
|
460 | false
|
461 | );
|
462 |
|
463 | t.end();
|
464 | });
|
465 |
|
466 | test('buffers', { skip: typeof Buffer !== 'function' }, function (t) {
|
467 |
|
468 | t.deepEqualTest(
|
469 | safeBuffer('xyz'),
|
470 | safeBuffer('xyz'),
|
471 | 'buffers with same contents are equal',
|
472 | true,
|
473 | true
|
474 | );
|
475 |
|
476 | t.deepEqualTest(
|
477 | safeBuffer('xyz'),
|
478 | safeBuffer('xyy'),
|
479 | 'buffers with same length and different contents are inequal',
|
480 | false,
|
481 | false
|
482 | );
|
483 |
|
484 | t.deepEqualTest(
|
485 | safeBuffer('xyz'),
|
486 | safeBuffer('xy'),
|
487 | 'buffers with different length are inequal',
|
488 | false,
|
489 | false
|
490 | );
|
491 |
|
492 | t.deepEqualTest(
|
493 | safeBuffer('abc'),
|
494 | safeBuffer('xyz'),
|
495 | 'buffers with different contents',
|
496 | false,
|
497 | false
|
498 | );
|
499 |
|
500 | var emptyBuffer = safeBuffer('');
|
501 |
|
502 | t.deepEqualTest(
|
503 | emptyBuffer,
|
504 | [],
|
505 | 'empty buffer and empty array',
|
506 | false,
|
507 | false
|
508 | );
|
509 |
|
510 | t.test('bufferlikes', { skip: !Object.defineProperty || !hasTypedArrays }, function (st) {
|
511 | var fakeBuffer = {
|
512 | 0: 'a',
|
513 | length: 1,
|
514 | __proto__: emptyBuffer.__proto__,
|
515 | copy: emptyBuffer.copy,
|
516 | slice: emptyBuffer.slice
|
517 | };
|
518 | Object.defineProperty(fakeBuffer, '0', { enumerable: false });
|
519 | Object.defineProperty(fakeBuffer, 'length', { enumerable: false });
|
520 | Object.defineProperty(fakeBuffer, 'copy', { enumerable: false });
|
521 | Object.defineProperty(fakeBuffer, 'slice', { enumerable: false });
|
522 |
|
523 | st.deepEqualTest(
|
524 | safeBuffer('a'),
|
525 | fakeBuffer,
|
526 | 'real buffer, and mildly fake buffer',
|
527 | false,
|
528 | false
|
529 | );
|
530 |
|
531 | st.test('bufferlike', { skip: buffersAreTypedArrays ? !hasSymbols || !Symbol.toStringTag : false }, function (s2t) {
|
532 | var bufferlike = buffersAreTypedArrays ? new Uint8Array() : {};
|
533 | Object.defineProperty(bufferlike, 'length', {
|
534 | enumerable: false,
|
535 | value: bufferlike.length || 0
|
536 | });
|
537 | Object.defineProperty(bufferlike, 'copy', {
|
538 | enumerable: false,
|
539 | value: emptyBuffer.copy
|
540 | });
|
541 | bufferlike.__proto__ = emptyBuffer.__proto__;
|
542 |
|
543 | s2t.deepEqualTest(
|
544 | emptyBuffer,
|
545 | bufferlike,
|
546 | 'empty buffer and empty bufferlike',
|
547 | true,
|
548 | true
|
549 | );
|
550 | s2t.end();
|
551 | });
|
552 |
|
553 | st.end();
|
554 | });
|
555 |
|
556 | t.end();
|
557 | });
|
558 |
|
559 | test('Arrays', function (t) {
|
560 | var a = [];
|
561 | var b = [];
|
562 | b.foo = true;
|
563 |
|
564 | t.deepEqualTest(
|
565 | a,
|
566 | b,
|
567 | 'two identical arrays, one with an extra property',
|
568 | false,
|
569 | false
|
570 | );
|
571 |
|
572 | t.end();
|
573 | });
|
574 |
|
575 | test('booleans', function (t) {
|
576 | t.deepEqualTest(
|
577 | true,
|
578 | true,
|
579 | 'trues',
|
580 | true,
|
581 | true,
|
582 | false
|
583 | );
|
584 |
|
585 | t.deepEqualTest(
|
586 | false,
|
587 | false,
|
588 | 'falses',
|
589 | true,
|
590 | true,
|
591 | false
|
592 | );
|
593 |
|
594 | t.deepEqualTest(
|
595 | true,
|
596 | false,
|
597 | 'true and false',
|
598 | false,
|
599 | false
|
600 | );
|
601 |
|
602 | t.end();
|
603 | });
|
604 |
|
605 | test('booleans and arrays', function (t) {
|
606 | t.deepEqualTest(
|
607 | true,
|
608 | [],
|
609 | 'true and an empty array',
|
610 | false,
|
611 | false
|
612 | );
|
613 | t.deepEqualTest(
|
614 | false,
|
615 | [],
|
616 | 'false and an empty array',
|
617 | false,
|
618 | false
|
619 | );
|
620 | t.end();
|
621 | });
|
622 |
|
623 | test('arrays initiated', function (t) {
|
624 | var a0 = [
|
625 | undefined,
|
626 | null,
|
627 | -1,
|
628 | 0,
|
629 | 1,
|
630 | false,
|
631 | true,
|
632 | undefined,
|
633 | '',
|
634 | 'abc',
|
635 | null,
|
636 | undefined
|
637 | ];
|
638 | var a1 = [
|
639 | undefined,
|
640 | null,
|
641 | -1,
|
642 | 0,
|
643 | 1,
|
644 | false,
|
645 | true,
|
646 | undefined,
|
647 | '',
|
648 | 'abc',
|
649 | null,
|
650 | undefined
|
651 | ];
|
652 |
|
653 | t.deepEqualTest(
|
654 | a0,
|
655 | a1,
|
656 | 'arrays with equal contents are equal',
|
657 | true,
|
658 | true,
|
659 | true
|
660 | );
|
661 | t.end();
|
662 | });
|
663 |
|
664 | test('arrays assigned', function (t) {
|
665 | var a0 = [
|
666 | undefined,
|
667 | null,
|
668 | -1,
|
669 | 0,
|
670 | 1,
|
671 | false,
|
672 | true,
|
673 | undefined,
|
674 | '',
|
675 | 'abc',
|
676 | null,
|
677 | undefined
|
678 | ];
|
679 | var a1 = [];
|
680 |
|
681 | a1[0] = undefined;
|
682 | a1[1] = null;
|
683 | a1[2] = -1;
|
684 | a1[3] = 0;
|
685 | a1[4] = 1;
|
686 | a1[5] = false;
|
687 | a1[6] = true;
|
688 | a1[7] = undefined;
|
689 | a1[8] = '';
|
690 | a1[9] = 'abc';
|
691 | a1[10] = null;
|
692 | a1[11] = undefined;
|
693 | a1.length = 12;
|
694 |
|
695 | t.deepEqualTest(a0, a1, 'a literal array and an assigned array', true, true);
|
696 | t.end();
|
697 | });
|
698 |
|
699 | test('arrays push', function (t) {
|
700 | var a0 = [
|
701 | undefined,
|
702 | null,
|
703 | -1,
|
704 | 0,
|
705 | 1,
|
706 | false,
|
707 | true,
|
708 | undefined,
|
709 | '',
|
710 | 'abc',
|
711 | null,
|
712 | undefined
|
713 | ],
|
714 | a1 = [];
|
715 |
|
716 | a1.push(undefined);
|
717 | a1.push(null);
|
718 | a1.push(-1);
|
719 | a1.push(0);
|
720 | a1.push(1);
|
721 | a1.push(false);
|
722 | a1.push(true);
|
723 | a1.push(undefined);
|
724 | a1.push('');
|
725 | a1.push('abc');
|
726 | a1.push(null);
|
727 | a1.push(undefined);
|
728 | a1.length = 12;
|
729 |
|
730 | t.deepEqualTest(a0, a1, 'a literal array and a pushed array', true, true);
|
731 | t.end();
|
732 | });
|
733 |
|
734 | test('null == undefined', function (t) {
|
735 | t.deepEqualTest(null, undefined, 'null and undefined', true, false);
|
736 | t.deepEqualTest([null], [undefined], '[null] and [undefined]', true, false);
|
737 |
|
738 | t.end();
|
739 | });
|
740 |
|
741 |
|
742 | var isNode14 = isNode && process.env.ASSERT && semver.satisfies(process.version, '>= 14');
|
743 | test('NaNs', function (t) {
|
744 | t.deepEqualTest(
|
745 | NaN,
|
746 | NaN,
|
747 | 'two NaNs',
|
748 | isNode14,
|
749 | true
|
750 | );
|
751 |
|
752 | t.deepEqualTest(
|
753 | { a: NaN },
|
754 | { a: NaN },
|
755 | 'two equiv objects with a NaN value',
|
756 | isNode14,
|
757 | true
|
758 | );
|
759 |
|
760 | t.deepEqualTest(NaN, 1, 'NaN and 1', false, false);
|
761 |
|
762 | t.end();
|
763 | });
|
764 |
|
765 | test('zeroes', function (t) {
|
766 | t.deepEqualTest(0, -0, '0 and -0', true, false);
|
767 |
|
768 | t.deepEqualTest({ a: 0 }, { a: -0 }, 'two objects with a same-keyed 0/-0 value', true, false);
|
769 |
|
770 | t.end();
|
771 | });
|
772 |
|
773 | test('Object.create', { skip: !Object.create }, function (t) {
|
774 | var a = { a: 'A' };
|
775 | var b = Object.create(a);
|
776 | b.b = 'B';
|
777 | var c = Object.create(a);
|
778 | c.b = 'C';
|
779 |
|
780 | t.deepEqualTest(
|
781 | b,
|
782 | c,
|
783 | 'two objects with the same [[Prototype]] but a different own property',
|
784 | false,
|
785 | false
|
786 | );
|
787 |
|
788 | t.end();
|
789 | });
|
790 |
|
791 | test('Object.create(null)', { skip: !Object.create }, function (t) {
|
792 | t.deepEqualTest(
|
793 | Object.create(null),
|
794 | Object.create(null),
|
795 | 'two empty null objects',
|
796 | true,
|
797 | true,
|
798 | true
|
799 | );
|
800 |
|
801 | t.deepEqualTest(
|
802 | Object.create(null, { a: { value: 'b' } }),
|
803 | Object.create(null, { a: { value: 'b' } }),
|
804 | 'two null objects with the same property pair',
|
805 | true,
|
806 | true,
|
807 | true
|
808 | );
|
809 |
|
810 | t.end();
|
811 | });
|
812 |
|
813 | test('regexes vs dates', function (t) {
|
814 | var d = new Date(1387585278000);
|
815 | var r = /abc/;
|
816 |
|
817 | t.deepEqualTest(d, r, 'Date and RegExp', false, false);
|
818 |
|
819 | t.end();
|
820 | });
|
821 |
|
822 | test('regexen', function (t) {
|
823 | t.deepEqualTest(/abc/, /xyz/, 'two different regexes', false, false);
|
824 | t.deepEqualTest(/abc/, /abc/, 'two abc regexes', true, true, false);
|
825 | t.deepEqualTest(/xyz/, /xyz/, 'two xyz regexes', true, true, false);
|
826 |
|
827 | t.test('fake RegExp', { skip: !hasDunderProto }, function (st) {
|
828 | var a = /abc/g;
|
829 | var b = tag(Object.create(
|
830 | a.__proto__,
|
831 | gOPDs(a)
|
832 | ), 'RegExp');
|
833 |
|
834 | st.deepEqualTest(a, b, 'regex and fake regex', false, false);
|
835 |
|
836 | st.end();
|
837 | });
|
838 |
|
839 | var a = /abc/gi;
|
840 | var b = /abc/gi;
|
841 | b.foo = true;
|
842 | t.deepEqualTest(
|
843 | a,
|
844 | b,
|
845 | 'two identical regexes, one with an extra property',
|
846 | false,
|
847 | false
|
848 | );
|
849 |
|
850 | t.end();
|
851 | });
|
852 |
|
853 | test('object literals', function (t) {
|
854 | t.deepEqualTest(
|
855 | { prototype: 2 },
|
856 | { prototype: '2' },
|
857 | 'two loosely equal, strictly inequal prototype properties',
|
858 | true,
|
859 | false
|
860 | );
|
861 |
|
862 | t.end();
|
863 | });
|
864 |
|
865 | test('arrays and objects', function (t) {
|
866 | t.deepEqualTest([], {}, 'empty array and empty object', false, false);
|
867 | t.deepEqualTest([], { length: 0 }, 'empty array and empty arraylike object', false, false);
|
868 | t.deepEqualTest([1], { 0: 1 }, 'array and similar object', false, false);
|
869 |
|
870 | t.end();
|
871 | });
|
872 |
|
873 | test('functions', function (t) {
|
874 | function f() {}
|
875 |
|
876 | t.deepEqualTest(f, f, 'a function and itself', true, true, true);
|
877 | t.deepEqualTest([f], [f], 'a function and itself in an array', true, true, true);
|
878 |
|
879 | t.deepEqualTest(function () {}, function () {}, 'two distinct functions', false, false, true);
|
880 | t.deepEqualTest([function () {}], [function () {}], 'two distinct functions in an array', false, false, true);
|
881 |
|
882 | t.deepEqualTest(f, {}, 'function and object', false, false, true);
|
883 | t.deepEqualTest([f], [{}], 'function and object in an array', false, false, true);
|
884 |
|
885 | t.end();
|
886 | });
|
887 |
|
888 | test('Errors', function (t) {
|
889 | t.deepEqualTest(new Error('xyz'), new Error('xyz'), 'two errors of the same type with the same message', true, true, false);
|
890 | t.deepEqualTest(new Error('xyz'), new TypeError('xyz'), 'two errors of different types with the same message', false, false);
|
891 | t.deepEqualTest(new Error('xyz'), new Error('zyx'), 'two errors of the same type with a different message', false, false);
|
892 |
|
893 | t.test('errorlike', { skip: !Object.defineProperty }, function (st) {
|
894 | var err = new Error('foo');
|
895 |
|
896 | var errorlike = tag({ message: err.message, stack: err.stack, name: err.name, constructor: err.constructor }, 'Error');
|
897 | Object.defineProperty(errorlike, 'message', { enumerable: false });
|
898 | Object.defineProperty(errorlike, 'stack', { enumerable: false });
|
899 | Object.defineProperty(errorlike, 'name', { enumerable: false });
|
900 | Object.defineProperty(errorlike, 'constructor', { enumerable: false });
|
901 | st.notOk(errorlike instanceof Error);
|
902 | st.ok(err instanceof Error);
|
903 | st.deepEqualTest(
|
904 | err,
|
905 | errorlike,
|
906 | 'error, and errorlike object',
|
907 | false,
|
908 | false
|
909 | );
|
910 |
|
911 | st.end();
|
912 | });
|
913 |
|
914 | t.deepEqualTest(
|
915 | new Error('a'),
|
916 | assign(new Error('a'), { code: 10 }),
|
917 | 'two otherwise equal errors with different own properties',
|
918 | false,
|
919 | false
|
920 | );
|
921 |
|
922 | t.test('fake error', { skip: !process.env.ASSERT || !hasDunderProto }, function (st) {
|
923 | var a = tag({
|
924 | __proto__: null
|
925 | }, 'Error');
|
926 | var b = new RangeError('abc');
|
927 | b.__proto__ = null;
|
928 |
|
929 | st.deepEqualTest(
|
930 | a,
|
931 | b,
|
932 | 'null object faking as an Error, RangeError with null proto',
|
933 | false,
|
934 | false
|
935 | );
|
936 | st.end();
|
937 | });
|
938 |
|
939 | t.end();
|
940 | });
|
941 |
|
942 | test('object and null', function (t) {
|
943 | t.deepEqualTest(
|
944 | {},
|
945 | null,
|
946 | 'null and an object',
|
947 | false,
|
948 | false
|
949 | );
|
950 |
|
951 | t.end();
|
952 | });
|
953 |
|
954 | test('errors', function (t) {
|
955 |
|
956 | t.end();
|
957 | });
|
958 |
|
959 | test('error = Object', function (t) {
|
960 | t.deepEqualTest(
|
961 | new Error('a'),
|
962 | { message: 'a' },
|
963 | false,
|
964 | false
|
965 | );
|
966 |
|
967 | t.end();
|
968 | });
|
969 |
|
970 | test('[[Prototypes]]', function (t) {
|
971 | function C() {}
|
972 | var instance = new C();
|
973 | delete instance.constructor;
|
974 |
|
975 | t.deepEqualTest({}, instance, 'two identical objects with different [[Prototypes]]', true, false);
|
976 |
|
977 | t.test('Dates with different prototypes', { skip: !hasDunderProto }, function (st) {
|
978 | var d1 = new Date(0);
|
979 | var d2 = new Date(0);
|
980 |
|
981 | st.deepEqualTest(d1, d2, 'two dates with the same timestamp', true, true);
|
982 |
|
983 | var newProto = {
|
984 | __proto__: Date.prototype
|
985 | };
|
986 | d2.__proto__ = newProto;
|
987 | st.ok(d2 instanceof Date, 'd2 is still a Date instance after tweaking [[Prototype]]');
|
988 |
|
989 | st.deepEqualTest(d1, d2, 'two dates with the same timestamp and different [[Prototype]]', true, false);
|
990 |
|
991 | st.end();
|
992 | });
|
993 |
|
994 | t.end();
|
995 | });
|
996 |
|
997 | test('toStringTag', { skip: !hasSymbols || !Symbol.toStringTag }, function (t) {
|
998 | var o1 = {};
|
999 | t.equal(Object.prototype.toString.call(o1), '[object Object]', 'o1: Symbol.toStringTag works');
|
1000 |
|
1001 | var o2 = {};
|
1002 | t.equal(Object.prototype.toString.call(o2), '[object Object]', 'o2: original Symbol.toStringTag works');
|
1003 |
|
1004 | t.deepEqualTest(o1, o2, 'two normal empty objects', true, true);
|
1005 |
|
1006 | o2[Symbol.toStringTag] = 'jifasnif';
|
1007 | t.equal(Object.prototype.toString.call(o2), '[object jifasnif]', 'o2: modified Symbol.toStringTag works');
|
1008 |
|
1009 | t.deepEqualTest(o1, o2, 'two normal empty objects with different toStringTags', false, false);
|
1010 |
|
1011 | t.end();
|
1012 | });
|
1013 |
|
1014 | test('boxed primitives', function (t) {
|
1015 | t.deepEqualTest(Object(false), false, 'boxed and primitive `false`', false, false);
|
1016 | t.deepEqualTest(Object(true), true, 'boxed and primitive `true`', false, false);
|
1017 | t.deepEqualTest(Object(3), 3, 'boxed and primitive `3`', false, false);
|
1018 | t.deepEqualTest(Object(NaN), NaN, 'boxed and primitive `NaN`', false, false);
|
1019 | t.deepEqualTest(Object(''), '', 'boxed and primitive `""`', false, false);
|
1020 | t.deepEqualTest(Object('str'), 'str', 'boxed and primitive `"str"`', false, false);
|
1021 |
|
1022 | t.test('symbol', { skip: !hasSymbols }, function (st) {
|
1023 | var s = Symbol('');
|
1024 | st.deepEqualTest(Object(s), s, 'boxed and primitive `Symbol()`', false, false);
|
1025 | st.end();
|
1026 | });
|
1027 |
|
1028 | t.test('bigint', { skip: typeof BigInt !== 'function' }, function (st) {
|
1029 | var hhgtg = BigInt(42);
|
1030 | st.deepEqualTest(Object(hhgtg), hhgtg, 'boxed and primitive `BigInt(42)`', false, false);
|
1031 | st.end();
|
1032 | });
|
1033 |
|
1034 | t.test('`valueOf` is called for boxed primitives', function (st) {
|
1035 | var a = Object(5);
|
1036 | a.valueOf = function () { throw new Error('failed'); };
|
1037 | var b = Object(5);
|
1038 | b.valueOf = function () { throw new Error('failed'); };
|
1039 |
|
1040 | st.deepEqualTest(a, b, 'two boxed numbers with a thrower valueOf', false, false);
|
1041 |
|
1042 | st.end();
|
1043 | });
|
1044 |
|
1045 | t.end();
|
1046 | });
|
1047 |
|
1048 | test('getters', { skip: !Object.defineProperty }, function (t) {
|
1049 | var a = {};
|
1050 | Object.defineProperty(a, 'a', { enumerable: true, get: function () { return 5; } });
|
1051 | var b = {};
|
1052 | Object.defineProperty(b, 'a', { enumerable: true, get: function () { return 6; } });
|
1053 |
|
1054 | t.deepEqualTest(a, b, 'two objects with the same getter but producing different values', false, false);
|
1055 |
|
1056 | t.end();
|
1057 | });
|
1058 |
|
1059 | var isBrokenNode = isNode && process.env.ASSERT && semver.satisfies(process.version, '<= 13.3.0');
|
1060 | test('fake arrays: extra keys will be tested', { skip: !hasDunderProto || isBrokenNode }, function (t) {
|
1061 | var a = tag({
|
1062 | __proto__: Array.prototype,
|
1063 | 0: 1,
|
1064 | 1: 1,
|
1065 | 2: 'broken',
|
1066 | length: 2
|
1067 | }, 'Array');
|
1068 | if (Object.defineProperty) {
|
1069 | Object.defineProperty(a, 'length', {
|
1070 | enumerable: false
|
1071 | });
|
1072 | }
|
1073 |
|
1074 | t.deepEqualTest(a, [1, 1], 'fake and real array with same contents and [[Prototype]]', false, false);
|
1075 |
|
1076 | var b = tag(/abc/, 'Array');
|
1077 | b.__proto__ = Array.prototype;
|
1078 | b.length = 3;
|
1079 | if (Object.defineProperty) {
|
1080 | Object.defineProperty(b, 'length', {
|
1081 | enumerable: false
|
1082 | });
|
1083 | }
|
1084 | t.deepEqualTest(b, ['a', 'b', 'c'], 'regex faking as array, and array', false, false);
|
1085 |
|
1086 | t.end();
|
1087 | });
|
1088 |
|
1089 | test('circular references', function (t) {
|
1090 | var b = {};
|
1091 | b.b = b;
|
1092 |
|
1093 | var c = {};
|
1094 | c.b = c;
|
1095 |
|
1096 | t.deepEqualTest(
|
1097 | b,
|
1098 | c,
|
1099 | 'two self-referencing objects',
|
1100 | true,
|
1101 | true
|
1102 | );
|
1103 |
|
1104 | var d = {};
|
1105 | d.a = 1;
|
1106 | d.b = d;
|
1107 |
|
1108 | var e = {};
|
1109 | e.a = 1;
|
1110 | e.b = e.a;
|
1111 |
|
1112 | t.deepEqualTest(
|
1113 | d,
|
1114 | e,
|
1115 | 'two deeply self-referencing objects',
|
1116 | false,
|
1117 | false
|
1118 | );
|
1119 |
|
1120 | t.end();
|
1121 | });
|
1122 |
|
1123 |
|
1124 | var isNodeWhereBufferBreaks = isNode && semver.satisfies(process.version, '< 3');
|
1125 | var isNode06 = isNode && semver.satisfies(process.version, '<= 0.6');
|
1126 |
|
1127 | test('TypedArrays', { skip: !hasTypedArrays }, function (t) {
|
1128 | t.test('Buffer faked as Uint8Array', { skip: typeof Buffer !== 'function' || !Object.create || !hasDunderProto || isNode06 }, function (st) {
|
1129 | var a = safeBuffer('test');
|
1130 | var b = tag(Object.create(
|
1131 | a.__proto__,
|
1132 | assign(gOPDs(a), {
|
1133 | length: {
|
1134 | enumerable: false,
|
1135 | value: 4
|
1136 | }
|
1137 | })
|
1138 | ), 'Uint8Array');
|
1139 |
|
1140 | st.deepEqualTest(
|
1141 | a,
|
1142 | b,
|
1143 | 'Buffer and Uint8Array',
|
1144 | isNodeWhereBufferBreaks,
|
1145 | isNodeWhereBufferBreaks
|
1146 | );
|
1147 |
|
1148 | st.end();
|
1149 | });
|
1150 |
|
1151 | t.test('one TypedArray faking as another', { skip: !hasDunderProto }, function (st) {
|
1152 |
|
1153 | var a = new Uint8Array(10);
|
1154 | var b = tag(new Int8Array(10), 'Uint8Array');
|
1155 | b.__proto__ = Uint8Array.prototype;
|
1156 |
|
1157 | st.deepEqualTest(
|
1158 | a,
|
1159 | b,
|
1160 | 'Uint8Array, and Int8Array pretending to be a Uint8Array',
|
1161 | false,
|
1162 | false
|
1163 | );
|
1164 |
|
1165 | st.end();
|
1166 | });
|
1167 |
|
1168 | t.end();
|
1169 | });
|