23
23
const {
24
24
ArrayBufferIsView,
25
25
ArrayBufferPrototypeGetByteLength,
26
- ArrayFrom,
27
26
ArrayIsArray,
28
27
ArrayPrototypeIndexOf,
29
28
ArrayPrototypeJoin,
@@ -395,12 +394,11 @@ function partiallyCompareMaps(actual, expected, comparedObjects) {
395
394
const expectedIterator = FunctionPrototypeCall ( SafeMap . prototype [ SymbolIterator ] , expected ) ;
396
395
397
396
for ( const { 0 : key , 1 : expectedValue } of expectedIterator ) {
398
- if ( ! MapPrototypeHas ( actual , key ) ) {
397
+ const actualValue = MapPrototypeGet ( actual , key ) ;
398
+ if ( actualValue === undefined && ! MapPrototypeHas ( actual , key ) ) {
399
399
return false ;
400
400
}
401
401
402
- const actualValue = MapPrototypeGet ( actual , key ) ;
403
-
404
402
if ( ! compareBranch ( actualValue , expectedValue , comparedObjects ) ) {
405
403
return false ;
406
404
}
@@ -475,24 +473,59 @@ function partiallyCompareArrayBuffersOrViews(actual, expected) {
475
473
}
476
474
477
475
function partiallyCompareSets ( actual , expected , comparedObjects ) {
478
- if ( SetPrototypeGetSize ( expected ) > SetPrototypeGetSize ( actual ) ) {
479
- return false ; // `expected` can't be a subset if it has more elements
476
+ if ( actual === expected ) return true ;
477
+
478
+ const expectedSize = SetPrototypeGetSize ( expected ) ;
479
+ if ( expectedSize === 0 ) return true ;
480
+
481
+ const actualSize = SetPrototypeGetSize ( actual ) ;
482
+ if ( expectedSize > actualSize ) {
483
+ return false ;
480
484
}
481
485
482
486
if ( isDeepEqual === undefined ) lazyLoadComparison ( ) ;
483
487
484
- const actualArray = ArrayFrom ( FunctionPrototypeCall ( SafeSet . prototype [ SymbolIterator ] , actual ) ) ;
488
+ // Separate expected items into direct matches and those needing deep comparison
489
+ const expectedItemsToCompare = [ ] ; // Items that need deep comparison
485
490
const expectedIterator = FunctionPrototypeCall ( SafeSet . prototype [ SymbolIterator ] , expected ) ;
486
- const usedIndices = new SafeSet ( ) ;
487
491
488
- expectedIteration: for ( const expectedItem of expectedIterator ) {
489
- for ( let actualIdx = 0 ; actualIdx < actualArray . length ; actualIdx ++ ) {
490
- if ( ! usedIndices . has ( actualIdx ) && isDeepStrictEqual ( actualArray [ actualIdx ] , expectedItem ) ) {
491
- usedIndices . add ( actualIdx ) ;
492
- continue expectedIteration;
492
+ for ( const expectedItem of expectedIterator ) {
493
+ if ( actual . has ( expectedItem ) ) {
494
+ continue ;
495
+ } else if ( isPrimitive ( expectedItem ) ) {
496
+ return false ;
497
+ } else {
498
+ expectedItemsToCompare . push ( expectedItem ) ;
499
+ }
500
+ }
501
+
502
+ if ( expectedItemsToCompare . length === 0 ) {
503
+ return true ;
504
+ }
505
+
506
+ // Only collect non-primitive items from actual for deep comparison
507
+ const actualSet = new SafeSet ( ) ;
508
+ for ( const item of FunctionPrototypeCall ( SafeSet . prototype [ SymbolIterator ] , actual ) ) {
509
+ if ( ! isPrimitive ( item ) ) {
510
+ actualSet . add ( item ) ;
511
+ }
512
+ }
513
+
514
+ // Now do deep comparison for the remaining expected items
515
+ for ( const expectedItem of expectedItemsToCompare ) {
516
+ let foundMatch = false ;
517
+
518
+ for ( const actualItem of actualSet ) {
519
+ if ( isDeepStrictEqual ( actualItem , expectedItem ) ) {
520
+ actualSet . delete ( actualItem ) ;
521
+ foundMatch = true ;
522
+ break ;
493
523
}
494
524
}
495
- return false ;
525
+
526
+ if ( ! foundMatch ) {
527
+ return false ;
528
+ }
496
529
}
497
530
498
531
return true ;
@@ -510,21 +543,26 @@ function getZeroKey(item) {
510
543
}
511
544
512
545
function partiallyCompareArrays ( actual , expected , comparedObjects ) {
546
+ if ( actual === expected ) return true ;
547
+
513
548
if ( expected . length > actual . length ) {
514
549
return false ;
515
550
}
516
551
552
+ if ( expected . length === 0 ) {
553
+ return true ;
554
+ }
555
+
517
556
if ( isDeepEqual === undefined ) lazyLoadComparison ( ) ;
518
557
519
558
// Create a map to count occurrences of each element in the expected array
520
559
const expectedCounts = new SafeMap ( ) ;
521
- const safeExpected = new SafeArrayIterator ( expected ) ;
522
560
523
- for ( const expectedItem of safeExpected ) {
524
- // Check if the item is a zero or a -0, as these need to be handled separately
561
+ const expectedIterator = new SafeArrayIterator ( expected ) ;
562
+ for ( const expectedItem of expectedIterator ) {
525
563
if ( expectedItem === 0 ) {
526
564
const zeroKey = getZeroKey ( expectedItem ) ;
527
- expectedCounts . set ( zeroKey , ( expectedCounts . get ( zeroKey ) ?. count || 0 ) + 1 ) ;
565
+ expectedCounts . set ( zeroKey , ( expectedCounts . get ( zeroKey ) ?? 0 ) + 1 ) ;
528
566
} else {
529
567
let found = false ;
530
568
for ( const { 0 : key , 1 : count } of expectedCounts ) {
@@ -540,10 +578,8 @@ function partiallyCompareArrays(actual, expected, comparedObjects) {
540
578
}
541
579
}
542
580
543
- const safeActual = new SafeArrayIterator ( actual ) ;
544
-
545
- for ( const actualItem of safeActual ) {
546
- // Check if the item is a zero or a -0, as these need to be handled separately
581
+ const actualIterator = new SafeArrayIterator ( actual ) ;
582
+ for ( const actualItem of actualIterator ) {
547
583
if ( actualItem === 0 ) {
548
584
const zeroKey = getZeroKey ( actualItem ) ;
549
585
@@ -567,6 +603,10 @@ function partiallyCompareArrays(actual, expected, comparedObjects) {
567
603
}
568
604
}
569
605
}
606
+
607
+ if ( expectedCounts . size === 0 ) {
608
+ return true ;
609
+ }
570
610
}
571
611
572
612
return expectedCounts . size === 0 ;
@@ -723,6 +763,10 @@ function compareExceptionKey(actual, expected, key, message, keys, fn) {
723
763
}
724
764
}
725
765
766
+ function isPrimitive ( value ) {
767
+ return typeof value !== 'object' || value === null ;
768
+ }
769
+
726
770
function expectedException ( actual , expected , message , fn ) {
727
771
let generatedMessage = false ;
728
772
let throwError = false ;
@@ -741,7 +785,7 @@ function expectedException(actual, expected, message, fn) {
741
785
}
742
786
throwError = true ;
743
787
// Handle primitives properly.
744
- } else if ( typeof actual !== 'object' || actual === null ) {
788
+ } else if ( isPrimitive ( actual ) ) {
745
789
const err = new AssertionError ( {
746
790
actual,
747
791
expected,
0 commit comments