import { coerceStored } from './useLocalStorageState'; describe('coerceStored', () => { const initial = { name: '', count: 0, flag: false, tags: [] as string[], nested: { a: '' } }; it('подставляет дефолт для полей, добавленных после сохранения', () => { expect(coerceStored(initial, { name: 'x' })).toEqual({ ...initial, name: 'x' }); }); it('отбрасывает ключи, которых в форме больше нет', () => { expect(coerceStored(initial, { name: 'x', removed: 1 })).not.toHaveProperty('removed'); }); it('заменяет значение другого типа дефолтом', () => { expect(coerceStored(initial, { name: 5, tags: { a: 1 }, flag: 'yes', nested: 'oops' })) .toEqual(initial); }); it('принимает массив нужного типа и мёржит вложенный объект', () => { expect(coerceStored(initial, { tags: ['a'], nested: {} })) .toEqual({ ...initial, tags: ['a'] }); }); it('не падает на null и примитиве вместо объекта', () => { expect(coerceStored(initial, null)).toEqual(initial); expect(coerceStored(initial, 'x')).toEqual(initial); }); it('для примитивного initial проверяет тип', () => { expect(coerceStored('', 5)).toBe(''); expect(coerceStored('', 'abc')).toBe('abc'); expect(coerceStored([], [1, 2])).toEqual([1, 2]); }); it('для boolean-флага отбрасывает значение другого типа', () => { expect(coerceStored(false, true)).toBe(true); expect(coerceStored(false, 'true')).toBe(false); }); it('при initial === undefined принимает сохранённое как есть', () => { expect(coerceStored(undefined, 'a')).toBe('a'); expect(coerceStored({ x: undefined as string | undefined }, { x: 'a' })).toEqual({ x: 'a' }); }); });