Skip to content

Commit

Permalink
Add tests! closes facebookarchive#2
Browse files Browse the repository at this point in the history
  • Loading branch information
ianobermiller committed Nov 5, 2018
1 parent 33545b5 commit aab2a98
Show file tree
Hide file tree
Showing 4 changed files with 154 additions and 11 deletions.
Empty file added .watchmanconfig
Empty file.
7 changes: 3 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,10 @@
"babel-runtime": "^6.26.0",
"cross-env": "^5.1.4",
"gh-pages": "^2.0.1",
"react": "^16.7.0-alpha.0",
"react-dom": "^16.7.0-alpha.0",
"react-scripts-ts": "^3.1.0",
"redux": "^4.0.1",
"rollup": "^0.66.6",
"rollup-plugin-babel": "^4.0.3",
"rollup-plugin-commonjs": "^9.1.3",
Expand All @@ -48,8 +50,5 @@
},
"files": [
"dist"
],
"dependencies": {
"@types/redux": "^3.6.0"
}
]
}
141 changes: 141 additions & 0 deletions src/__tests__/index-test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import {Store} from 'redux';
import {useMappedState} from '..';

interface IAction {
type: 'add todo';
}

interface IState {
bar: number;
foo: string;
}

describe('redux-react-hook', () => {
let subscriberCallback: () => void;
let state: IState;
let cancelSubscription: () => void;
let store: Store<IState, IAction>;
let context: React.Context<Store<IState>>;
let reactRoot: HTMLDivElement;

const createStore = (): Store<IState, IAction> => ({
dispatch: (action: any) => action,
getState: () => state,
subscribe: (l: () => void) => {
subscriberCallback = l;
return cancelSubscription;
},
// tslint:disable-next-line:no-empty
replaceReducer() {},
});

beforeEach(() => {
cancelSubscription = jest.fn();
state = {bar: 123, foo: 'bar'};
store = createStore();
context = React.createContext(store);

reactRoot = document.createElement('div');
document.body.appendChild(reactRoot);
});

afterEach(() => {
document.body.removeChild(reactRoot);
});

function render(element: React.ReactElement<any>) {
ReactDOM.render(
<context.Provider value={store}>{element}</context.Provider>,
reactRoot,
);
}

function getText() {
return reactRoot.textContent;
}

it('renders with state from the store', () => {
const mapState = (s: IState) => s.foo;
const Component = () => {
const foo = useMappedState(context, mapState);
return <div>{foo}</div>;
};

render(<Component />);

expect(getText()).toBe('bar');
});

it('rerenders with new state when the subscribe callback is called', () => {
const mapState = (s: IState) => s.foo;
const Component = () => {
const foo = useMappedState(context, mapState);
return <div>{foo}</div>;
};

render(<Component />);

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

expect(getText()).toBe('foo');
});

it('does not rerender if the selected state has not changed', () => {
const mapState = (s: IState) => s.foo;
let renderCount = 0;
const Component = () => {
const foo = useMappedState(context, mapState);
renderCount++;
return (
<div>
{foo} {renderCount}
</div>
);
};

render(<Component />);

expect(getText()).toBe('bar 1');

state = {bar: 456, ...state};
subscriberCallback();

expect(getText()).toBe('bar 1');
});

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

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

expect(getText()).toBe('bar 100');

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

expect(getText()).toBe('bar 45');
});

it('rerenders if the store changes', () => {
const mapState = (s: IState) => s.foo;
const Component = () => {
const foo = useMappedState(context, mapState);
return <div>{foo}</div>;
};

render(<Component />);

expect(getText()).toBe('bar');

store = createStore();
state = {...state, foo: 'hello'};
render(<Component />);
expect(getText()).toBe('hello');
});
});
17 changes: 10 additions & 7 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -64,12 +64,6 @@
"@types/prop-types" "*"
csstype "^2.2.0"

"@types/redux@^3.6.0":
version "3.6.0"
resolved "https://registry.yarnpkg.com/@types/redux/-/redux-3.6.0.tgz#f1ebe1e5411518072e4fdfca5c76e16e74c1399a"
dependencies:
redux "*"

abab@^1.0.3:
version "1.0.4"
resolved "https://registry.yarnpkg.com/abab/-/abab-1.0.4.tgz#5faad9c2c07f60dd76770f71cf025b62a63cfd4e"
Expand Down Expand Up @@ -5879,6 +5873,15 @@ react-scripts-ts@^3.1.0:
optionalDependencies:
fsevents "^1.1.3"

react@^16.7.0-alpha.0:
version "16.7.0-alpha.0"
resolved "https://registry.yarnpkg.com/react/-/react-16.7.0-alpha.0.tgz#e2ed4abe6f268c9b092a1d1e572953684d1783a9"
dependencies:
loose-envify "^1.1.0"
object-assign "^4.1.1"
prop-types "^15.6.2"
scheduler "^0.11.0-alpha.0"

read-pkg-up@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-1.0.1.tgz#9d63c13276c065918d57f002a57f40a1b643fb02"
Expand Down Expand Up @@ -5965,7 +5968,7 @@ reduce-function-call@^1.0.1:
dependencies:
balanced-match "^0.4.2"

redux@*:
redux@^4.0.1:
version "4.0.1"
resolved "https://registry.yarnpkg.com/redux/-/redux-4.0.1.tgz#436cae6cc40fbe4727689d7c8fae44808f1bfef5"
dependencies:
Expand Down

0 comments on commit aab2a98

Please sign in to comment.