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 }
@@ -481,18 +479,38 @@ function partiallyCompareSets(actual, expected, comparedObjects) {
481479
482480 if ( isDeepEqual === undefined ) lazyLoadComparison ( ) ;
483481
484- const actualArray = ArrayFrom ( FunctionPrototypeCall ( SafeSet . prototype [ SymbolIterator ] , actual ) ) ;
482+ // Create a map for faster lookups
483+ const actualMap = new SafeMap ( ) ;
484+ const actualIterator = FunctionPrototypeCall ( SafeSet . prototype [ SymbolIterator ] , actual ) ;
485485 const expectedIterator = FunctionPrototypeCall ( SafeSet . prototype [ SymbolIterator ] , expected ) ;
486- const usedIndices = new SafeSet ( ) ;
487486
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;
487+ for ( const actualItem of actualIterator ) {
488+ actualMap . set ( actualItem , true ) ;
489+ }
490+
491+ for ( const expectedItem of expectedIterator ) {
492+ let foundMatch = false ;
493+
494+ // Check for primitives first to avoid useless loops
495+ if ( isPrimitive ( expectedItem ) ) {
496+ if ( actualMap . has ( expectedItem ) ) {
497+ actualMap . delete ( expectedItem ) ;
498+ foundMatch = true ;
499+ }
500+ } else {
501+ // Check for non-primitives
502+ for ( const { 0 : actualItem } of actualMap ) {
503+ if ( isDeepStrictEqual ( actualItem , expectedItem ) ) {
504+ actualMap . delete ( actualItem ) ;
505+ foundMatch = true ;
506+ break ;
507+ }
493508 }
494509 }
495- return false ;
510+
511+ if ( ! foundMatch ) {
512+ return false ;
513+ }
496514 }
497515
498516 return true ;
@@ -518,13 +536,11 @@ function partiallyCompareArrays(actual, expected, comparedObjects) {
518536
519537 // Create a map to count occurrences of each element in the expected array
520538 const expectedCounts = new SafeMap ( ) ;
521- const safeExpected = new SafeArrayIterator ( expected ) ;
522539
523- for ( const expectedItem of safeExpected ) {
524- // Check if the item is a zero or a -0, as these need to be handled separately
540+ for ( const expectedItem of new SafeArrayIterator ( expected ) ) {
525541 if ( expectedItem === 0 ) {
526542 const zeroKey = getZeroKey ( expectedItem ) ;
527- expectedCounts . set ( zeroKey , ( expectedCounts . get ( zeroKey ) ?. count || 0 ) + 1 ) ;
543+ expectedCounts . set ( zeroKey , ( expectedCounts . get ( zeroKey ) ?? 0 ) + 1 ) ;
528544 } else {
529545 let found = false ;
530546 for ( const { 0 : key , 1 : count } of expectedCounts ) {
@@ -540,10 +556,7 @@ function partiallyCompareArrays(actual, expected, comparedObjects) {
540556 }
541557 }
542558
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
559+ for ( const actualItem of new SafeArrayIterator ( actual ) ) {
547560 if ( actualItem === 0 ) {
548561 const zeroKey = getZeroKey ( actualItem ) ;
549562
@@ -723,6 +736,10 @@ function compareExceptionKey(actual, expected, key, message, keys, fn) {
723736 }
724737}
725738
739+ function isPrimitive ( value ) {
740+ return typeof value !== 'object' || value === null ;
741+ }
742+
726743function expectedException ( actual , expected , message , fn ) {
727744 let generatedMessage = false ;
728745 let throwError = false ;
@@ -741,7 +758,7 @@ function expectedException(actual, expected, message, fn) {
741758 }
742759 throwError = true ;
743760 // Handle primitives properly.
744- } else if ( typeof actual !== 'object' || actual === null ) {
761+ } else if ( isPrimitive ( actual ) ) {
745762 const err = new AssertionError ( {
746763 actual,
747764 expected,
0 commit comments