import { describe, expect, it } from 'vitest'; import { firstDivergence } from '../src/roundtrip.js'; describe('firstDivergence', () => { it('returns null for equal nested objects', () => { const a = { k1: { k2: 1, k3: [1, 2, 3] }, n: 'x' }; const b = { k1: { k2: 1, k3: [1, 2, 3] }, n: 'x' }; expect(firstDivergence(a, b)).toBeNull(); }); it('reports the correct path for a differing leaf', () => { const a = { k1: { k2: 1 } }; const b = { k1: { k2: 2 } }; const d = firstDivergence(a, b); expect(d).not.toBeNull(); expect(d!.path).toBe('$.k1.k2'); expect(d!.a).toBe(1); expect(d!.b).toBe(2); }); it('reports an array length mismatch at $.arr.length', () => { const a = { arr: [1, 2, 3] }; const b = { arr: [1, 2] }; const d = firstDivergence(a, b); expect(d).not.toBeNull(); expect(d!.path).toBe('$.arr.length'); expect(d!.a).toBe(3); expect(d!.b).toBe(2); }); it('reports a key present only in a', () => { const a = { only: 'here', shared: 1 }; const b = { shared: 1 }; const d = firstDivergence(a, b); expect(d).not.toBeNull(); expect(d!.path).toBe('$.only'); expect(d!.a).toBe('here'); expect(d!.b).toBeUndefined(); }); // --- branches NOT covered above (report ยง2) --- it('reports a type mismatch (string vs number) at the current path', () => { const d = firstDivergence({ k: '1' }, { k: 1 }); expect(d).toEqual({ path: '$.k', a: '1', b: 1 }); }); it('reports null-vs-object as a divergence (typeof object both, but one is null)', () => { // typeof null === 'object', so this exercises the explicit `a===null` guard. const d = firstDivergence({ k: null }, { k: { nested: true } }); expect(d).toEqual({ path: '$.k', a: null, b: { nested: true } }); }); it('reports array-vs-object as a divergence (aIsArr !== bIsArr)', () => { const d = firstDivergence({ k: [1, 2] }, { k: { 0: 1, 1: 2 } }); expect(d).not.toBeNull(); expect(d!.path).toBe('$.k'); expect(Array.isArray(d!.a)).toBe(true); expect(Array.isArray(d!.b)).toBe(false); }); it('returns null for two equal primitives (the a === b fast path)', () => { expect(firstDivergence(7, 7)).toBeNull(); expect(firstDivergence('same', 'same')).toBeNull(); expect(firstDivergence(null, null)).toBeNull(); expect(firstDivergence(true, true)).toBeNull(); }); it('reports a key present only in b (a-side undefined)', () => { // The key union scans both objects, so a key only in `b` is detected with // the a-side value undefined. const d = firstDivergence({ shared: 1 }, { shared: 1, extra: 'b-only' }); expect(d).not.toBeNull(); expect(d!.path).toBe('$.extra'); expect(d!.a).toBeUndefined(); expect(d!.b).toBe('b-only'); }); });