use-swr-cache.test.tsx
Overview
This file contains comprehensive test suites for verifying the behavior, correctness, and flexibility of the caching mechanism in the useSWR React hook from the SWR library. It specifically focuses on:
Custom cache providers and their integration with
useSWR.The interaction between components and caches at multiple levels (global cache, nested caches, isolated caches).
Cache mutation and update flows.
Revalidation behaviors (such as revalidate on focus).
Fallback cache values.
Cache instance persistence across component renders and unmounts.
Ensuring compatibility with React's Strict Mode.
The tests leverage React Testing Library and utilities to simulate component rendering, user interactions, and asynchronous state updates.
Detailed Explanation of Test Suites and Key Functions
Imported Utilities and Hooks
useSWR: The hook under test, which manages data fetching and caching.useSWRConfig,SWRConfig,mutate as globalMutate: Provides global SWR configuration, cache instance, and mutate function.Testing utilities:
act,fireEvent, screen from@testing-library/reactfor simulating user events and asserting UI states.Helper utilities from ./utils (e.g.
sleep,createKey,renderWithConfig) to facilitate cache key generation, asynchronous waits, and rendering SWR components with custom configuration.
Test Suite: useSWR - cache provider
This suite tests behaviors when using custom cache providers (i.e., caches supplied via provider option or SWRConfig).
Key Test Cases
Cache update propagation
Verifies that cache updates propagate correctly when switching between keys.
Usage: Renders a component that switches between two keys on click; asserts cache contents before and after.
Initial cache reads with subsequent updates
Ensures data initially read from cache correctly updates after asynchronous fetches.
Direct mutation of cache data
Uses mutate from
useSWRConfigto directly change cached data and verifies UI reflects this immediately.
Multi-level cache support
Shows nested components can use different cache providers, resulting in different data for the same cache key.
Isolated cache instances
Ensures that multiple
SWRConfigproviders with different caches isolate state correctly.
Provider options respect (initFocus, initReconnect)
Tests that lifecycle hooks for focus and reconnect events are called and unsubscribed properly.
Revalidate on focus works
Confirms that data is revalidated when window gains focus, considering throttling intervals.
Fallback values with custom provider
Verifies fallback cache values are used immediately before fetch completion.
Fallback ignored if cache exists
Tests fallback values do not override existing cached data.
Parent cache extension
Demonstrates how a custom provider can wrap and extend the parent cache's behavior (e.g., by appending text to cached data).
Cache instance access via
useSWRConfigConfirms that the cache instance returned from the hook matches the provided cache.
Cache hierarchy correctness
Ensures nested
SWRConfigcomponents maintain correct fallback and cache precedence.
Cache provider instance reuse on rerender
Validates that the cache provider function is not called multiple times unnecessarily during rerenders.
Test Suite: useSWR - global cache
This suite tests behaviors using the global cache instance that SWR provides by default.
Key Test Cases
Global cache and mutate by default
Confirms that useSWRConfig() returns the global cache and mutate function.
Updating the global cache
Similar to custom provider tests but with global cache, verifies cache updates on key changes.
Mutate cached value globally
Uses mutate from global config to update cache and verifies UI.
Revalidation on focus with global cache
Tests revalidate on window focus behavior with the global cache.
Fallback values supported globally
Verifies fallback values work as expected with global cache.
Cache instance reuse after unmounting SWRConfig
Tests that cache and event listeners persist correctly even when
SWRConfigis unmounted and remounted.
Correct cache instance under React Strict Mode
Ensures cache works correctly when components are wrapped in React's StrictMode.
Important Implementation Details and Algorithms
Cache Providers: The tests extensively simulate different cache providers by passing functions returning
Mapinstances or wrapped objects with cache methods (get,set,delete,keys). This mimics how SWR can be customized to use any cache storage.Cache Mutation: The mutate function allows imperative updates of cache entries, which tests verify propagate immediately to components.
Multi-level Caches: Nesting of
SWRConfigcomponents demonstrates how SWR supports layered caches with fallback and overriding cache entries.Revalidation Mechanisms: Tests simulate window focus events to check SWR's automatic revalidation behavior within configured throttle intervals.
Fallback Data: SWR's fallback mechanism is tested to ensure that cached or fallback data is prioritized correctly during initial data loading stages.
Provider Lifecycle Hooks: Hooks such as
initFocusandinitReconnectenable providers to subscribe/unsubscribe to browser events, which tests verify are invoked correctly and cleaned up on unmount.
Interaction With Other System Parts
useSWRHook: The file tests howuseSWRinteracts with caching layers and config providers.SWRConfigContext Provider: Provides custom cache instances and configuration to descendant components.Utilities from ./utils: Used extensively for generating keys, simulating delays (
sleep), rendering components with specific configs, and controlling event timing (nextTick,focusOn).React Testing Library: Used for component rendering, event dispatching, and querying DOM elements to verify UI states.
React State & Effects: Components use React's
useStateand effects implicitly withinuseSWRfor data fetching and cache updates.
Usage Examples
Example 1: Updating cache on interaction
function Page() {
const [index, setIndex] = useState(0)
const { data } = useSWR(keys[index], key => 'res:' + key)
return <div onClick={() => setIndex(1)}>{data}</div>
}
// Renders initially data for keys[0], then updates to keys[1] on click
renderWithConfig(<Page />, { provider: () => new Map() })
Example 2: Using multi-level caches
function Foo() {
const { data } = useSWR(key, null)
return <>{data}</>
}
function Page() {
const { data } = useSWR(key, null)
return (
<div>
{data}:
<SWRConfig value={{ provider: () => new Map([[key, { data: '2' }]]) }}>
<Foo />
</SWRConfig>
</div>
)
}
Visual Diagram: Component and Cache Interaction Flow
flowchart TD
A[Page Component] -->|useSWR(key1)| B[Cache Provider 1]
A -->|SWRConfig| C[Child Component Foo]
C -->|useSWR(key1)| D[Cache Provider 2]
B -->|provides cache data| A
D -->|provides cache data| C
E[Global Cache] -->|Default cache| F[useSWRConfig hook]
style B fill:#f9f,stroke:#333,stroke-width:1px
style D fill:#bbf,stroke:#333,stroke-width:1px
style E fill:#afa,stroke:#333,stroke-width:1px
PageusesuseSWRwith a cache provider (could be custom or global).Foois wrapped in a nestedSWRConfigproviding a different cache.useSWRConfigexposes the current cache and mutate functions.The diagram illustrates multi-level caches and their interaction with components.
Summary
The use-swr-cache.test.tsx file is a robust test suite validating the caching layer of the SWR React hook. It ensures that:
Custom and global caches work correctly with SWR.
Cache mutation and updates propagate properly.
Multiple cache layers and isolated caches coexist without interference.
Revalidation on window focus and other lifecycle events behave as expected.
Fallback caches are respected.
Cache instances persist and behave consistently across React render cycles and modes.
These tests are vital to maintaining the integrity and flexibility of SWR's caching mechanism in complex React applications.