@wix/design-system
Version:
@wix/design-system
93 lines • 4.16 kB
JavaScript
import React, { useState } from 'react';
import { render, renderHook } from '@testing-library/react';
import { uniTestkitFactoryCreator } from '@wix/wix-ui-test-utils/testing-library';
import { act } from '../../utils/test-utils/react';
import useDebouncedCallback from './useDebouncedCallback';
import Box from '../../Box';
import Text from '../../Text';
import Button from '../../Button';
import { buttonDriverFactory } from '../../Button/Button.uni.driver';
import { textUniDriverFactory } from '../../Text/Text.uni.driver';
import { debounce } from '../../utils/test-utils/unit';
const dataHooks = {
count: 'test-component-count',
button: 'test-component-button',
};
const ButtonTestkit = uniTestkitFactoryCreator(buttonDriverFactory);
const TextTestkit = uniTestkitFactoryCreator(textUniDriverFactory);
const TestComponent = ({ onClick, debounceMs }) => {
const [counter, setCounter] = useState(0);
const debouncedIncreaseCounter = useDebouncedCallback(() => {
const newCount = counter + 1;
setCounter(newCount);
if (onClick) {
onClick(newCount);
}
}, [onClick, counter, setCounter], debounceMs,
// default lodash debounce doesn't work with jest fake timers
debounce);
return (React.createElement(Box, null,
React.createElement(Text, { dataHook: dataHooks.count }, counter),
React.createElement(Button, { dataHook: dataHooks.button, onClick: debouncedIncreaseCounter }, "Increase")));
};
vi.useFakeTimers();
describe('useDebouncedCallback', () => {
it('debounces calls to provided callback', async () => {
const debounceDelay = 200;
const onClick = vi.fn();
const { container } = render(React.createElement(TestComponent, { debounceMs: debounceDelay, onClick: onClick }));
const buttonTestkit = ButtonTestkit({
wrapper: container,
dataHook: dataHooks.button,
});
const textTestkit = TextTestkit({
wrapper: container,
dataHook: dataHooks.count,
});
expect(await textTestkit.getText()).toBe('0');
await buttonTestkit.click();
await buttonTestkit.click();
act(() => vi.advanceTimersByTime(debounceDelay));
expect(onClick).toHaveBeenCalledTimes(1);
expect(onClick).toHaveBeenNthCalledWith(1, 1);
expect(await textTestkit.getText()).toBe('1');
});
it('updates function when dependencies change', async () => {
const debounceDelay = 200;
const onClick = vi.fn();
const { container } = render(React.createElement(TestComponent, { debounceMs: debounceDelay, onClick: onClick }));
const buttonTestkit = ButtonTestkit({
wrapper: container,
dataHook: dataHooks.button,
});
const textTestkit = TextTestkit({
wrapper: container,
dataHook: dataHooks.count,
});
await buttonTestkit.click();
await buttonTestkit.click();
act(() => vi.advanceTimersByTime(debounceDelay));
await buttonTestkit.click();
await buttonTestkit.click();
act(() => vi.advanceTimersByTime(debounceDelay));
expect(onClick).toHaveBeenCalledTimes(2);
expect(onClick).toHaveBeenNthCalledWith(1, 1);
expect(onClick).toHaveBeenNthCalledWith(2, 2);
expect(await textTestkit.getText()).toBe('2');
});
it('creates new callback when debounce delay changes', async () => {
const fn = vi.fn();
const { result, rerender } = renderHook(({ debounceMs = 200 } = {}) => useDebouncedCallback(fn, [], debounceMs, debounce));
const debouncedCallback = result.current;
rerender({ debounceMs: 500 });
// Callback was changed when debounce delay changed
expect(result.current).not.toBe(debouncedCallback);
await act(async () => result.current());
vi.advanceTimersByTime(200);
// debounce duration is now longer
expect(fn).not.toHaveBeenCalled();
vi.advanceTimersByTime(300);
expect(fn).toHaveBeenCalled();
});
});
//# sourceMappingURL=useDebouncedCallback.spec.js.map