diff --git a/.eslintrc.json b/.eslintrc.json index 0900f56..1b1fd40 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -37,6 +37,7 @@ "no-unused-vars": 0, "no-underscore-dangle": 0, "no-self-compare": 0, + "no-prototype-builtins": 0, "function-paren-newline": 0, "no-new-wrappers": 0, "guard-for-in": 0, diff --git a/src/__tests__/rehydrate.test.ts b/src/__tests__/rehydrate.test.ts index be55719..54378e8 100644 --- a/src/__tests__/rehydrate.test.ts +++ b/src/__tests__/rehydrate.test.ts @@ -175,8 +175,10 @@ describe('rehydrate.ts', () => { }); describe('rehydrate()', () => { + let mockState = {}; const mockStore = { - dispatch: jest.fn() + dispatch: jest.fn(), + getState: jest.fn(() => mockState) }; let rememberedKeys: string[]; @@ -195,7 +197,10 @@ describe('rehydrate.ts', () => { beforeEach(() => { rememberedKeys = ['3', '2', '1']; + + mockState = {}; mockStore.dispatch = jest.fn(); + mockStore.getState = jest.fn(() => mockState); mockDriver = { getItem: jest.fn((key) => `"${key}"`), @@ -231,6 +236,18 @@ describe('rehydrate.ts', () => { global.console.warn = consoleWarn; }); + it('calls store.getState()', async () => { + await exec({ + driver: { + getItem: async () => ({}) + }, + unserialize: (o: any) => o, + persistWholeStore: true + }); + + expect(mockStore.getState).toBeCalledTimes(1); + }); + it('calls store.dispatch()', async () => { await exec({ unserialize: (o: any) => JSON.parse(o) @@ -265,5 +282,33 @@ describe('rehydrate.ts', () => { } }); }); + + it('merges with existing state', async () => { + mockState = { + 1: 'prev-state-1', + 2: 'prev-state-2' + }; + + await exec({ + driver: { + getItem: async () => ({ + 3: 'number-3', + 2: 'number-2', + 100: 'skip-me' + }) + }, + unserialize: (o: any) => o, + persistWholeStore: true + }); + + expect(mockStore.dispatch).nthCalledWith(1, { + type: REMEMBER_REHYDRATED, + payload: { + 3: 'number-3', + 2: 'number-2', + 1: 'prev-state-1' + } + }); + }); }); }); diff --git a/src/__tests__/utils.test.ts b/src/__tests__/utils.test.ts index c5afba3..9006164 100644 --- a/src/__tests__/utils.test.ts +++ b/src/__tests__/utils.test.ts @@ -22,6 +22,17 @@ describe('utils.ts', () => { third: 'get me too' }); }); + + it('does not copy non-existent properties', () => { + const src = { + first: 'get the first only', + skipped: 'I will be skipped :(', + }; + + expect(utils.pick(src, ['first', 'third'] as any)).toEqual({ + first: 'get the first only' + }); + }); }); describe('throttle()', () => { diff --git a/src/utils.ts b/src/utils.ts index a1ca56b..9585579 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -13,7 +13,10 @@ export const pick = , K extends keyof T>( while (++index < keys.length) { const key = keys[index]; - dest[key] = src[key]; + + if (src.hasOwnProperty(key)) { + dest[key] = src[key]; + } } return dest;