mirror of
https://github.com/streamich/react-use.git
synced 2025-12-08 18:02:14 +00:00
Also reduce max line width to 100. And remove `lint:types` step for commit sequence, it bothers when committing incomplete (wip) changes.
185 lines
4.7 KiB
TypeScript
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
|
|
);
|
|
};
|