Uh oh!
There was an error while loading. Please reload this page.
test(svelte-query/createQueries): add test for not fetching queries with different durations when 'isRestoring' is true - #10387
Conversation
…ith different durations when 'isRestoring' is true
📝 WalkthroughWalkthroughA Vitest test case was added to the Changes
Estimated code review effort🎯 1 (Trivial) | ⏱️ ~5 minutes Possibly related PRs
Suggested labels
Poem
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
View your CI Pipeline Execution ↗ for commit 45b46a7
☁️ Nx Cloud last updated this comment at |
🚀 Changeset Version PreviewNo changeset entries found. Merging this PR will not cause a version bump for any packages. |
size-limit report 📦
|
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@packages/svelte-query/tests/createQueries/createQueries.svelte.test.ts`:
- Around line 974-1017: The test enables fake timers with vi.useFakeTimers() but
restores them unconditionally at the end, risking leakage if an assertion
throws; wrap the test body that uses vi.useFakeTimers(), the calls to
vi.advanceTimersByTimeAsync(...) and all assertions in a try block and call
vi.useRealTimers() in a finally block so timers are always restored; locate the
code around vi.useFakeTimers(), the advanceTimers calls and the final
vi.useRealTimers() to implement the try/finally.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 6c73de61-7455-43ea-9d7c-38581703f51b
📒 Files selected for processing (1)
packages/svelte-query/tests/createQueries/createQueries.svelte.test.ts
| vi.useFakeTimers() | ||
| const queryFn1 = vi.fn(() => sleep(10).then(() => 'data1')) | ||
| const queryFn2 = vi.fn(() => sleep(20).then(() => 'data2')) | ||
| const rendered = render(IsRestoringExample, { | ||
| props: { queryFn1, queryFn2 }, | ||
| }) | ||
| await vi.advanceTimersByTimeAsync(0) | ||
| expect(rendered.getByTestId('status1')).toHaveTextContent('pending') | ||
| expect(rendered.getByTestId('status2')).toHaveTextContent('pending') | ||
| expect(rendered.getByTestId('fetchStatus1')).toHaveTextContent('idle') | ||
| expect(rendered.getByTestId('fetchStatus2')).toHaveTextContent('idle') | ||
| expect(rendered.getByTestId('data1')).toHaveTextContent('undefined') | ||
| expect(rendered.getByTestId('data2')).toHaveTextContent('undefined') | ||
| expect(queryFn1).toHaveBeenCalledTimes(0) | ||
| expect(queryFn2).toHaveBeenCalledTimes(0) | ||
| await vi.advanceTimersByTimeAsync(11) | ||
| expect(rendered.getByTestId('status1')).toHaveTextContent('pending') | ||
| expect(rendered.getByTestId('status2')).toHaveTextContent('pending') | ||
| expect(rendered.getByTestId('fetchStatus1')).toHaveTextContent('idle') | ||
| expect(rendered.getByTestId('fetchStatus2')).toHaveTextContent('idle') | ||
| expect(rendered.getByTestId('data1')).toHaveTextContent('undefined') | ||
| expect(rendered.getByTestId('data2')).toHaveTextContent('undefined') | ||
| expect(queryFn1).toHaveBeenCalledTimes(0) | ||
| expect(queryFn2).toHaveBeenCalledTimes(0) | ||
| await vi.advanceTimersByTimeAsync(10) | ||
| expect(rendered.getByTestId('status1')).toHaveTextContent('pending') | ||
| expect(rendered.getByTestId('status2')).toHaveTextContent('pending') | ||
| expect(rendered.getByTestId('fetchStatus1')).toHaveTextContent('idle') | ||
| expect(rendered.getByTestId('fetchStatus2')).toHaveTextContent('idle') | ||
| expect(rendered.getByTestId('data1')).toHaveTextContent('undefined') | ||
| expect(rendered.getByTestId('data2')).toHaveTextContent('undefined') | ||
| expect(queryFn1).toHaveBeenCalledTimes(0) | ||
| expect(queryFn2).toHaveBeenCalledTimes(0) | ||
| vi.useRealTimers() | ||
| }) |
There was a problem hiding this comment.
Protect fake-timer cleanup with try/finally to avoid cross-test leakage.
If any assertion fails before Line 1016, fake timers stay enabled and may cascade failures into later tests. Wrap the body in try/finally and restore timers in finally.
Suggested fix
it('should not fetch queries with different durations for the duration of the restoring period when isRestoring is true', async () => {
- vi.useFakeTimers()-- const queryFn1 = vi.fn(() => sleep(10).then(() => 'data1'))- const queryFn2 = vi.fn(() => sleep(20).then(() => 'data2'))-- const rendered = render(IsRestoringExample, {- props: { queryFn1, queryFn2 },- })-- await vi.advanceTimersByTimeAsync(0)-- expect(rendered.getByTestId('status1')).toHaveTextContent('pending')- expect(rendered.getByTestId('status2')).toHaveTextContent('pending')- expect(rendered.getByTestId('fetchStatus1')).toHaveTextContent('idle')- expect(rendered.getByTestId('fetchStatus2')).toHaveTextContent('idle')- expect(rendered.getByTestId('data1')).toHaveTextContent('undefined')- expect(rendered.getByTestId('data2')).toHaveTextContent('undefined')- expect(queryFn1).toHaveBeenCalledTimes(0)- expect(queryFn2).toHaveBeenCalledTimes(0)-- await vi.advanceTimersByTimeAsync(11)-- expect(rendered.getByTestId('status1')).toHaveTextContent('pending')- expect(rendered.getByTestId('status2')).toHaveTextContent('pending')- expect(rendered.getByTestId('fetchStatus1')).toHaveTextContent('idle')- expect(rendered.getByTestId('fetchStatus2')).toHaveTextContent('idle')- expect(rendered.getByTestId('data1')).toHaveTextContent('undefined')- expect(rendered.getByTestId('data2')).toHaveTextContent('undefined')- expect(queryFn1).toHaveBeenCalledTimes(0)- expect(queryFn2).toHaveBeenCalledTimes(0)-- await vi.advanceTimersByTimeAsync(10)-- expect(rendered.getByTestId('status1')).toHaveTextContent('pending')- expect(rendered.getByTestId('status2')).toHaveTextContent('pending')- expect(rendered.getByTestId('fetchStatus1')).toHaveTextContent('idle')- expect(rendered.getByTestId('fetchStatus2')).toHaveTextContent('idle')- expect(rendered.getByTestId('data1')).toHaveTextContent('undefined')- expect(rendered.getByTestId('data2')).toHaveTextContent('undefined')- expect(queryFn1).toHaveBeenCalledTimes(0)- expect(queryFn2).toHaveBeenCalledTimes(0)-- vi.useRealTimers()+ vi.useFakeTimers()+ try {+ const queryFn1 = vi.fn(() => sleep(10).then(() => 'data1'))+ const queryFn2 = vi.fn(() => sleep(20).then(() => 'data2'))++ const rendered = render(IsRestoringExample, {+ props: { queryFn1, queryFn2 },+ })++ await vi.advanceTimersByTimeAsync(0)++ expect(rendered.getByTestId('status1')).toHaveTextContent('pending')+ expect(rendered.getByTestId('status2')).toHaveTextContent('pending')+ expect(rendered.getByTestId('fetchStatus1')).toHaveTextContent('idle')+ expect(rendered.getByTestId('fetchStatus2')).toHaveTextContent('idle')+ expect(rendered.getByTestId('data1')).toHaveTextContent('undefined')+ expect(rendered.getByTestId('data2')).toHaveTextContent('undefined')+ expect(queryFn1).toHaveBeenCalledTimes(0)+ expect(queryFn2).toHaveBeenCalledTimes(0)++ await vi.advanceTimersByTimeAsync(11)++ expect(rendered.getByTestId('status1')).toHaveTextContent('pending')+ expect(rendered.getByTestId('status2')).toHaveTextContent('pending')+ expect(rendered.getByTestId('fetchStatus1')).toHaveTextContent('idle')+ expect(rendered.getByTestId('fetchStatus2')).toHaveTextContent('idle')+ expect(rendered.getByTestId('data1')).toHaveTextContent('undefined')+ expect(rendered.getByTestId('data2')).toHaveTextContent('undefined')+ expect(queryFn1).toHaveBeenCalledTimes(0)+ expect(queryFn2).toHaveBeenCalledTimes(0)++ await vi.advanceTimersByTimeAsync(10)++ expect(rendered.getByTestId('status1')).toHaveTextContent('pending')+ expect(rendered.getByTestId('status2')).toHaveTextContent('pending')+ expect(rendered.getByTestId('fetchStatus1')).toHaveTextContent('idle')+ expect(rendered.getByTestId('fetchStatus2')).toHaveTextContent('idle')+ expect(rendered.getByTestId('data1')).toHaveTextContent('undefined')+ expect(rendered.getByTestId('data2')).toHaveTextContent('undefined')+ expect(queryFn1).toHaveBeenCalledTimes(0)+ expect(queryFn2).toHaveBeenCalledTimes(0)+ } finally {+ vi.useRealTimers()+ }
})📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| vi.useFakeTimers() | |
| constqueryFn1=vi.fn(()=>sleep(10).then(()=>'data1')) | |
| constqueryFn2=vi.fn(()=>sleep(20).then(()=>'data2')) | |
| constrendered=render(IsRestoringExample,{ | |
| props: {queryFn1,queryFn2}, | |
| }) | |
| awaitvi.advanceTimersByTimeAsync(0) | |
| expect(rendered.getByTestId('status1')).toHaveTextContent('pending') | |
| expect(rendered.getByTestId('status2')).toHaveTextContent('pending') | |
| expect(rendered.getByTestId('fetchStatus1')).toHaveTextContent('idle') | |
| expect(rendered.getByTestId('fetchStatus2')).toHaveTextContent('idle') | |
| expect(rendered.getByTestId('data1')).toHaveTextContent('undefined') | |
| expect(rendered.getByTestId('data2')).toHaveTextContent('undefined') | |
| expect(queryFn1).toHaveBeenCalledTimes(0) | |
| expect(queryFn2).toHaveBeenCalledTimes(0) | |
| awaitvi.advanceTimersByTimeAsync(11) | |
| expect(rendered.getByTestId('status1')).toHaveTextContent('pending') | |
| expect(rendered.getByTestId('status2')).toHaveTextContent('pending') | |
| expect(rendered.getByTestId('fetchStatus1')).toHaveTextContent('idle') | |
| expect(rendered.getByTestId('fetchStatus2')).toHaveTextContent('idle') | |
| expect(rendered.getByTestId('data1')).toHaveTextContent('undefined') | |
| expect(rendered.getByTestId('data2')).toHaveTextContent('undefined') | |
| expect(queryFn1).toHaveBeenCalledTimes(0) | |
| expect(queryFn2).toHaveBeenCalledTimes(0) | |
| awaitvi.advanceTimersByTimeAsync(10) | |
| expect(rendered.getByTestId('status1')).toHaveTextContent('pending') | |
| expect(rendered.getByTestId('status2')).toHaveTextContent('pending') | |
| expect(rendered.getByTestId('fetchStatus1')).toHaveTextContent('idle') | |
| expect(rendered.getByTestId('fetchStatus2')).toHaveTextContent('idle') | |
| expect(rendered.getByTestId('data1')).toHaveTextContent('undefined') | |
| expect(rendered.getByTestId('data2')).toHaveTextContent('undefined') | |
| expect(queryFn1).toHaveBeenCalledTimes(0) | |
| expect(queryFn2).toHaveBeenCalledTimes(0) | |
| vi.useRealTimers() | |
| }) | |
| vi.useFakeTimers() | |
| try{ | |
| constqueryFn1=vi.fn(()=>sleep(10).then(()=>'data1')) | |
| constqueryFn2=vi.fn(()=>sleep(20).then(()=>'data2')) | |
| constrendered=render(IsRestoringExample,{ | |
| props: {queryFn1,queryFn2}, | |
| }) | |
| awaitvi.advanceTimersByTimeAsync(0) | |
| expect(rendered.getByTestId('status1')).toHaveTextContent('pending') | |
| expect(rendered.getByTestId('status2')).toHaveTextContent('pending') | |
| expect(rendered.getByTestId('fetchStatus1')).toHaveTextContent('idle') | |
| expect(rendered.getByTestId('fetchStatus2')).toHaveTextContent('idle') | |
| expect(rendered.getByTestId('data1')).toHaveTextContent('undefined') | |
| expect(rendered.getByTestId('data2')).toHaveTextContent('undefined') | |
| expect(queryFn1).toHaveBeenCalledTimes(0) | |
| expect(queryFn2).toHaveBeenCalledTimes(0) | |
| awaitvi.advanceTimersByTimeAsync(11) | |
| expect(rendered.getByTestId('status1')).toHaveTextContent('pending') | |
| expect(rendered.getByTestId('status2')).toHaveTextContent('pending') | |
| expect(rendered.getByTestId('fetchStatus1')).toHaveTextContent('idle') | |
| expect(rendered.getByTestId('fetchStatus2')).toHaveTextContent('idle') | |
| expect(rendered.getByTestId('data1')).toHaveTextContent('undefined') | |
| expect(rendered.getByTestId('data2')).toHaveTextContent('undefined') | |
| expect(queryFn1).toHaveBeenCalledTimes(0) | |
| expect(queryFn2).toHaveBeenCalledTimes(0) | |
| awaitvi.advanceTimersByTimeAsync(10) | |
| expect(rendered.getByTestId('status1')).toHaveTextContent('pending') | |
| expect(rendered.getByTestId('status2')).toHaveTextContent('pending') | |
| expect(rendered.getByTestId('fetchStatus1')).toHaveTextContent('idle') | |
| expect(rendered.getByTestId('fetchStatus2')).toHaveTextContent('idle') | |
| expect(rendered.getByTestId('data1')).toHaveTextContent('undefined') | |
| expect(rendered.getByTestId('data2')).toHaveTextContent('undefined') | |
| expect(queryFn1).toHaveBeenCalledTimes(0) | |
| expect(queryFn2).toHaveBeenCalledTimes(0) | |
| }finally{ | |
| vi.useRealTimers() | |
| } |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@packages/svelte-query/tests/createQueries/createQueries.svelte.test.ts`
around lines 974 - 1017, The test enables fake timers with vi.useFakeTimers()
but restores them unconditionally at the end, risking leakage if an assertion
throws; wrap the test body that uses vi.useFakeTimers(), the calls to
vi.advanceTimersByTimeAsync(...) and all assertions in a try block and call
vi.useRealTimers() in a finally block so timers are always restored; locate the
code around vi.useFakeTimers(), the advanceTimers calls and the final
vi.useRealTimers() to implement the try/finally.
Uh oh!
There was an error while loading. Please reload this page.
🎯 Changes
createQueriesdoes not fetch queries with different durations (sleep(10)andsleep(20)) during the restoring period whenisRestoringis truereact-querytest pattern foruseQuerieswithIsRestoringProvider✅ Checklist
pnpm run test:pr.🚀 Release Impact
Summary by CodeRabbit