From d44c8a5b5c0f03fef21f43449ced3d334de99df8 Mon Sep 17 00:00:00 2001 From: jordangarcia Date: Thu, 5 Nov 2015 08:52:04 -0800 Subject: [PATCH] Fix isCached function for empty store states The bug exists when the isCached function thinks that no storeStates means the entry is cached due to how `Array.prototype.every` works --- src/reactor/fns.js | 8 +++++- tests/reactor-tests.js | 55 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+), 1 deletion(-) diff --git a/src/reactor/fns.js b/src/reactor/fns.js index 05f0fe5..47bb513 100644 --- a/src/reactor/fns.js +++ b/src/reactor/fns.js @@ -382,7 +382,13 @@ function isCached(reactorState, keyPathOrGetter) { return false } - return entry.get('storeStates').every((stateId, storeId) => { + const storeStates = entry.get('storeStates') + if (storeStates.size === 0) { + // if there are no store states for this entry then it was never cached before + return false + } + + return storeStates.every((stateId, storeId) => { return reactorState.getIn(['storeStates', storeId]) === stateId }) } diff --git a/tests/reactor-tests.js b/tests/reactor-tests.js index 931e838..a67159c 100644 --- a/tests/reactor-tests.js +++ b/tests/reactor-tests.js @@ -396,6 +396,61 @@ describe('Reactor', () => { expect(mockFn.calls.count()).toEqual(0) }) + + it('should trigger an observer for a late registered store', () => { + var mockFn = jasmine.createSpy() + var reactor = new Reactor() + reactor.observe(['test'], mockFn) + + expect(mockFn.calls.count()).toEqual(0) + + reactor.registerStores({ + test: Store({ + getInitialState() { + return 1 + } + }) + }) + + expect(mockFn.calls.count()).toEqual(1) + expect(mockFn.calls.argsFor(0)).toEqual([1]) + }) + + it('should trigger an observer for a late registered store for the identity getter', () => { + var mockFn = jasmine.createSpy() + var reactor = new Reactor() + reactor.observe([], mockFn) + + expect(mockFn.calls.count()).toEqual(0) + + reactor.registerStores({ + test: Store({ + getInitialState() { + return 1 + }, + initialize() { + this.on('increment', (state) => state + 1) + } + }) + }) + + // it should call the observer after the store has been registered + expect(mockFn.calls.count()).toEqual(1) + var observedValue = mockFn.calls.argsFor(0)[0] + var expectedHandlerValue = Map({ + test: 1 + }) + expect(is(observedValue, expectedHandlerValue)).toBe(true) + + // it should call the observer again when the store handles an action + reactor.dispatch('increment') + expect(mockFn.calls.count()).toEqual(2) + var observedValue = mockFn.calls.argsFor(1)[0] + var expectedHandlerValue = Map({ + test: 2 + }) + expect(is(observedValue, expectedHandlerValue)).toBe(true) + }) }) describe('#unobserve', () => {