Skip to content

Commit

Permalink
feat(createSelector): Expose projector function on selectors to impro…
Browse files Browse the repository at this point in the history
…ve testability

Closes #290
  • Loading branch information
03byron authored and MikeRyanDev committed Aug 20, 2017
1 parent d20ebf1 commit 56cb21f
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 4 deletions.
11 changes: 11 additions & 0 deletions modules/store/spec/selector.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,17 @@ describe('Selectors', () => {
expect(projectFn).toHaveBeenCalledWith(countOne, countTwo);
});

it('should be possible to test a projector fn independent from the selectors it is composed of', () => {
const projectFn = jasmine.createSpy('projectionFn');
const selector = createSelector(incrementOne, incrementTwo, projectFn);

selector.projector('', '');

expect(incrementOne).not.toHaveBeenCalled();
expect(incrementTwo).not.toHaveBeenCalled();
expect(projectFn).toHaveBeenCalledWith('', '');
});

it('should call the projector function only when the value of a dependent selector change', () => {
const firstState = { first: 'state', unchanged: 'state' };
const secondState = { second: 'state', unchanged: 'state' };
Expand Down
12 changes: 8 additions & 4 deletions modules/store/src/selector.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import { Selector } from './models';

export type AnyFn = (...args: any[]) => any;

export interface MemoizedSelector<State, Result>
extends Selector<State, Result> {
release(): void;
projector: AnyFn;
}

export type AnyFn = (...args: any[]) => any;

export function memoize(t: AnyFn): { memoized: AnyFn; reset: () => void } {
let lastArguments: null | IArguments = null;
let lastResult: any = null;
Expand Down Expand Up @@ -132,7 +133,10 @@ export function createSelector(...args: any[]): Selector<any, any> {
memoizedSelectors.forEach(selector => selector.release());
}

return Object.assign(memoizedState.memoized, { release });
return Object.assign(memoizedState.memoized, {
release,
projector: memoizedProjector.memoized,
});
}

export function createFeatureSelector<T>(
Expand All @@ -142,5 +146,5 @@ export function createFeatureSelector<T>(
return state[featureName];
});

return Object.assign(memoized, { release: reset });
return Object.assign(memoized, { release: reset, projector: memoized });
}

0 comments on commit 56cb21f

Please sign in to comment.