Skip to content

Conversation

@sukvvon
Copy link
Contributor

@sukvvon sukvvon commented Nov 22, 2025

🎯 Changes

βœ… Checklist

  • I have followed the steps in the Contributing guide.
  • I have tested this code locally with pnpm run test:pr.

πŸš€ Release Impact

  • This change affects published code, and I have generated a changeset.
  • This change is docs/CI/dev-only (no release).

Summary by CodeRabbit

Summary by CodeRabbit

  • Tests
    • Refactored tests to use fake timers and explicit timer advancement for deterministic async behavior.
    • Replaced immediate resolved promises with delayed promises to better simulate hydration and fetch timing.
    • Switched some assertions to immediate checks followed by timer progression to drive state transitions.
    • Broadened scenarios to cover single/multiple queries, initial data, restoration, and error flows for improved robustness.

✏️ Tip: You can customize this high-level summary in your review settings.

@changeset-bot
Copy link

changeset-bot bot commented Nov 22, 2025

⚠️ No Changeset found

Latest commit: c9e6076

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 22, 2025

Walkthrough

Refactors the PersistQueryClientProvider test to use fake timers (vi.useFakeTimers/useRealTimers), replacing Promise.resolve-based delays and waitFor calls with sleep-based delays plus explicit advanceTimersByTimeAsync calls; adjusts mocked persister/restore behavior accordingly.

Changes

Cohort / File(s) Summary
Test suite timer refactor
packages/solid-query-persist-client/src/__tests__/PersistQueryClientProvider.test.tsx
Replaced real async timing with fake timers via beforeEach/afterEach. Converted Promise.resolve delays to sleep(...)-based promises. Updated mocks (persister.restoreClient) to return delayed promises. Replaced waitFor assertions with immediate checks plus advanceTimersByTimeAsync to drive hydration/fetch progression. Adjusted prefetchQuery/useQueries flows and error-path tests to align with timer-driven sequencing.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • Single-file but substantial behavioral/test-pattern changes.
  • Review focus:
    • Ensure sleep durations match advanceTimersByTimeAsync calls.
    • Verify mocked persister.restoreClient timing and sequencing.
    • Confirm replacements of waitFor preserve test semantics for hydration/fetch transitions.
    • Check error and initialData scenarios still assert correct states.

Possibly related PRs

Suggested reviewers

  • manudeli

Poem

🐰 I hopped through tests with a tiny spring,
Timers in paw, I taught them to sing.
Ticks now guide hydration and fetch so neat,
No flakey waits β€” just tidy, timed repeat.
✨⏰

Pre-merge checks and finishing touches

❌ Failed checks (2 warnings)
Check name Status Explanation Resolution
Description check ⚠️ Warning The PR description is incomplete. The 🎯 Changes section contains only a template comment and no actual description of the changes made, their motivation, or impact. Add a substantive description under the 🎯 Changes section explaining what was changed, why, and the impact of switching to fake timers and the new testing patterns.
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
βœ… Passed checks (1 passed)
Check name Status Explanation
Title check βœ… Passed The title accurately summarizes the main changes: switching to fake timers, replacing 'waitFor' with 'advanceTimersByTimeAsync', and adopting 'sleep().then()' pattern, matching the raw summary.
✨ Finishing touches
  • πŸ“ Generate docstrings
πŸ§ͺ Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Comment @coderabbitai help to get the list of available commands and usage tips.

@nx-cloud
Copy link

nx-cloud bot commented Nov 22, 2025

View your CI Pipeline Execution β†— for commit c9e6076

Command Status Duration Result
nx affected --targets=test:sherif,test:knip,tes... βœ… Succeeded 1m 32s View β†—
nx run-many --target=build --exclude=examples/*... βœ… Succeeded 5s View β†—

☁️ Nx Cloud last updated this comment at 2025-11-23 16:56:48 UTC

@pkg-pr-new
Copy link

pkg-pr-new bot commented Nov 22, 2025

More templates

@tanstack/angular-query-experimental

npm i https://pkg.pr.new/@tanstack/angular-query-experimental@9892

@tanstack/eslint-plugin-query

npm i https://pkg.pr.new/@tanstack/eslint-plugin-query@9892

@tanstack/query-async-storage-persister

npm i https://pkg.pr.new/@tanstack/query-async-storage-persister@9892

@tanstack/query-broadcast-client-experimental

npm i https://pkg.pr.new/@tanstack/query-broadcast-client-experimental@9892

@tanstack/query-core

npm i https://pkg.pr.new/@tanstack/query-core@9892

@tanstack/query-devtools

npm i https://pkg.pr.new/@tanstack/query-devtools@9892

@tanstack/query-persist-client-core

npm i https://pkg.pr.new/@tanstack/query-persist-client-core@9892

@tanstack/query-sync-storage-persister

npm i https://pkg.pr.new/@tanstack/query-sync-storage-persister@9892

@tanstack/react-query

npm i https://pkg.pr.new/@tanstack/react-query@9892

@tanstack/react-query-devtools

npm i https://pkg.pr.new/@tanstack/react-query-devtools@9892

@tanstack/react-query-next-experimental

npm i https://pkg.pr.new/@tanstack/react-query-next-experimental@9892

@tanstack/react-query-persist-client

npm i https://pkg.pr.new/@tanstack/react-query-persist-client@9892

@tanstack/solid-query

npm i https://pkg.pr.new/@tanstack/solid-query@9892

@tanstack/solid-query-devtools

npm i https://pkg.pr.new/@tanstack/solid-query-devtools@9892

@tanstack/solid-query-persist-client

npm i https://pkg.pr.new/@tanstack/solid-query-persist-client@9892

@tanstack/svelte-query

npm i https://pkg.pr.new/@tanstack/svelte-query@9892

@tanstack/svelte-query-devtools

npm i https://pkg.pr.new/@tanstack/svelte-query-devtools@9892

@tanstack/svelte-query-persist-client

npm i https://pkg.pr.new/@tanstack/svelte-query-persist-client@9892

@tanstack/vue-query

npm i https://pkg.pr.new/@tanstack/vue-query@9892

@tanstack/vue-query-devtools

npm i https://pkg.pr.new/@tanstack/vue-query-devtools@9892

commit: c9e6076

@codecov
Copy link

codecov bot commented Nov 22, 2025

Codecov Report

βœ… All modified and coverable lines are covered by tests.
βœ… Project coverage is 100.00%. Comparing base (ae47807) to head (c9e6076).
⚠️ Report is 1 commits behind head on main.

Additional details and impacted files

Impacted file tree graph

@@             Coverage Diff              @@
##             main     #9892       +/-   ##
============================================
+ Coverage   45.70%   100.00%   +54.29%     
============================================
  Files         200         1      -199     
  Lines        8437        20     -8417     
  Branches     1936         2     -1934     
============================================
- Hits         3856        20     -3836     
+ Misses       4133         0     -4133     
+ Partials      448         0      -448     
Components Coverage Ξ”
@tanstack/angular-query-experimental βˆ… <ΓΈ> (βˆ…)
@tanstack/eslint-plugin-query βˆ… <ΓΈ> (βˆ…)
@tanstack/query-async-storage-persister βˆ… <ΓΈ> (βˆ…)
@tanstack/query-broadcast-client-experimental βˆ… <ΓΈ> (βˆ…)
@tanstack/query-codemods βˆ… <ΓΈ> (βˆ…)
@tanstack/query-core βˆ… <ΓΈ> (βˆ…)
@tanstack/query-devtools βˆ… <ΓΈ> (βˆ…)
@tanstack/query-persist-client-core βˆ… <ΓΈ> (βˆ…)
@tanstack/query-sync-storage-persister βˆ… <ΓΈ> (βˆ…)
@tanstack/query-test-utils βˆ… <ΓΈ> (βˆ…)
@tanstack/react-query βˆ… <ΓΈ> (βˆ…)
@tanstack/react-query-devtools βˆ… <ΓΈ> (βˆ…)
@tanstack/react-query-next-experimental βˆ… <ΓΈ> (βˆ…)
@tanstack/react-query-persist-client βˆ… <ΓΈ> (βˆ…)
@tanstack/solid-query βˆ… <ΓΈ> (βˆ…)
@tanstack/solid-query-devtools βˆ… <ΓΈ> (βˆ…)
@tanstack/solid-query-persist-client 100.00% <ΓΈ> (ΓΈ)
@tanstack/svelte-query βˆ… <ΓΈ> (βˆ…)
@tanstack/svelte-query-devtools βˆ… <ΓΈ> (βˆ…)
@tanstack/svelte-query-persist-client βˆ… <ΓΈ> (βˆ…)
@tanstack/vue-query βˆ… <ΓΈ> (βˆ…)
@tanstack/vue-query-devtools βˆ… <ΓΈ> (βˆ…)
πŸš€ New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • πŸ“¦ JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@sukvvon sukvvon marked this pull request as ready for review November 22, 2025 08:48
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

πŸ“œ Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

πŸ“₯ Commits

Reviewing files that changed from the base of the PR and between ae47807 and 22509e6.

πŸ“’ Files selected for processing (1)
  • packages/solid-query-persist-client/src/__tests__/PersistQueryClientProvider.test.tsx (19 hunks)
🧰 Additional context used
🧠 Learnings (3)
πŸ““ Common learnings
Learnt from: justjake
Repo: TanStack/query PR: 9612
File: packages/query-core/src/__tests__/timeoutManager.test.tsx:37-57
Timestamp: 2025-09-04T16:36:04.575Z
Learning: In Node.js v12.19+ (and browsers), converting a Timeout object to a number (e.g., Number(timeoutId)) is valid because Timeout implements Symbol.toPrimitive; clearTimeout/clearInterval accept the object or its numeric primitive. Do not flag this pattern in tests like packages/query-core/src/__tests__/timeoutManager.test.tsx.
πŸ“š Learning: 2025-09-02T17:57:33.184Z
Learnt from: TkDodo
Repo: TanStack/query PR: 9612
File: packages/query-async-storage-persister/src/asyncThrottle.ts:0-0
Timestamp: 2025-09-02T17:57:33.184Z
Learning: When importing from tanstack/query-core in other TanStack Query packages like query-async-storage-persister, a workspace dependency "tanstack/query-core": "workspace:*" needs to be added to the package.json.

Applied to files:

  • packages/solid-query-persist-client/src/__tests__/PersistQueryClientProvider.test.tsx
πŸ“š Learning: 2025-08-19T03:18:18.303Z
Learnt from: oscartbeaumont
Repo: TanStack/query PR: 9564
File: packages/solid-query-devtools/src/production.tsx:2-3
Timestamp: 2025-08-19T03:18:18.303Z
Learning: In the solid-query-devtools package, the codebase uses a pattern of type-only default imports combined with typeof for component type annotations (e.g., `import type SolidQueryDevtoolsComp from './devtools'` followed by `typeof SolidQueryDevtoolsComp`). This pattern is consistently used across index.tsx and production.tsx files, and the maintainers prefer consistency over changing this approach.

Applied to files:

  • packages/solid-query-persist-client/src/__tests__/PersistQueryClientProvider.test.tsx
🧬 Code graph analysis (1)
packages/solid-query-persist-client/src/__tests__/PersistQueryClientProvider.test.tsx (2)
packages/query-persist-client-core/src/__tests__/utils.ts (2)
  • createMockPersister (5-20)
  • removeClient (16-18)
packages/query-persist-client-core/src/persist.ts (1)
  • persistQueryClientSave (114-127)
πŸ”‡ Additional comments (8)
packages/solid-query-persist-client/src/__tests__/PersistQueryClientProvider.test.tsx (8)

49-55: LGTM! Proper fake timer lifecycle setup.

The beforeEach/afterEach hooks correctly initialize and clean up fake timers for all tests in the suite.


20-21: LGTM! Consistent with the sleep().then() pattern.

The refactor from async/await to promise chaining aligns with the PR objectives and works correctly with fake timers.


57-134: LGTM! Well-structured test with deterministic timing.

The test correctly uses fake timers with the sleep().then() pattern throughout, and timer advancements properly match the sleep durations (10ms for async operations, 0ms to flush microtasks for persist).


136-218: LGTM! Consistent pattern for useQueries.

The test properly validates useQueries behavior with the same fake timer patterns used throughout the suite.


220-302: LGTM! Correct validation of initialData during restoration.

The test properly validates that initialData is displayed while the restore operation is in progress, with correct fake timer usage.


386-435: LGTM! Proper validation of onSuccess callback timing.

The test correctly validates that onSuccess is called after restoration completes, with consistent use of fake timers and the sleep().then() pattern.


437-485: LGTM! Error handling test with correct timer usage.

The test properly validates error handling during restoration, including removal of corrupted cache, with consistent use of fake timers.


487-599: LGTM! Multi-client persistence test with proper mock setup.

The test correctly validates persistence across multiple clients with vi.fn().mockImplementation() using the sleep().then() pattern, and proper timer advancement to control execution flow.

…o fake timers, replace 'waitFor' with 'advanceTimersByTimeAsync', and use 'sleep().then()' pattern
@sukvvon sukvvon force-pushed the test/solid-query-persist-client-persist-query-client-provider-fake-timers branch from 22509e6 to c9e6076 Compare November 23, 2025 16:54
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
packages/solid-query-persist-client/src/__tests__/PersistQueryClientProvider.test.tsx (1)

331-335: Inconsistent with established pattern for side effects.

Based on learnings, when a queryFn contains side effects (like setting the fetched flag), the preferred pattern is async/await for clarity rather than .then(). This makes side effects more explicit and easier to understand.

Apply this diff to align with the established pattern:

-      const state = useQuery(() => ({
-        queryKey: key,
-        queryFn: () =>
-          sleep(10).then(() => {
-            fetched = true
-            return 'fetched'
-          }),
-        staleTime: Infinity,
-      }))
+      const state = useQuery(() => ({
+        queryKey: key,
+        queryFn: async () => {
+          await sleep(10)
+          fetched = true
+          return 'fetched'
+        },
+        staleTime: Infinity,
+      }))

Based on learnings, this pattern makes the side effect more visible and easier to verify.

πŸ“œ Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

πŸ“₯ Commits

Reviewing files that changed from the base of the PR and between 22509e6 and c9e6076.

πŸ“’ Files selected for processing (1)
  • packages/solid-query-persist-client/src/__tests__/PersistQueryClientProvider.test.tsx (19 hunks)
🧰 Additional context used
🧠 Learnings (4)
πŸ““ Common learnings
Learnt from: sukvvon
Repo: TanStack/query PR: 9892
File: packages/solid-query-persist-client/src/__tests__/PersistQueryClientProvider.test.tsx:331-335
Timestamp: 2025-11-22T09:06:05.219Z
Learning: In TanStack/query test files, when a queryFn contains side effects (e.g., setting flags for test verification), prefer async/await syntax for clarity; when there are no side effects, prefer the .then() pattern for conciseness.
πŸ“š Learning: 2025-11-22T09:06:05.219Z
Learnt from: sukvvon
Repo: TanStack/query PR: 9892
File: packages/solid-query-persist-client/src/__tests__/PersistQueryClientProvider.test.tsx:331-335
Timestamp: 2025-11-22T09:06:05.219Z
Learning: In TanStack/query test files, when a queryFn contains side effects (e.g., setting flags for test verification), prefer async/await syntax for clarity; when there are no side effects, prefer the .then() pattern for conciseness.

Applied to files:

  • packages/solid-query-persist-client/src/__tests__/PersistQueryClientProvider.test.tsx
πŸ“š Learning: 2025-08-19T03:18:18.303Z
Learnt from: oscartbeaumont
Repo: TanStack/query PR: 9564
File: packages/solid-query-devtools/src/production.tsx:2-3
Timestamp: 2025-08-19T03:18:18.303Z
Learning: In the solid-query-devtools package, the codebase uses a pattern of type-only default imports combined with typeof for component type annotations (e.g., `import type SolidQueryDevtoolsComp from './devtools'` followed by `typeof SolidQueryDevtoolsComp`). This pattern is consistently used across index.tsx and production.tsx files, and the maintainers prefer consistency over changing this approach.

Applied to files:

  • packages/solid-query-persist-client/src/__tests__/PersistQueryClientProvider.test.tsx
πŸ“š Learning: 2025-09-04T16:36:04.575Z
Learnt from: justjake
Repo: TanStack/query PR: 9612
File: packages/query-core/src/__tests__/timeoutManager.test.tsx:37-57
Timestamp: 2025-09-04T16:36:04.575Z
Learning: In Node.js v12.19+ (and browsers), converting a Timeout object to a number (e.g., Number(timeoutId)) is valid because Timeout implements Symbol.toPrimitive; clearTimeout/clearInterval accept the object or its numeric primitive. Do not flag this pattern in tests like packages/query-core/src/__tests__/timeoutManager.test.tsx.

Applied to files:

  • packages/solid-query-persist-client/src/__tests__/PersistQueryClientProvider.test.tsx
🧬 Code graph analysis (1)
packages/solid-query-persist-client/src/__tests__/PersistQueryClientProvider.test.tsx (3)
packages/query-persist-client-core/src/__tests__/utils.ts (2)
  • createMockPersister (5-20)
  • removeClient (16-18)
packages/query-persist-client-core/src/persist.ts (1)
  • persistQueryClientSave (114-127)
packages/solid-query/src/useQuery.ts (1)
  • useQuery (36-50)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Test
πŸ”‡ Additional comments (5)
packages/solid-query-persist-client/src/__tests__/PersistQueryClientProvider.test.tsx (5)

49-55: LGTM! Fake timer setup is correct.

The beforeEach/afterEach hooks properly set up and tear down fake timers for all tests.


20-22: LGTM! Persister pattern aligns with fake timers.

The change from async/await to the .then() pattern works correctly with fake timers and matches the PR objectives.


66-113: LGTM! Timer-driven test flow is correct.

The test properly uses fake timers with explicit timer advancement at each async boundary. The replacement of waitFor with direct assertions followed by advanceTimersByTimeAsync makes the test more deterministic.


372-384: Verify the change in expected state count is intentional.

The expected number of states changed from 3 to 2. With fake timers providing deterministic timing, this appears correct: when staleTime: Infinity prevents a refetch, we should see only the initial pending state and the hydrated success state, without an intermediate fetching state.

Please confirm this behavioral change is expected with fake timers and not a regression.


512-517: LGTM! Mock implementations use correct pattern.

The mock queryFn implementations properly use the sleep().then() pattern without side effects, which aligns with the established convention and works correctly with fake timers.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant