Skip to content

Commit 5c7604d

Browse files
committed
Published using @Stream44 Studio
Signed-off-by: Christoph <christoph@christoph.diy>
1 parent 379b90b commit 5c7604d

2 files changed

Lines changed: 35 additions & 11 deletions

File tree

caps/ProjectTest.ts

Lines changed: 34 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -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
},

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@stream44.studio/t44",
3-
"version": "0.4.0-rc.26",
3+
"version": "0.4.0-rc.27",
44
"license": "LGPL",
55
"repository": {
66
"type": "git",

0 commit comments

Comments
 (0)