react-use/tests/useEvent.test.ts
xobotyi b6993a6f95
feat(prettier): make prettier a part of eslint.
Also reduce max line width to 100. And remove `lint:types` step for
commit sequence, it bothers when committing incomplete (wip) changes.
2021-02-01 18:58:55 +03:00

185 lines
4.7 KiB
TypeScript

import { renderHook } from '@testing-library/react-hooks';
import useEvent, { ListenerType1, ListenerType2 } from '../src/useEvent';
interface Props {
name: string;
handler: (...args: any[]) => void;
target: ListenerType1 | ListenerType2;
options: any;
}
const propsList1 = [
{
name: 'name1',
handler: () => {},
target: {
addEventListener: jest.fn(),
removeEventListener: jest.fn(),
},
options: { a: 'opt1' },
},
{
name: 'name2',
handler: () => {},
target: {
addEventListener: jest.fn(),
removeEventListener: jest.fn(),
},
options: { a: 'opt2' },
},
];
const propsList2 = [
{
...propsList1[0],
target: {
on: jest.fn(),
off: jest.fn(),
},
},
{
...propsList1[1],
target: {
on: jest.fn(),
off: jest.fn(),
},
},
];
it('should call addEventListener/removeEventListener on mount/unmount', () => {
checkOnMountAndUnmount(propsList1[0], 'addEventListener', 'removeEventListener');
});
it('should call on/off on mount/unmount', () => {
checkOnMountAndUnmount(propsList2[0], 'on', 'off');
});
it('should call addEventListener/removeEventListener on deps changes', () => {
checkOnDepsChanges(propsList1[0], propsList1[1], 'addEventListener', 'removeEventListener');
});
it('should call on/off on deps changes', () => {
checkOnDepsChanges(propsList2[0], propsList2[1], 'on', 'off');
});
const checkOnMountAndUnmount = (
props: Props,
addEventListenerName: string,
removeEventListenerName: string
) => {
const { unmount } = renderHook((p: Props) => useEvent(p.name, p.handler, p.target, p.options), {
initialProps: props,
});
expect(props.target[addEventListenerName]).toHaveBeenCalledTimes(1);
expect(props.target[addEventListenerName]).toHaveBeenLastCalledWith(
props.name,
props.handler,
props.options
);
unmount();
expect(props.target[removeEventListenerName]).toHaveBeenCalledTimes(1);
expect(props.target[removeEventListenerName]).toHaveBeenLastCalledWith(
props.name,
props.handler,
props.options
);
};
const checkOnDepsChanges = (
props1: Props,
props2: Props,
addEventListenerName: string,
removeEventListenerName: string
) => {
const { rerender } = renderHook((p: Props) => useEvent(p.name, p.handler, p.target, p.options), {
initialProps: props1,
});
expect(props1.target[addEventListenerName]).toHaveBeenCalledTimes(1);
expect(props1.target[addEventListenerName]).toHaveBeenLastCalledWith(
props1.name,
props1.handler,
props1.options
);
// deps are same as previous
rerender({
name: props1.name,
handler: props1.handler,
target: props1.target,
options: props1.options,
});
expect(props1.target[removeEventListenerName]).not.toHaveBeenCalled();
// name is different from previous
rerender({
name: props2.name,
handler: props1.handler,
target: props1.target,
options: props1.options,
});
expect(props1.target[removeEventListenerName]).toHaveBeenCalledTimes(1);
expect(props1.target[removeEventListenerName]).toHaveBeenLastCalledWith(
props1.name,
props1.handler,
props1.options
);
// handler is different from previous
rerender({
name: props2.name,
handler: props2.handler,
target: props1.target,
options: props1.options,
});
expect(props1.target[removeEventListenerName]).toHaveBeenCalledTimes(2);
expect(props1.target[removeEventListenerName]).toHaveBeenLastCalledWith(
props2.name,
props1.handler,
props1.options
);
// options contents is same as previous
rerender({
name: props2.name,
handler: props2.handler,
target: props1.target,
options: { a: 'opt1' },
});
expect(props1.target[removeEventListenerName]).toHaveBeenCalledTimes(2);
// options is different from previous
rerender({
name: props2.name,
handler: props2.handler,
target: props1.target,
options: props2.options,
});
expect(props1.target[removeEventListenerName]).toHaveBeenCalledTimes(3);
expect(props1.target[removeEventListenerName]).toHaveBeenLastCalledWith(
props2.name,
props2.handler,
props1.options
);
// target is different from previous
rerender({
name: props2.name,
handler: props2.handler,
target: props2.target,
options: props2.options,
});
expect(props1.target[removeEventListenerName]).toHaveBeenCalledTimes(4);
expect(props1.target[removeEventListenerName]).toHaveBeenLastCalledWith(
props2.name,
props2.handler,
props2.options
);
expect(props2.target[addEventListenerName]).toHaveBeenCalledTimes(1);
expect(props2.target[addEventListenerName]).toHaveBeenLastCalledWith(
props2.name,
props2.handler,
props2.options
);
};