Skip to content

Commit a3c9ea4

Browse files
committed
fix(testing): allow nesting routing roots inside TestRoutingContext
1 parent 10fbb79 commit a3c9ea4

File tree

4 files changed

+56
-3
lines changed

4 files changed

+56
-3
lines changed

src/routing/index.ts

+1
Original file line numberDiff line numberDiff line change
@@ -28,5 +28,6 @@ export {
2828
RoutingContext,
2929
TestRoutingContext,
3030
useInRoutingContext,
31+
useInTestRoutingContext,
3132
useActiveRouteEvents,
3233
} from "./providers";

src/routing/providers.tsx

+14-1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { RoutingEvent } from "./routingEvent";
55

66
type Context = {
77
activeRouteEvents?: MutableRefObject<RoutingEvent<any>[]>;
8+
isTestRoutingContext?: boolean;
89
};
910

1011
export const RoutingContext = createContext<Context | undefined>(undefined);
@@ -30,6 +31,15 @@ export function useInRoutingContext(): boolean {
3031
return context !== undefined;
3132
}
3233

34+
/**
35+
* @private
36+
*/
37+
export function useInTestRoutingContext(): boolean {
38+
const context = useContext(RoutingContext);
39+
40+
return context?.isTestRoutingContext ?? false;
41+
}
42+
3343
/**
3444
* @public
3545
*
@@ -62,7 +72,10 @@ export function TestRoutingContext({
6272
}) {
6373
return (
6474
<RoutingContext.Provider
65-
value={{ activeRouteEvents: { current: activeRouteEvents } }}
75+
value={{
76+
activeRouteEvents: { current: activeRouteEvents },
77+
isTestRoutingContext: true,
78+
}}
6679
>
6780
{children}
6881
</RoutingContext.Provider>

src/xstateTree.spec.tsx

+33
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import {
1111
buildActions,
1212
createXStateTreeMachine,
1313
} from "./builders";
14+
import { TestRoutingContext } from "./routing";
1415
import { singleSlot } from "./slots";
1516
import { delay } from "./utils";
1617
import {
@@ -337,6 +338,38 @@ describe("xstate-tree", () => {
337338
throw new Error("Should have thrown");
338339
});
339340

341+
it("does not throw an error if it's inside a test routing context", async () => {
342+
const machine = createMachine({
343+
id: "test",
344+
initial: "idle",
345+
states: {
346+
idle: {},
347+
},
348+
});
349+
350+
const RootMachine = createXStateTreeMachine(machine, {
351+
View() {
352+
return <p>I am root</p>;
353+
},
354+
});
355+
const Root = buildRootComponent(RootMachine, {
356+
basePath: "/",
357+
history: createMemoryHistory(),
358+
routes: [],
359+
});
360+
361+
const { rerender } = render(
362+
<TestRoutingContext activeRouteEvents={[]}>
363+
<Root />
364+
</TestRoutingContext>
365+
);
366+
rerender(
367+
<TestRoutingContext activeRouteEvents={[]}>
368+
<Root />
369+
</TestRoutingContext>
370+
);
371+
});
372+
340373
it("does not throw an error if either or one are a routing root", async () => {
341374
const machine = createMachine({
342375
id: "test",

src/xstateTree.tsx

+8-2
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,9 @@ import {
2424
RoutingEvent,
2525
SharedMeta,
2626
useInRoutingContext,
27+
useInTestRoutingContext,
28+
useActiveRouteEvents,
2729
} from "./routing";
28-
import { useActiveRouteEvents } from "./routing/providers";
2930
import { GetSlotNames, Slot } from "./slots";
3031
import { GlobalEvents, AnyXstateTreeMachine, XstateTreeHistory } from "./types";
3132
import { useConstant } from "./useConstant";
@@ -357,7 +358,12 @@ export function buildRootComponent(
357358
activeRouteEventsRef.current = events;
358359
};
359360
const insideRoutingContext = useInRoutingContext();
360-
if (insideRoutingContext && typeof routing !== "undefined") {
361+
const inTestRoutingContext = useInTestRoutingContext();
362+
if (
363+
!inTestRoutingContext &&
364+
insideRoutingContext &&
365+
typeof routing !== "undefined"
366+
) {
361367
const m =
362368
"Routing root rendered inside routing context, this implies a bug";
363369
if (process.env.NODE_ENV !== "production") {

0 commit comments

Comments
 (0)