Skip to content

Commit

Permalink
fix(testing): allow nesting routing roots inside TestRoutingContext
Browse files Browse the repository at this point in the history
  • Loading branch information
UberMouse committed Aug 15, 2024
1 parent f33a645 commit 70607bb
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 3 deletions.
1 change: 1 addition & 0 deletions src/routing/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,5 +28,6 @@ export {
RoutingContext,
TestRoutingContext,
useInRoutingContext,
useInTestRoutingContext,
useActiveRouteEvents,
} from "./providers";
15 changes: 14 additions & 1 deletion src/routing/providers.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { RoutingEvent } from "./routingEvent";

type Context = {
activeRouteEvents?: MutableRefObject<RoutingEvent<AnyRoute>[]>;
isTestRoutingContext?: boolean;
};

export const RoutingContext = createContext<Context | undefined>(undefined);
Expand All @@ -31,6 +32,15 @@ export function useInRoutingContext(): boolean {
return context !== undefined;
}

/**
* @private
*/
export function useInTestRoutingContext(): boolean {
const context = useContext(RoutingContext);

return context?.isTestRoutingContext ?? false;
}

/**
* @public
*
Expand Down Expand Up @@ -63,7 +73,10 @@ export function TestRoutingContext({
}) {
return (
<RoutingContext.Provider
value={{ activeRouteEvents: { current: activeRouteEvents } }}
value={{
activeRouteEvents: { current: activeRouteEvents },
isTestRoutingContext: true,
}}
>
{children}
</RoutingContext.Provider>
Expand Down
36 changes: 36 additions & 0 deletions src/xstateTree.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import React from "react";
import { setup, createActor, assign } from "xstate";

import { createXStateTreeMachine, viewToMachine } from "./builders";
import { TestRoutingContext } from "./routing";
import { singleSlot } from "./slots";
import { delay } from "./utils";
import {
Expand Down Expand Up @@ -438,6 +439,41 @@ describe("xstate-tree", () => {
throw new Error("Should have thrown");
});

it("does not throw an error if it's inside a test routing context", async () => {
const machine = setup({}).createMachine({
id: "test",
initial: "idle",
states: {
idle: {},
},
});

const RootMachine = createXStateTreeMachine(machine, {
View() {
return <p>I am root</p>;
},
});
const Root = buildRootComponent({
machine: RootMachine,
routing: {
basePath: "/",
history: createMemoryHistory<any>(),
routes: [],
},
});

const { rerender } = render(
<TestRoutingContext activeRouteEvents={[]}>
<Root />
</TestRoutingContext>
);
rerender(
<TestRoutingContext activeRouteEvents={[]}>
<Root />
</TestRoutingContext>
);
});

it("does not throw an error if either or one are a routing root", async () => {
const RootMachine = viewToMachine(() => <p>I am root</p>);
const Root = buildRootComponent({ machine: RootMachine });
Expand Down
10 changes: 8 additions & 2 deletions src/xstateTree.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,9 @@ import {
RoutingEvent,
SharedMeta,
useInRoutingContext,
useInTestRoutingContext,
useActiveRouteEvents,
} from "./routing";
import { useActiveRouteEvents } from "./routing/providers";
import { GetSlotNames, Slot } from "./slots";
import { GlobalEvents, AnyXstateTreeMachine, XstateTreeHistory } from "./types";
import { useConstant } from "./useConstant";
Expand Down Expand Up @@ -381,7 +382,12 @@ export function buildRootComponent<TMachine extends AnyXstateTreeMachine>(
activeRouteEventsRef.current = events;
};
const insideRoutingContext = useInRoutingContext();
if (insideRoutingContext && typeof routing !== "undefined") {
const inTestRoutingContext = useInTestRoutingContext();
if (
!inTestRoutingContext &&
insideRoutingContext &&
typeof routing !== "undefined"
) {
const m =
"Routing root rendered inside routing context, this implies a bug";
if (process.env.NODE_ENV !== "production") {
Expand Down

0 comments on commit 70607bb

Please sign in to comment.