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 14, 2024
1 parent 10fbb79 commit a3c9ea4
Show file tree
Hide file tree
Showing 4 changed files with 56 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 @@ -5,6 +5,7 @@ import { RoutingEvent } from "./routingEvent";

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

export const RoutingContext = createContext<Context | undefined>(undefined);
Expand All @@ -30,6 +31,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 @@ -62,7 +72,10 @@ export function TestRoutingContext({
}) {
return (
<RoutingContext.Provider
value={{ activeRouteEvents: { current: activeRouteEvents } }}
value={{
activeRouteEvents: { current: activeRouteEvents },
isTestRoutingContext: true,
}}
>
{children}
</RoutingContext.Provider>
Expand Down
33 changes: 33 additions & 0 deletions src/xstateTree.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
buildActions,
createXStateTreeMachine,
} from "./builders";
import { TestRoutingContext } from "./routing";
import { singleSlot } from "./slots";
import { delay } from "./utils";
import {
Expand Down Expand Up @@ -337,6 +338,38 @@ 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 = createMachine({
id: "test",
initial: "idle",
states: {
idle: {},
},
});

const RootMachine = createXStateTreeMachine(machine, {
View() {
return <p>I am root</p>;
},
});
const Root = buildRootComponent(RootMachine, {
basePath: "/",
history: createMemoryHistory(),
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 machine = createMachine({
id: "test",
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 @@ -357,7 +358,12 @@ export function buildRootComponent(
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 a3c9ea4

Please sign in to comment.