Testing Utilities
Testing Utilities: published entrypoints, signatures, and the constraints around them.
Example
Mock the query or route boundary, drive public state transitions, and inspect invalidation or route warnings without replacing the application runtime.
import { createInvalidationRecorder, mockQuery } from '@askrjs/askr/testing';
import { matchRoute } from '@askrjs/askr/router';
const projects = mockQuery({ data: [{ id: 'p1', name: 'Northstar' }] });
const invalidations = createInvalidationRecorder();
expect(matchRoute('/projects/p1', { registry })?.params.id).toBe('p1');
expect(invalidations.calls).toEqual([]);Query mocks
@askrjs/askr/testing exports mockQuery for constructing a Query<T> in any state your components might see: mockQuery(data) for fresh data, plus .loading(), .error(err, previousData?), .refreshing(data), .stale(data, reason?), and .pendingWrite(data). Each accepts an optional refresh callback via MockQueryOptions so you can assert refetch behavior without touching a real query registry.
Invalidation recorder
createInvalidationRecorder() returns an InvalidationRecorder that captures every cache invalidation call made during a test — each record is { prefix, markPendingWrite }, and the recorder exposes the running list as calls and the deduped prefixes seen so far. Call .clear() between assertions or .stop() when you're done listening, so recorders don't leak across test cases.
Route matching
matchRoute(path, options) from @askrjs/askr/router runs a path through the router's matching logic without booting an app, returning a RouteMatch or null; pass the same explicit RouteRegistry used by your application via { registry } to test against a specific route set. It's the fastest way to assert that a given URL resolves to the route you expect, including param extraction, before wiring up any actual navigation.
Warnings
getRouteWarnings({ registry }) surfaces route-collision problems as RoutePatternWarning[] — each warning reports the kind (currently 'route-collision'), the conflicting path, the specific segment that collides, and an optional namespace for MFE-style route grouping. Run it in a test against the same explicit RouteRegistry your app uses to catch ambiguous patterns before they show up as a mis-routed request in production.