UNPKG

one

Version:

One is a new React Framework that makes Vite serve both native and web.

182 lines (181 loc) 6.25 kB
import React from "react"; import TestRenderer, { act } from "react-test-renderer"; import { afterEach, beforeEach, describe, expect, it } from "vitest"; import { getQualifiedRouteComponent } from "./useScreens.mjs"; import { jsx, jsxs } from "react/jsx-runtime"; const pendingRoute = new Promise(() => {}); const previousTarget = "web"; const previousSuspendRoutesNative = process.env.ONE_SUSPEND_ROUTES_NATIVE; const previousDisableSuspense = globalThis.__ONE_DISABLE_SUSPENSE_ROUTES__; function createRouteNode(type, route, contextKey, loadRoute) { return { type, route, contextKey, loadRoute, children: [], dynamic: null }; } function SuspendingRoute() { throw pendingRoute; } beforeEach(() => { process.env.TAMAGUI_TARGET = "native"; delete process.env.ONE_SUSPEND_ROUTES_NATIVE; delete globalThis.__ONE_DISABLE_SUSPENSE_ROUTES__; }); afterEach(() => { process.env.TAMAGUI_TARGET = previousTarget; if (previousSuspendRoutesNative === void 0) delete process.env.ONE_SUSPEND_ROUTES_NATIVE;else process.env.ONE_SUSPEND_ROUTES_NATIVE = previousSuspendRoutesNative; if (previousDisableSuspense === void 0) delete globalThis.__ONE_DISABLE_SUSPENSE_ROUTES__;else globalThis.__ONE_DISABLE_SUSPENSE_ROUTES__ = previousDisableSuspense; }); describe("route SuspenseFallback", () => { it("inherits the layout fallback and passes the suspended route details", async () => { const ChildRoute = getQualifiedRouteComponent(createRouteNode("spa", "profile/[id]", "./(app)/profile/[id].tsx", () => { throw pendingRoute; })); const LayoutRoute = getQualifiedRouteComponent(createRouteNode("layout", "(app)", "./(app)/_layout.tsx", () => ({ default: () => /* @__PURE__ */jsx(ChildRoute, { route: { params: { id: "123" } } }), SuspenseFallback: ({ route, params }) => /* @__PURE__ */jsxs("div", { "data-fallback": "layout", children: [route, ":", params.id] }) }))); let renderer; await act(async () => { renderer = TestRenderer.create(/* @__PURE__ */jsx(LayoutRoute, {})); }); expect(renderer.root.findByProps({ "data-fallback": "layout" }).children).toEqual(["./(app)/profile/[id].tsx", ":", "123"]); }); it("uses the nearest layout fallback", async () => { const ChildRoute = getQualifiedRouteComponent(createRouteNode("spa", "profile", "./(app)/profile.tsx", () => ({ default: SuspendingRoute }))); const NestedLayoutRoute = getQualifiedRouteComponent(createRouteNode("layout", "(app)", "./(app)/_layout.tsx", () => ({ default: () => /* @__PURE__ */jsx(ChildRoute, {}), SuspenseFallback: () => /* @__PURE__ */jsx("div", { "data-fallback": "nested" }) }))); const RootLayoutRoute = getQualifiedRouteComponent(createRouteNode("layout", "", "./_layout.tsx", () => ({ default: () => /* @__PURE__ */jsx(NestedLayoutRoute, {}), SuspenseFallback: () => /* @__PURE__ */jsx("div", { "data-fallback": "root" }) }))); let renderer; await act(async () => { renderer = TestRenderer.create(/* @__PURE__ */jsx(RootLayoutRoute, {})); }); expect(renderer.root.findAllByProps({ "data-fallback": "nested" })).toHaveLength(1); expect(renderer.root.findAllByProps({ "data-fallback": "root" })).toHaveLength(0); }); it("ignores a SuspenseFallback exported from a leaf route", async () => { const ChildRoute = getQualifiedRouteComponent(createRouteNode("spa", "profile", "./profile.tsx", () => ({ default: SuspendingRoute, SuspenseFallback: () => /* @__PURE__ */jsx("div", { "data-fallback": "leaf" }) }))); let renderer; await act(async () => { renderer = TestRenderer.create(/* @__PURE__ */jsx(ChildRoute, {})); }); expect(renderer.root.findAllByProps({ "data-fallback": "leaf" })).toHaveLength(0); expect(renderer.toJSON()).toBeNull(); }); }); describe("ErrorBoundary route identity", () => { it("preserves page state across a re-render when the route exports ErrorBoundary", async () => { let mounts = 0; function Page() { const [count, setCount] = React.useState(0); React.useEffect(() => { mounts += 1; }, []); return /* @__PURE__ */jsx("button", { "data-count": count, onClick: () => setCount(value => value + 1), children: count }); } function ErrorBoundary() { return /* @__PURE__ */jsx("div", { "data-error": "1" }); } const Route = getQualifiedRouteComponent(createRouteNode("spa", "onboarding", "./auth/onboarding.tsx", () => ({ default: Page, ErrorBoundary }))); function Harness({ tick }) { return /* @__PURE__ */jsx(Route, { tick }); } let renderer; await act(async () => { renderer = TestRenderer.create(/* @__PURE__ */jsx(Harness, { tick: 0 })); }); const button = renderer.root.findByType("button"); expect(button.props["data-count"]).toBe(0); await act(async () => { button.props.onClick(); }); expect(renderer.root.findByType("button").props["data-count"]).toBe(1); expect(mounts).toBe(1); await act(async () => { renderer.update(/* @__PURE__ */jsx(Harness, { tick: 1 })); }); expect(renderer.root.findByType("button").props["data-count"]).toBe(1); expect(mounts).toBe(1); }); it("still renders the exported ErrorBoundary when the page throws", async () => { function Page() { throw new Error("boom"); } function ErrorBoundary({ error }) { return /* @__PURE__ */jsx("div", { "data-caught": error.message }); } const Route = getQualifiedRouteComponent(createRouteNode("spa", "broken", "./broken.tsx", () => ({ default: Page, ErrorBoundary }))); let renderer; await act(async () => { renderer = TestRenderer.create(/* @__PURE__ */jsx(Route, {})); }); expect(renderer.root.findByProps({ "data-caught": "boom" })).toBeTruthy(); }); }); //# sourceMappingURL=useScreens.test.mjs.map