Skip to content

Commit 7e99c3d

Browse files
committed
test(commons): add coverage for circular array/object ancestor checks in deepMerge
1 parent e9d7457 commit 7e99c3d

1 file changed

Lines changed: 32 additions & 0 deletions

File tree

packages/commons/tests/unit/deepMerge.test.ts

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -303,6 +303,38 @@ describe('Function: deepMerge', () => {
303303
expect((result.arr as unknown[])[1]).toBe(2);
304304
});
305305

306+
it('skips array that references an ancestor array', () => {
307+
// Prepare - an array contains an object whose property points back to the array
308+
const arr: unknown[] = [];
309+
const inner: Record<string, unknown> = { backRef: arr };
310+
arr.push(inner);
311+
const target = { arr: [{ a: 1 }] };
312+
const source = { arr };
313+
314+
// Act
315+
const result = deepMerge(target, source);
316+
317+
// Assess - inner.backRef is the same array that's in the ancestor chain,
318+
// so the circular array reference is skipped during mergeRecursive
319+
expect(result.arr).toBeDefined();
320+
expect((result.arr as Record<string, unknown>[])[0]).not.toHaveProperty(
321+
'backRef'
322+
);
323+
});
324+
325+
it('skips circular plain objects inside arrays', () => {
326+
// Prepare
327+
const target = { arr: [{ a: 1 }] };
328+
const source: Record<string, unknown> = { b: 2 };
329+
source.arr = [source];
330+
331+
// Act
332+
const result = deepMerge(target, source);
333+
334+
// Assess - source inside its own array is a circular ref and is skipped
335+
expect(result).toEqual({ arr: [{ a: 1 }], b: 2 });
336+
});
337+
306338
it('merges shared array references into all properties', () => {
307339
// Prepare
308340
const target = {};

0 commit comments

Comments
 (0)