2323const {
2424 ArrayBufferIsView,
2525 ArrayBufferPrototypeGetByteLength,
26- ArrayFrom,
2726 ArrayIsArray,
2827 ArrayPrototypeIndexOf,
2928 ArrayPrototypeJoin,
@@ -395,12 +394,11 @@ function partiallyCompareMaps(actual, expected, comparedObjects) {
395394 const expectedIterator = FunctionPrototypeCall ( SafeMap . prototype [ SymbolIterator ] , expected ) ;
396395
397396 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 ) ) {
399399 return false ;
400400 }
401401
402- const actualValue = MapPrototypeGet ( actual , key ) ;
403-
404402 if ( ! compareBranch ( actualValue , expectedValue , comparedObjects ) ) {
405403 return false ;
406404 }
@@ -475,24 +473,59 @@ function partiallyCompareArrayBuffersOrViews(actual, expected) {
475473}
476474
477475function 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 ;
480484 }
481485
482486 if ( isDeepEqual === undefined ) lazyLoadComparison ( ) ;
483487
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
485490 const expectedIterator = FunctionPrototypeCall ( SafeSet . prototype [ SymbolIterator ] , expected ) ;
486- const usedIndices = new SafeSet ( ) ;
487491
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 ;
493523 }
494524 }
495- return false ;
525+
526+ if ( ! foundMatch ) {
527+ return false ;
528+ }
496529 }
497530
498531 return true ;
@@ -510,21 +543,26 @@ function getZeroKey(item) {
510543}
511544
512545function partiallyCompareArrays ( actual , expected , comparedObjects ) {
546+ if ( actual === expected ) return true ;
547+
513548 if ( expected . length > actual . length ) {
514549 return false ;
515550 }
516551
552+ if ( expected . length === 0 ) {
553+ return true ;
554+ }
555+
517556 if ( isDeepEqual === undefined ) lazyLoadComparison ( ) ;
518557
519558 // Create a map to count occurrences of each element in the expected array
520559 const expectedCounts = new SafeMap ( ) ;
521- const safeExpected = new SafeArrayIterator ( expected ) ;
522560
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 ) {
525563 if ( expectedItem === 0 ) {
526564 const zeroKey = getZeroKey ( expectedItem ) ;
527- expectedCounts . set ( zeroKey , ( expectedCounts . get ( zeroKey ) ?. count || 0 ) + 1 ) ;
565+ expectedCounts . set ( zeroKey , ( expectedCounts . get ( zeroKey ) ?? 0 ) + 1 ) ;
528566 } else {
529567 let found = false ;
530568 for ( const { 0 : key , 1 : count } of expectedCounts ) {
@@ -540,10 +578,8 @@ function partiallyCompareArrays(actual, expected, comparedObjects) {
540578 }
541579 }
542580
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 ) {
547583 if ( actualItem === 0 ) {
548584 const zeroKey = getZeroKey ( actualItem ) ;
549585
@@ -567,6 +603,10 @@ function partiallyCompareArrays(actual, expected, comparedObjects) {
567603 }
568604 }
569605 }
606+
607+ if ( expectedCounts . size === 0 ) {
608+ return true ;
609+ }
570610 }
571611
572612 return expectedCounts . size === 0 ;
@@ -723,6 +763,10 @@ function compareExceptionKey(actual, expected, key, message, keys, fn) {
723763 }
724764}
725765
766+ function isPrimitive ( value ) {
767+ return typeof value !== 'object' || value === null ;
768+ }
769+
726770function expectedException ( actual , expected , message , fn ) {
727771 let generatedMessage = false ;
728772 let throwError = false ;
@@ -741,7 +785,7 @@ function expectedException(actual, expected, message, fn) {
741785 }
742786 throwError = true ;
743787 // Handle primitives properly.
744- } else if ( typeof actual !== 'object' || actual === null ) {
788+ } else if ( isPrimitive ( actual ) ) {
745789 const err = new AssertionError ( {
746790 actual,
747791 expected,
0 commit comments