import hasChanged from './hasChanged'; describe('hasChanged', () => { test('returns false when newVal is undefined', () => { expect(hasChanged(undefined, 'old-value')).toBe(false); }); test('returns false when values are the same', () => { expect(hasChanged('same-value', 'same-value')).toBe(false); expect(hasChanged(123, 123)).toBe(false); expect(hasChanged(true, true)).toBe(false); }); test('returns true when primitive values differ', () => { expect(hasChanged('new-value', 'old-value')).toBe(true); expect(hasChanged(456, 123)).toBe(true); expect(hasChanged(true, false)).toBe(true); }); test('returns true when array values differ', () => { expect(hasChanged([1, 2, 3], [1, 2])).toBe(true); expect(hasChanged(['a', 'b'], ['a'])).toBe(true); }); test('returns false when arrays are the same', () => { expect(hasChanged([1, 2, 3], [1, 2, 3])).toBe(false); expect(hasChanged(['a', 'b'], ['a', 'b'])).toBe(false); }); test('returns true when comparing array to null/undefined oldVal', () => { expect(hasChanged([1, 2], null)).toBe(true); expect(hasChanged([1, 2], undefined)).toBe(true); }); test('returns false when both are empty arrays', () => { expect(hasChanged([], [])).toBe(false); }); test('returns true when object values differ', () => { expect(hasChanged({ a: 1 }, { a: 2 })).toBe(true); expect(hasChanged({ a: 1, b: 2 }, { a: 1 })).toBe(true); }); test('returns false when objects are the same', () => { expect(hasChanged({ a: 1, b: 2 }, { a: 1, b: 2 })).toBe(false); }); test('returns true when comparing object to null/undefined oldVal', () => { expect(hasChanged({ a: 1 }, null)).toBe(true); expect(hasChanged({ a: 1 }, undefined)).toBe(true); }); test('returns false when both are empty objects', () => { expect(hasChanged({}, {})).toBe(false); }); test('handles complex nested objects', () => { expect( hasChanged( { tier: ['1'], status: 'active' }, { tier: ['1'], status: 'active' }, ), ).toBe(false); expect( hasChanged( { tier: ['2'], status: 'active' }, { tier: ['1'], status: 'active' }, ), ).toBe(true); }); test('handles null values', () => { expect(hasChanged(null, 'old-value')).toBe(true); expect(hasChanged(null, null)).toBe(false); }); test('handles objects with different property order as equal', () => { expect(hasChanged({ a: 1, b: 2, c: 3 }, { c: 3, b: 2, a: 1 })).toBe(false); expect( hasChanged( { name: 'test', id: 123, active: true }, { active: true, name: 'test', id: 123 }, ), ).toBe(false); }); test('handles arrays with same elements in different order as different', () => { // Arrays should be order-sensitive expect(hasChanged([1, 2, 3], [3, 2, 1])).toBe(true); expect(hasChanged(['a', 'b'], ['b', 'a'])).toBe(true); }); test('handles clearing values - empty array from populated', () => { // Clearing an array (from something to empty) should be a change expect(hasChanged([], [1, 2, 3])).toBe(true); expect(hasChanged([], ['a'])).toBe(true); }); test('handles clearing values - empty string from populated', () => { // Clearing a string (from something to empty) should be a change expect(hasChanged('', 'old-value')).toBe(true); expect(hasChanged('', null)).toBe(true); expect(hasChanged('', '')).toBe(false); }); test('handles clearing values - null from populated', () => { // Setting to null (from something to null) should be a change expect(hasChanged(null, 'old-value')).toBe(true); expect(hasChanged(null, [1, 2])).toBe(true); expect(hasChanged(null, { a: 1 })).toBe(true); expect(hasChanged(null, undefined)).toBe(true); }); test('handles clearing values - empty object from populated', () => { // Clearing an object (from something to empty) should be a change expect(hasChanged({}, { a: 1, b: 2 })).toBe(true); expect(hasChanged({}, { key: 'value' })).toBe(true); }); test('handles undefined vs null distinction', () => { // undefined = field not provided (no change requested) expect(hasChanged(undefined, 'old-value')).toBe(false); expect(hasChanged(undefined, null)).toBe(false); expect(hasChanged(undefined, undefined)).toBe(false); // null = explicit value (change requested if different from old value) expect(hasChanged(null, 'old-value')).toBe(true); expect(hasChanged(null, undefined)).toBe(true); expect(hasChanged(null, null)).toBe(false); }); test('handles edge cases with falsy values', () => { // 0, false, '' are valid values that should be treated as changes when different expect(hasChanged(0, 1)).toBe(true); expect(hasChanged(0, null)).toBe(true); expect(hasChanged(0, 0)).toBe(false); expect(hasChanged(false, true)).toBe(true); expect(hasChanged(false, null)).toBe(true); expect(hasChanged(false, false)).toBe(false); }); });