Skip to content

Commit

Permalink
Add tests for unsubscribe and mapState changes
Browse files Browse the repository at this point in the history
  • Loading branch information
ianobermiller committed Dec 7, 2018
1 parent f8922db commit 0120236
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 2 deletions.
40 changes: 38 additions & 2 deletions src/__tests__/index-test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,12 @@ interface IState {
foo: string;
}

// https://github.com/kentcdodds/react-testing-library/issues/215
// useEffect is not triggered on re-renders
beforeAll(() =>
jest.spyOn(React, 'useEffect').mockImplementation(React.useLayoutEffect));
afterAll(() => (React.useEffect as any).mockRestore());

describe('redux-react-hook', () => {
let subscriberCallback: () => void;
let state: IState;
Expand All @@ -24,10 +30,10 @@ describe('redux-react-hook', () => {
const createStore = (): Store<IState, IAction> => ({
dispatch: (action: any) => action,
getState: () => state,
subscribe: (l: () => void) => {
subscribe: jest.fn((l: () => void) => {
subscriberCallback = l;
return cancelSubscription;
},
}),
// tslint:disable-next-line:no-empty
replaceReducer() {},
});
Expand Down Expand Up @@ -83,6 +89,20 @@ describe('redux-react-hook', () => {
expect(getText()).toBe('foo');
});

it('cancels subscription on unmount', () => {
const mapState = (s: IState) => s.foo;
const Component = () => {
const foo = useMappedState(mapState);
return <div>{foo}</div>;
};

render(<Component />);

ReactDOM.unmountComponentAtNode(reactRoot);

expect(cancelSubscription).toHaveBeenCalled();
});

it('does not rerender if the selected state has not changed', () => {
const mapState = (s: IState) => s.foo;
let renderCount = 0;
Expand Down Expand Up @@ -138,4 +158,20 @@ describe('redux-react-hook', () => {
render(<Component />);
expect(getText()).toBe('hello');
});

it('calls the correct mapState if mapState changes and the store updates', () => {
const Component = ({n}: {n: number}) => {
const mapState = React.useCallback((s: IState) => s.foo + ' ' + n, [n]);
const foo = useMappedState(mapState);
return <div>{foo}</div>;
};

render(<Component n={100} />);
render(<Component n={45} />);

state = {...state, foo: 'foo'};
subscriberCallback();

expect(getText()).toBe('foo 45');
});
});
4 changes: 4 additions & 0 deletions src/typings.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ declare module 'react' {
didUpdate: () => (() => void) | void,
dependencies?: Array<any>,
): void;
export function useLayoutEffect(
didUpdate: () => (() => void) | void,
dependencies?: Array<any>,
): void;
export function useRef<T>(initialValue?: T): {current: T};
export function useState<T>(
initialState: T | (() => T),
Expand Down

0 comments on commit 0120236

Please sign in to comment.