use-swr-config.test.tsx
Overview
This file contains unit and integration tests focused on verifying the behavior and configurations of the useSWR hook and SWRConfig context provider from the SWR (stale-while-revalidate) React data fetching library. It validates how SWR's configuration options, such as fallback data, refresh intervals, deduplication intervals, middleware usage, and pause behavior, are correctly applied and propagated through nested contexts.
The tests utilize React Testing Library and React hooks (useState, useEffect) to simulate component behavior under different SWR configurations. The file ensures robustness of the SWR configuration system, including context inheritance, config merging, and dynamic config functions.
Detailed Explanation of the File Contents
Imported Modules
React Testing Library:
act,screen,fireEvent— for rendering components, querying DOM, and simulating user events.React:
useState,useEffect— for state and lifecycle management in test components.SWR:
useSWR,SWRConfig,useSWRConfig, andMiddlewaretype — core hooks and configuration context.Custom utils:
renderWithConfig,createKey, renderWithGlobalCache — helper functions for rendering components with SWR context or generating unique keys.
Test Suite: 'useSWR - configs'
This suite tests various aspects of SWR's configuration behavior.
Test Cases
1. should read the config fallback from the context
Purpose: Verifies that fallback data and other configs (like
refreshIntervalanddedupingInterval) passed throughSWRConfigare correctly applied inuseSWR.Key points:
A fetcher increments a value on each call.
refreshIntervaltriggers automatic revalidation every 100 ms.Initial render shows no data (
data:).After mount, data updates to
0then increments to1after refresh interval.
Usage:
renderWithConfig(<Page />, {
fetcher,
refreshInterval: 100,
dedupingInterval: 0
})
2. should stop revalidations when config.isPaused returns true
Purpose: Ensures that when the
isPausedconfig returnstrue, SWR stops revalidations, and resumes whenisPausedreturnsfalse.Implementation details:
isPausedis a function depending on local statepaused.On mount,
pausedis set totrueto stop revalidations.Clicking the div toggles
paused.mutate()triggers manual revalidation.
Behavior:
While paused, data does not update on
mutate().When unpaused (clicked), data updates on revalidation.
Example interaction:
<div onClick={() => setPaused(!paused)}>
{error ? error : `data: ${data}`}
</div>
3. should expose default config as static property on SWRConfig
Checks:
SWRConfig.defaultValueexists and exposes the default SWR config object.
4. should expose the default config from useSWRConfig
Purpose: Validates that
useSWRConfighook returns the global default SWR config when no provider overrides it.Implementation:
Renders a dummy component that calls
useSWRConfig.Compares returned config with
SWRConfig.defaultValue.
5. should expose the correctly extended config from useSWRConfig
Purpose: Tests how nested
SWRConfigproviders merge their configs.Key points:
Two middlewares (
middleware1,middleware2) are defined.Outer
SWRConfigsets some config andmiddleware1.Inner
SWRConfigoverrides some config and usesmiddleware2.The merged config:
dedupingIntervalfrom inner config (2).refreshIntervalfrom outer config (1).fallbackmerges keys from both{ a: 2, b: 1, c: 2 }.useconcatenates middlewares[middleware1, middleware2].
Usage Example:
<SWRConfig value={{ dedupingInterval: 1, use: [middleware1] }}>
<SWRConfig value={{ dedupingInterval: 2, use: [middleware2] }}>
<Page />
</SWRConfig>
</SWRConfig>
6. should ignore parent config when value is functional
Purpose: Tests that when the
valueprop ofSWRConfigis a function (receives parent config), it overrides the parent's config instead of merging.Behavior:
The function receives parent config and returns a new config object.
Resulting config includes computed
dedupingIntervaland newfallbackandusearrays.refreshIntervalis not inherited.
Example:
<SWRConfig value={parentConfig => ({
dedupingInterval: 2 + parentConfig.dedupingInterval,
fallback: { a: 2, c: 2 },
use: [middleware2]
})}>
<Page />
</SWRConfig>
7. should not occur error when fallback is undefined
Purpose: Ensures that SWR works fine when fallback data is explicitly set to
undefined.Details:
Uses
createKeyto generate a unique key.Fetcher returns a static string
'data'.Renders a component using SWR with fallback set to
undefined.Verifies that data is fetched and displayed correctly.
Important Implementation Details
useSWRConfigHook: Used inside test components to access current SWR config from context.Middleware Usage: Middleware functions wrap
useSWRto extend or modify behavior; tested for composition and merging.Config Merging: Nested
SWRConfigproviders merge config objects by default, combining fallback data and middleware arrays.Pause Mechanism: The
isPausedconfig is a function that controls whether SWR should skip automatic revalidations.Testing Timers and Revalidations: Uses
refreshIntervaland manualmutate()calls to test timed and on-demand data fetching.
Interaction with Other Parts of the System
SWR Library: This file tests core functionality of the
useSWRhook andSWRConfigprovider from the SWR library.Custom Utils: Relies on utility functions like
renderWithConfigandcreateKeyfrom./utilsto facilitate rendering components with SWR context and generating unique keys for cache keys.React Testing Library: Uses testing utilities to simulate user interactions and verify UI updates.
Middleware: Middleware functions here are placeholders to test config merging, but in the system, they could be used for logging, caching strategies, or other enhancements.
Usage Examples Extracted from Tests
Basic useSWR with Config Fallback
function Page() {
const { data } = useSWR(key)
return <div>data: {data}</div>
}
renderWithConfig(<Page />, {
fetcher,
refreshInterval: 100,
dedupingInterval: 0
})
Pause Revalidation Based on State
function Page() {
const [paused, setPaused] = useState(false)
const { data, error, mutate } = useSWR(key, fetcher, {
revalidateOnMount: true,
refreshInterval: 1,
isPaused: () => paused
})
useEffect(() => {
setPaused(true) // pause on mount
}, [])
return (
<div onClick={() => setPaused(!paused)}>
{error ? error : `data: ${data}`}
</div>
)
}
Mermaid Diagram
flowchart TD
A[use-swr-config.test.tsx]
A --> B[Tests "useSWR - configs"]
B --> C1[Config fallback reading]
B --> C2[Pause revalidation via isPaused]
B --> C3[Default config static property]
B --> C4[useSWRConfig returns default config]
B --> C5[Nested SWRConfig merges config]
B --> C6[Functional value config overrides parent]
B --> C7[Fallback undefined does not error]
C2 -->|uses| D1[Page component with paused state & mutate]
C5 -->|uses| D2[Page component with useSWRConfig]
C6 -->|uses| D3[Page component with functional SWRConfig value]
Summary
This test file thoroughly validates the configuration system of the SWR library, ensuring that:
Config contexts propagate correctly.
Nested configs merge or override as expected.
Pause functionality works for stopping revalidations.
Default configs are accessible and consistent.
Edge cases like undefined fallback data don't cause errors.
It is essential for maintaining the reliability and predictability of SWR's behavior in React applications.