import { Endpoint } from '@data-client/endpoint';
import { act } from '@data-client/test';
import { render, waitFor } from '@testing-library/react';
import React from 'react';
import AsyncBoundary from '../../components/AsyncBoundary';
import DataProvider from '../../components/DataProvider';
import { useSuspense } from '../../hooks';
import useDebounce from '../useDebounce';
describe('useDebounce()', () => {
beforeAll(() => {
jest.useFakeTimers();
});
afterAll(() => {
jest.useRealTimers();
});
it('should be pending while async operation is performed based on debounced value', async () => {
const issueQuery = new Endpoint(
({ q }: { q: string }) => Promise.resolve({ q, text: 'hi' }),
{ name: 'issueQuery' },
);
function IssueList({ q }: { q: string }) {
const response = useSuspense(issueQuery, { q });
return
{response.q}
;
}
function Search({ query }: { query: string }) {
const [debouncedQuery, isPending] = useDebounce(query, 100);
return (
{isPending ?
loading
: null}
searching... }>
);
}
const tree = (
);
const { queryByText, rerender, getByText } = render(tree);
expect(queryByText(/loading/i)).toBeNull();
expect(getByText(/searching/i)).not.toBeNull();
await waitFor(() => expect(queryByText(/searching/i)).toBeNull());
expect(getByText(/initial/i)).not.toBeNull();
rerender(
,
);
rerender(
,
);
act(() => {
jest.advanceTimersByTime(100);
});
// only check in react 18
if ('useTransition' in React) {
// isPending
expect(getByText(/loading/i)).not.toBeNull();
}
// keep showing previous values
expect(getByText(/initial/i)).not.toBeNull();
// only check in react 18
if ('useTransition' in React) {
expect(queryByText(/searching/i)).toBeNull();
}
await waitFor(() => expect(queryByText(/loading/i)).toBeNull());
expect(getByText(/third/i)).not.toBeNull();
});
});