@@ -192,7 +192,7 @@ export async function capsule({
192192 value : async function ( this : any , actual : any , opts ?: { strict ?: boolean } ) : Promise < void > {
193193 const strict = opts ?. strict === true
194194
195- const isUpdate = process . env . UPDATE_SNAPSHOTS === '1' || process . argv . includes ( '--update-snapshots' ) || process . argv . includes ( '-u' )
195+ const isUpdate = process . env . UPDATE_SNAPSHOTS === '1' || process . env . BUN_UPDATE_SNAPSHOTS === '1' || process . argv . includes ( '--update-snapshots' ) || process . argv . includes ( '-u' )
196196 const expect = this . bunTest . expect
197197
198198 // Build the snapshot key from describe stack + current it name
@@ -205,15 +205,37 @@ export async function capsule({
205205 this . _snapshotCounters . set ( baseKey , count )
206206 const snapshotKey = `${ baseKey } #${ count } `
207207
208- // Stabilize the actual value: sort all keys/arrays deterministically
209- const stabilize = ( obj : any ) : any => JSON . parse ( stringify ( obj ) || 'null' )
210- const stabilized = stabilize ( actual )
208+ // Stabilize for storage: sort object keys only (preserves array order in snapshots)
209+ const stabilizeForStorage = ( obj : any ) : any => JSON . parse ( stringify ( obj ) || 'null' )
210+
211+ // Deep sort for comparison: sort both object keys AND array elements recursively
212+ const deepSortForComparison = ( obj : any ) : any => {
213+ if ( obj === null || obj === undefined ) return obj
214+ if ( Array . isArray ( obj ) ) {
215+ // Recursively sort array elements, then sort the array itself
216+ const sorted = obj . map ( deepSortForComparison )
217+ // Sort arrays by their JSON representation for deterministic ordering
218+ return sorted . sort ( ( a , b ) => {
219+ const aStr = JSON . stringify ( a ) ?? ''
220+ const bStr = JSON . stringify ( b ) ?? ''
221+ return aStr . localeCompare ( bStr )
222+ } )
223+ }
224+ if ( typeof obj === 'object' ) {
225+ const sorted : Record < string , any > = { }
226+ for ( const key of Object . keys ( obj ) . sort ( ) ) {
227+ sorted [ key ] = deepSortForComparison ( obj [ key ] )
228+ }
229+ return sorted
230+ }
231+ return obj
232+ }
211233
212234 const snapshots = await this . _loadSnapshots ( )
213235
214236 if ( isUpdate || ! ( snapshotKey in snapshots ) ) {
215- // Write mode: store the stabilized value
216- snapshots [ snapshotKey ] = stabilized
237+ // Write mode: store with sorted keys but preserve array order
238+ snapshots [ snapshotKey ] = stabilizeForStorage ( actual )
217239 this . _snapshotDirty = true
218240 return
219241 }
@@ -222,13 +244,15 @@ export async function capsule({
222244 const stored = snapshots [ snapshotKey ]
223245
224246 if ( strict ) {
225- // Strict mode: exact deep equality (order matters)
247+ // Strict mode: exact deep equality (order matters for both keys and arrays)
248+ const stabilized = stabilizeForStorage ( actual )
226249 expect ( stabilized ) . toEqual ( stored )
227250 } else {
228251 // Default mode: sort-order-ignorant deep comparison
229- // Both sides are stabilized through json-stable-stringify
230- const storedStabilized = stabilize ( stored )
231- expect ( stabilized ) . toEqual ( storedStabilized )
252+ // Both sides are deeply sorted (keys AND arrays)
253+ const actualSorted = deepSortForComparison ( actual )
254+ const storedSorted = deepSortForComparison ( stored )
255+ expect ( actualSorted ) . toEqual ( storedSorted )
232256 }
233257 }
234258 } ,
0 commit comments