diff --git a/packages/react-query/src/__tests__/useQueries.test.tsx b/packages/react-query/src/__tests__/useQueries.test.tsx index b885def59c..5efd067df1 100644 --- a/packages/react-query/src/__tests__/useQueries.test.tsx +++ b/packages/react-query/src/__tests__/useQueries.test.tsx @@ -1,5 +1,13 @@ -import { describe, expect, expectTypeOf, it, vi } from 'vitest' -import { fireEvent, render, waitFor } from '@testing-library/react' +import { + afterEach, + beforeEach, + describe, + expect, + expectTypeOf, + it, + vi, +} from 'vitest' +import { fireEvent, render } from '@testing-library/react' import * as React from 'react' import { ErrorBoundary } from 'react-error-boundary' import { queryKey, sleep } from '@tanstack/query-test-utils' @@ -21,6 +29,14 @@ import type { import type { QueryFunctionContext } from '@tanstack/query-core' describe('useQueries', () => { + beforeEach(() => { + vi.useFakeTimers() + }) + + afterEach(() => { + vi.useRealTimers() + }) + const queryCache = new QueryCache() const queryClient = new QueryClient({ queryCache }) @@ -62,7 +78,8 @@ describe('useQueries', () => { const rendered = renderWithClient(queryClient, ) - await waitFor(() => rendered.getByText('data1: 1, data2: 2')) + await vi.advanceTimersByTimeAsync(201) + rendered.getByText('data1: 1, data2: 2') expect(results.length).toBe(3) expect(results[0]).toMatchObject([{ data: undefined }, { data: undefined }]) @@ -100,7 +117,8 @@ describe('useQueries', () => { const rendered = renderWithClient(queryClient, ) - await waitFor(() => rendered.getByText('data: 1')) + await vi.advanceTimersByTimeAsync(11) + rendered.getByText('data: 1') expect(results.length).toBe(2) expect(results[0]).toMatchObject([{ data: undefined }]) @@ -108,7 +126,8 @@ describe('useQueries', () => { fireEvent.click(rendered.getByRole('button', { name: /refetch/i })) - await waitFor(() => rendered.getByText('data: 2')) + await vi.advanceTimersByTimeAsync(11) + rendered.getByText('data: 2') // only one render for data update, no render for isFetching transition expect(results.length).toBe(3) @@ -842,12 +861,9 @@ describe('useQueries', () => { , ) - await waitFor(() => - expect(rendered.getByText('error boundary')).toBeInTheDocument(), - ) - await waitFor(() => - expect(rendered.getByText('single query error')).toBeInTheDocument(), - ) + await vi.advanceTimersByTimeAsync(0) + expect(rendered.getByText('error boundary')).toBeInTheDocument() + expect(rendered.getByText('single query error')).toBeInTheDocument() consoleMock.mockRestore() }) @@ -913,12 +929,9 @@ describe('useQueries', () => { , ) - await waitFor(() => - expect(rendered.getByText('error boundary')).toBeInTheDocument(), - ) - await waitFor(() => - expect(rendered.getByText('single query error')).toBeInTheDocument(), - ) + await vi.advanceTimersByTimeAsync(0) + expect(rendered.getByText('error boundary')).toBeInTheDocument() + expect(rendered.getByText('single query error')).toBeInTheDocument() consoleMock.mockRestore() }) @@ -946,9 +959,8 @@ describe('useQueries', () => { const rendered = render() - await waitFor(() => - expect(rendered.getByText('data: custom client')).toBeInTheDocument(), - ) + await vi.advanceTimersByTimeAsync(0) + expect(rendered.getByText('data: custom client')).toBeInTheDocument() }) it('should combine queries', async () => { @@ -989,11 +1001,10 @@ describe('useQueries', () => { const rendered = render() - await waitFor(() => - expect( - rendered.getByText('data: true first result,second result'), - ).toBeInTheDocument(), - ) + await vi.advanceTimersByTimeAsync(0) + expect( + rendered.getByText('data: true first result,second result'), + ).toBeInTheDocument() }) it('should not return new instances when called without queries', async () => { @@ -1035,14 +1046,16 @@ describe('useQueries', () => { const rendered = renderWithClient(queryClient, ) - await waitFor(() => rendered.getByText('data: {"empty":"object"}')) - await waitFor(() => rendered.getByText('count: 0')) + await vi.advanceTimersByTimeAsync(0) + rendered.getByText('data: {"empty":"object"}') + rendered.getByText('count: 0') expect(resultChanged).toBe(1) fireEvent.click(rendered.getByRole('button', { name: /inc/i })) - await waitFor(() => rendered.getByText('count: 1')) + await vi.advanceTimersByTimeAsync(0) + rendered.getByText('count: 1') // there should be no further effect calls because the returned object is structurally shared expect(resultChanged).toBe(1) }) @@ -1064,7 +1077,7 @@ describe('useQueries', () => { renderWithClient(queryClient, ) - await sleep(10) + await vi.advanceTimersByTimeAsync(10) expect(renderCount).toBe(1) }) @@ -1102,13 +1115,13 @@ describe('useQueries', () => { } const rendered = renderWithClient(queryClient, ) - await waitFor(() => - expect( - rendered.getByText( - 'data: {"data":{"query1":"query1","query2":"query2"}}', - ), - ).toBeInTheDocument(), - ) + + await vi.advanceTimersByTimeAsync(21) + expect( + rendered.getByText( + 'data: {"data":{"query1":"query1","query2":"query2"}}', + ), + ).toBeInTheDocument() }) it('should track property access through combine function', async () => { @@ -1163,11 +1176,10 @@ describe('useQueries', () => { const rendered = render() - await waitFor(() => - expect( - rendered.getByText('data: true first result 0,second result 0'), - ).toBeInTheDocument(), - ) + await vi.advanceTimersByTimeAsync(51) + expect( + rendered.getByText('data: true first result 0,second result 0'), + ).toBeInTheDocument() expect(results.length).toBe(3) @@ -1193,9 +1205,8 @@ describe('useQueries', () => { fireEvent.click(rendered.getByRole('button', { name: /refetch/i })) - await waitFor(() => - rendered.getByText('data: true first result 1,second result 1'), - ) + await vi.advanceTimersByTimeAsync(51) + rendered.getByText('data: true first result 1,second result 1') const length = results.length @@ -1209,7 +1220,7 @@ describe('useQueries', () => { fireEvent.click(rendered.getByRole('button', { name: /refetch/i })) - await sleep(100) + await vi.advanceTimersByTimeAsync(100) // no further re-render because data didn't change expect(results.length).toBe(length) }) @@ -1259,15 +1270,10 @@ describe('useQueries', () => { const rendered = renderWithClient(queryClient, ) - await waitFor(() => - expect( - rendered.getByText('Loading Status: Loading...'), - ).toBeInTheDocument(), - ) + expect(rendered.getByText('Loading Status: Loading...')).toBeInTheDocument() - await waitFor(() => - expect(rendered.getByText('Loading Status: Loaded')).toBeInTheDocument(), - ) + await vi.advanceTimersByTimeAsync(11) + expect(rendered.getByText('Loading Status: Loaded')).toBeInTheDocument() }) it('should not have stale closures with combine (#6648)', async () => { @@ -1305,13 +1311,13 @@ describe('useQueries', () => { const rendered = render() - await waitFor(() => rendered.getByText('data: 0 result')) + await vi.advanceTimersByTimeAsync(0) + rendered.getByText('data: 0 result') fireEvent.click(rendered.getByRole('button', { name: /inc/i })) - await waitFor(() => - expect(rendered.getByText('data: 1 result')).toBeInTheDocument(), - ) + await vi.advanceTimersByTimeAsync(0) + expect(rendered.getByText('data: 1 result')).toBeInTheDocument() }) it('should optimize combine if it is a stable reference', async () => { @@ -1367,14 +1373,15 @@ describe('useQueries', () => { const rendered = render() - await waitFor(() => - rendered.getByText('data: true first result:0,second result:0'), - ) + await vi.advanceTimersByTimeAsync(21) + rendered.getByText('data: true first result:0,second result:0') // both pending, one pending, both resolved expect(spy).toHaveBeenCalledTimes(3) - await client.refetchQueries() + client.refetchQueries() + + await vi.advanceTimersByTimeAsync(21) // no increase because result hasn't changed expect(spy).toHaveBeenCalledTimes(3) @@ -1385,11 +1392,10 @@ describe('useQueries', () => { value = 1 - await client.refetchQueries() + client.refetchQueries() - await waitFor(() => - rendered.getByText('data: true first result:1,second result:1'), - ) + await vi.advanceTimersByTimeAsync(21) + rendered.getByText('data: true first result:1,second result:1') // two value changes = two re-renders expect(spy).toHaveBeenCalledTimes(5) @@ -1451,9 +1457,8 @@ describe('useQueries', () => { const rendered = render() - await waitFor(() => - rendered.getByText('data: 0 first result,second result'), - ) + await vi.advanceTimersByTimeAsync(21) + rendered.getByText('data: 0 first result,second result') // both pending, one pending, both resolved expect(spy).toHaveBeenCalledTimes(3) @@ -1510,11 +1515,10 @@ describe('useQueries', () => { const rendered = render() - await waitFor(() => rendered.getByText('data: foo')) + await vi.advanceTimersByTimeAsync(21) + rendered.getByText('data: foo') - await waitFor(() => - expect(queryFns).toEqual(['first result', 'second result']), - ) + expect(queryFns).toEqual(['first result', 'second result']) expect(renders).toBe(1) }) @@ -1574,8 +1578,10 @@ describe('useQueries', () => { const rendered = render() - await waitFor(() => rendered.getByText('data: pending')) - await waitFor(() => rendered.getByText('data: foo')) + await vi.advanceTimersByTimeAsync(0) + rendered.getByText('data: pending') + await vi.advanceTimersByTimeAsync(21) + rendered.getByText('data: foo') // one with pending, one with foo expect(renders).toBe(2) @@ -1640,23 +1646,20 @@ describe('useQueries', () => { const rendered = render() - await waitFor(() => - expect(rendered.getByText('data: pending')).toBeInTheDocument(), - ) - await waitFor(() => - expect( - rendered.getByText('data: first result, second result, third result'), - ).toBeInTheDocument(), - ) + await vi.advanceTimersByTimeAsync(0) + expect(rendered.getByText('data: pending')).toBeInTheDocument() + await vi.advanceTimersByTimeAsync(21) + expect( + rendered.getByText('data: first result, second result, third result'), + ).toBeInTheDocument() fireEvent.click(rendered.getByRole('button', { name: /update/i })) - await waitFor(() => - expect( - rendered.getByText( - 'data: first result updated, second result, third result', - ), - ).toBeInTheDocument(), - ) + await vi.advanceTimersByTimeAsync(21) + expect( + rendered.getByText( + 'data: first result updated, second result, third result', + ), + ).toBeInTheDocument() }) })