UNPKG

one

Version:

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

2,145 lines 62 kB
import { produce } from "immer"; import { expect, test } from "vitest"; import { findFocusedRoute } from "../findFocusedRoute"; import { getPathFromState } from "../getPathFromState"; import { getStateFromPath } from "../getStateFromPath"; const changePath = (state, path) => produce(state, (draftState) => { const route = findFocusedRoute(draftState); route.path = path; }); test("returns undefined for invalid path", () => { expect(getStateFromPath("//")).toBeUndefined(); }); test.skip("converts path string to initial state", () => { const path = "foo/bar/baz%20qux?author=jane%20%26%20co&valid=true", state = { routes: [ { name: "foo", state: { routes: [ { name: "bar", state: { routes: [ { name: "baz qux", params: { author: "jane & co", valid: "true" }, path } ] } } ] } } ] }; expect(getStateFromPath(path)).toEqual(state), expect(getStateFromPath(getPathFromState(state))).toEqual( changePath(state, "/foo/bar/baz%20qux?author=jane%20%26%20co&valid=true") ); }); test.skip("decodes encoded params in path", () => { const path = "/foo/bar/bar_%23_foo", config = { screens: { Foo: { path: "foo", screens: { Bar: { path: "/bar/:id" } } } } }, state = { routes: [ { name: "Foo", state: { routes: [ { name: "Bar", params: { id: "bar_#_foo" }, path } ] } } ] }; expect(getStateFromPath(path, config)).toEqual(state), expect(getPathFromState(getStateFromPath(path, config), config)).toEqual(path); }); test.skip("decodes encoded params in path that have encoded /", () => { const path = "/foo/bar/bar_%2F_foo", config = { screens: { Foo: { path: "foo", screens: { Bar: { path: "/bar/:id" } } } } }, state = { routes: [ { name: "Foo", state: { routes: [ { name: "Bar", params: { id: "bar_/_foo" }, path } ] } } ] }; expect(getStateFromPath(path, config)).toEqual(state), expect(getPathFromState(getStateFromPath(path, config), config)).toEqual(path); }); test.skip("converts path string to initial state with config", () => { const path = "/foo/bar/sweet/apple/baz/jane?count=10&answer=42&valid=true", config = { screens: { Foo: { path: "foo", screens: { Bar: { path: "bar/:type/:fruit", screens: { Baz: { path: "baz/:author", parse: { author: (author) => author.replace(/^\w/, (c) => c.toUpperCase()), count: Number, valid: Boolean }, stringify: { author: (author) => author.toLowerCase() } } } } } } } }, state = { routes: [ { name: "Foo", state: { routes: [ { name: "Bar", params: { fruit: "apple", type: "sweet" }, state: { routes: [ { name: "Baz", params: { author: "Jane", count: 10, answer: "42", valid: !0 }, path } ] } } ] } } ] }; expect(getStateFromPath(path, config)).toEqual(state), expect(getStateFromPath(getPathFromState(state, config), config)).toEqual(state); }); test("handles leading slash when converting", () => { const path = "/foo/bar/?count=42"; expect(getStateFromPath(path)).toEqual({ routes: [ { name: "foo", state: { routes: [ { name: "bar", params: { count: "42" }, path } ] } } ] }); }); test("handles ending slash when converting", () => { const path = "foo/bar/?count=42"; expect(getStateFromPath(path)).toEqual({ routes: [ { name: "foo", state: { routes: [ { name: "bar", params: { count: "42" }, path } ] } } ] }); }); test("handles route without param", () => { const path = "foo/bar", state = { routes: [ { name: "foo", state: { routes: [{ name: "bar", path }] } } ] }; expect(getStateFromPath(path)).toEqual(state), expect(getStateFromPath(getPathFromState(state))).toEqual( changePath(state, "/foo/bar") ); }); test.skip("converts path string to initial state with config with nested screens", () => { const path = "/foe/bar/sweet/apple/baz/jane?count=10&answer=42&valid=true", config = { screens: { Foo: { path: "foo", screens: { Foe: { path: "foe", exact: !0, screens: { Bar: { path: "bar/:type/:fruit", screens: { Baz: { path: "baz/:author", parse: { author: (author) => author.replace(/^\w/, (c) => c.toUpperCase()), count: Number, valid: Boolean }, stringify: { author: (author) => author.toLowerCase() } } } } } } } } } }, state = { routes: [ { name: "Foo", state: { routes: [ { name: "Foe", state: { routes: [ { name: "Bar", params: { fruit: "apple", type: "sweet" }, state: { routes: [ { name: "Baz", params: { author: "Jane", count: 10, answer: "42", valid: !0 }, path } ] } } ] } } ] } } ] }; expect(getStateFromPath(path, config)).toEqual(state), expect(getStateFromPath(getPathFromState(state, config), config)).toEqual(state); }); test.skip("converts path string to initial state with config with nested screens and unused parse functions", () => { const path = "/foe/baz/jane?count=10&answer=42&valid=true", config = { screens: { Foo: { path: "foo", screens: { Foe: { path: "foe", exact: !0, screens: { Baz: { path: "baz/:author", parse: { author: (author) => author.replace(/^\w/, (c) => c.toUpperCase()), count: Number, valid: Boolean, id: Boolean } } } } } } } }, state = { routes: [ { name: "Foo", state: { routes: [ { name: "Foe", state: { routes: [ { name: "Baz", params: { author: "Jane", count: 10, answer: "42", valid: !0 }, path } ] } } ] } } ] }; expect(getStateFromPath(path, config)).toEqual(state), expect(getStateFromPath(getPathFromState(state, config), config)).toEqual( changePath(state, "/foe/baz/Jane?count=10&answer=42&valid=true") ); }); test.skip("handles nested object with unused configs and with parse in it", () => { const path = "/bar/sweet/apple/foe/bis/jane?count=10&answer=42&valid=true", config = { screens: { Bar: { path: "bar/:type/:fruit", screens: { Foo: { screens: { Foe: { path: "foe", screens: { Baz: { screens: { Bos: { path: "bos", exact: !0 }, Bis: { path: "bis/:author", stringify: { author: (author) => author.replace(/^\w/, (c) => c.toLowerCase()) }, parse: { author: (author) => author.replace(/^\w/, (c) => c.toUpperCase()), count: Number, valid: Boolean } } } } } } } } } } } }, state = { routes: [ { name: "Bar", params: { fruit: "apple", type: "sweet" }, state: { routes: [ { name: "Foo", state: { routes: [ { name: "Foe", state: { routes: [ { name: "Baz", state: { routes: [ { name: "Bis", params: { author: "Jane", count: 10, answer: "42", valid: !0 }, path } ] } } ] } } ] } } ] } } ] }; expect(getStateFromPath(path, config)).toEqual(state), expect(getStateFromPath(getPathFromState(state, config), config)).toEqual(state); }); test("handles parse in nested object for second route depth", () => { const path = "/baz", config = { screens: { Foo: { path: "foo", screens: { Foe: { path: "foe", exact: !0 }, Bar: { path: "bar", exact: !0, screens: { Baz: { path: "baz", exact: !0 } } } } } } }, state = { routes: [ { name: "Foo", state: { routes: [ { name: "Bar", state: { routes: [{ name: "Baz", path }] } } ] } } ] }; expect(getStateFromPath(path, config)).toEqual(state), expect(getStateFromPath(getPathFromState(state, config), config)).toEqual(state); }); test("handles parse in nested object for second route depth and and path and parse in roots", () => { const path = "/baz", config = { screens: { Foo: { path: "foo/:id", parse: { id: Number }, stringify: { id: (id) => `id=${id}` }, screens: { Foe: "foe", Bar: { screens: { Baz: { path: "baz", exact: !0 } } } } } } }, state = { routes: [ { name: "Foo", state: { routes: [ { name: "Bar", state: { routes: [{ name: "Baz", path }] } } ] } } ] }; expect(getStateFromPath(path, config)).toEqual(state), expect(getStateFromPath(getPathFromState(state, config), config)).toEqual(state); }); test.skip("handles path at top level", () => { const path = "/foo/fruits/apple", config = { path: "foo", screens: { Foo: { screens: { Fruits: "fruits/:fruit" } } } }, state = { routes: [ { name: "Foo", state: { routes: [ { name: "Fruits", params: { fruit: "apple" }, path } ] } } ] }; expect(getStateFromPath(path, config)).toEqual(state), expect(getStateFromPath(getPathFromState(state, config), config)).toEqual(state); }); test("handles initialRouteName at top level", () => { const path = "/baz", config = { initialRouteName: "Boo", screens: { Foo: { screens: { Foe: "foe", Bar: { screens: { Baz: "baz" } } } } } }, state = { index: 1, routes: [ { name: "Boo" }, { name: "Foo", state: { routes: [ { name: "Bar", state: { routes: [{ name: "Baz", path }] } } ] } } ] }; expect(getStateFromPath(path, config)).toEqual(state), expect(getStateFromPath(getPathFromState(state, config), config)).toEqual(state); }); test("handles initialRouteName inside a screen", () => { const path = "/baz", config = { screens: { Foo: { initialRouteName: "Foe", screens: { Foe: "foe", Bar: { screens: { Baz: "baz" } } } } } }, state = { routes: [ { name: "Foo", state: { index: 1, routes: [ { name: "Foe" }, { name: "Bar", state: { routes: [{ name: "Baz", path }] } } ] } } ] }; expect(getStateFromPath(path, config)).toEqual(state), expect(getStateFromPath(getPathFromState(state, config), config)).toEqual(state); }); test("handles initialRouteName included in path", () => { const path = "/baz", config = { screens: { Foo: { initialRouteName: "Foe", screens: { Foe: { screens: { Baz: "baz" } }, Bar: "bar" } } } }, state = { routes: [ { name: "Foo", state: { routes: [ { name: "Foe", state: { routes: [{ name: "Baz", path }] } } ] } } ] }; expect(getStateFromPath(path, config)).toEqual(state), expect(getStateFromPath(getPathFromState(state, config), config)).toEqual(state); }); test.skip("handles two initialRouteNames", () => { const path = "/bar/sweet/apple/foe/bis/jane?answer=42&count=10&valid=true", config = { screens: { Bar: { path: "bar/:type/:fruit", screens: { Foo: { screens: { Foe: { path: "foe", screens: { Baz: { initialRouteName: "Bos", screens: { Bos: { path: "bos", exact: !0 }, Bis: { path: "bis/:author", stringify: { author: (author) => author.replace(/^\w/, (c) => c.toLowerCase()) }, parse: { author: (author) => author.replace(/^\w/, (c) => c.toUpperCase()), count: Number, valid: Boolean } } } } } } } } } } } }, state = { routes: [ { name: "Bar", params: { fruit: "apple", type: "sweet" }, state: { routes: [ { name: "Foo", state: { routes: [ { name: "Foe", state: { routes: [ { name: "Baz", state: { index: 1, routes: [ { name: "Bos" }, { name: "Bis", params: { answer: "42", author: "Jane", count: 10, valid: !0 }, path } ] } } ] } } ] } } ] } } ] }; expect(getStateFromPath(path, config)).toEqual(state), expect(getStateFromPath(getPathFromState(state, config), config)).toEqual(state); }); test.skip("accepts initialRouteName without config for it", () => { const path = "/bar/sweet/apple/foe/bis/jane?answer=42&count=10&valid=true", config = { screens: { Bar: { path: "bar/:type/:fruit", screens: { Foo: { screens: { Foe: { path: "foe", screens: { Baz: { initialRouteName: "Bas", screens: { Bos: { path: "bos", exact: !0 }, Bis: { path: "bis/:author", stringify: { author: (author) => author.replace(/^\w/, (c) => c.toLowerCase()) }, parse: { author: (author) => author.replace(/^\w/, (c) => c.toUpperCase()), count: Number, valid: Boolean } } } } } } } } } } } }, state = { routes: [ { name: "Bar", params: { fruit: "apple", type: "sweet" }, state: { routes: [ { name: "Foo", state: { routes: [ { name: "Foe", state: { routes: [ { name: "Baz", state: { index: 1, routes: [ { name: "Bas" }, { name: "Bis", params: { answer: "42", author: "Jane", count: 10, valid: !0 }, path } ] } } ] } } ] } } ] } } ] }; expect(getStateFromPath(path, config)).toEqual(state), expect(getStateFromPath(getPathFromState(state, config), config)).toEqual(state); }); test("returns undefined if no matching screen is present (top level path)", () => { expect(getStateFromPath("/foo/bar", { path: "qux", screens: { Foo: { screens: { Foe: "foo", Bar: { screens: { Baz: "bar" } } } } } })).toBeUndefined(); }); test("returns undefined if no matching screen is present", () => { expect(getStateFromPath("/baz", { screens: { Foo: { path: "foo", screens: { Foe: "foe", Bar: { screens: { Baz: "baz" } } } } } })).toBeUndefined(); }); test("returns undefined if path is empty and no matching screen is present", () => { expect(getStateFromPath("", { screens: { Foo: { screens: { Foe: "foe", Bar: { screens: { Baz: "baz" } } } } } })).toBeUndefined(); }); test.skip("returns matching screen if path is empty", () => { const config = { screens: { Foo: { screens: { Foe: "foe", Bar: { screens: { Qux: "", Baz: "baz" } } } } } }, state = { routes: [ { name: "Foo", state: { routes: [ { name: "Bar", state: { routes: [{ name: "Qux", path: "" }] } } ] } } ] }; expect(getStateFromPath("", config)).toEqual(state), expect(getStateFromPath(getPathFromState(state, config), config)).toEqual( changePath(state, "") ); }); test.skip("returns matching screen if path is only slash", () => { const config = { screens: { Foo: { screens: { Foe: "foe", Bar: { screens: { Qux: "", Baz: "baz" } } } } } }, state = { routes: [ { name: "Foo", state: { routes: [ { name: "Bar", state: { routes: [{ name: "Qux", path: "" }] } } ] } } ] }; expect(getStateFromPath("/", config)).toEqual(state), expect(getStateFromPath(getPathFromState(state, config), config)).toEqual( changePath(state, "") ); }); test("returns matching screen with params if path is empty", () => { const path = "?foo=42", config = { screens: { Foo: { screens: { Foe: "foe", Bar: { screens: { Qux: { path: "", parse: { foo: Number } }, Baz: "baz" } } } } } }, state = { routes: [ { name: "Foo", state: { routes: [ { name: "Bar", state: { routes: [{ name: "Qux", params: { foo: 42 }, path }] } } ] } } ] }; expect(getStateFromPath(path, config)).toEqual(state), expect(getStateFromPath(getPathFromState(state, config), config)).toEqual( changePath(state, "/?foo=42") ); }); test("doesn't match nested screen if path is empty", () => { expect(getStateFromPath("", { screens: { Foo: { screens: { Foe: "foe", Bar: { path: "bar", screens: { Qux: { path: "", parse: { foo: Number } } } } } } } })).toBeUndefined(); }); test.skip("chooses more exhaustive pattern", () => { const path = "/foo/5", config = { screens: { Foe: { path: "/", initialRouteName: "Foo", screens: { Foo: "foo", Bis: { path: "foo/:id", parse: { id: Number } } } } } }, state = { routes: [ { name: "Foe", state: { index: 1, routes: [ { name: "Foo" }, { name: "Bis", params: { id: 5 }, path } ] } } ] }; expect(getStateFromPath(path, config)).toEqual(state), expect(getStateFromPath(getPathFromState(state, config), config)).toEqual(state); }); test("handles same paths beginnings", () => { const path = "/foos", config = { screens: { Foe: { path: "/", initialRouteName: "Foo", screens: { Foo: "foo", Bis: { path: "foos" } } } } }, state = { routes: [ { name: "Foe", state: { index: 1, routes: [ { name: "Foo" }, { name: "Bis", path } ] } } ] }; expect(getStateFromPath(path, config)).toEqual(state), expect(getStateFromPath(getPathFromState(state, config), config)).toEqual(state); }); test.skip("handles same paths beginnings with params", () => { const path = "/foos/5", config = { screens: { Foe: { path: "/", initialRouteName: "Foo", screens: { Foo: "foo", Bis: { path: "foos/:id", parse: { id: Number } } } } } }, state = { routes: [ { name: "Foe", state: { index: 1, routes: [ { name: "Foo" }, { name: "Bis", params: { id: 5 }, path } ] } } ] }; expect(getStateFromPath(path, config)).toEqual(state), expect(getStateFromPath(getPathFromState(state, config), config)).toEqual(state); }); test.skip("handles not taking path with too many segments", () => { const path = "/foos/5", config = { screens: { Foe: { path: "/", initialRouteName: "Foo", screens: { Foo: "foo", Bis: { path: "foos/:id", parse: { id: Number } }, Bas: { path: "foos/:id/:nip", parse: { id: Number, pwd: Number } } } } } }, state = { routes: [ { name: "Foe", state: { index: 1, routes: [ { name: "Foo" }, { name: "Bis", params: { id: 5 }, path } ] } } ] }; expect(getStateFromPath(path, config)).toEqual(state), expect(getStateFromPath(getPathFromState(state, config), config)).toEqual(state); }); test.skip("handles differently ordered params v1", () => { const path = "/foos/5/res/20", config = { screens: { Foe: { path: "/", initialRouteName: "Foo", screens: { Foo: "foo", Bis: { path: "foos/:id", parse: { id: Number } }, Bas: { path: "foos/:id/res/:pwd", parse: { id: Number, pwd: Number } } } } } }, state = { routes: [ { name: "Foe", state: { index: 1, routes: [ { name: "Foo" }, { name: "Bas", params: { id: 5, pwd: 20 }, path } ] } } ] }; expect(getStateFromPath(path, config)).toEqual(state), expect(getStateFromPath(getPathFromState(state, config), config)).toEqual(state); }); test.skip("handles differently ordered params v2", () => { const path = "/5/20/foos/res", config = { screens: { Foe: { path: "/", initialRouteName: "Foo", screens: { Foo: "foo", Bis: { path: "foos/:id", parse: { id: Number } }, Bas: { path: ":id/:pwd/foos/res", parse: { id: Number, pwd: Number } } } } } }, state = { routes: [ { name: "Foe", state: { index: 1, routes: [ { name: "Foo" }, { name: "Bas", params: { id: 5, pwd: 20 }, path } ] } } ] }; expect(getStateFromPath(path, config)).toEqual(state), expect(getStateFromPath(getPathFromState(state, config), config)).toEqual(state); }); test.skip("handles differently ordered params v3", () => { const path = "/foos/5/20/res", config = { screens: { Foe: { path: "/", initialRouteName: "Foo", screens: { Foo: "foo", Bis: { path: "foos/:id", parse: { id: Number } }, Bas: { path: "foos/:id/:pwd/res", parse: { id: Number, pwd: Number } } } } } }, state = { routes: [ { name: "Foe", state: { index: 1, routes: [ { name: "Foo" }, { name: "Bas", params: { id: 5, pwd: 20 }, path } ] } } ] }; expect(getStateFromPath(path, config)).toEqual(state), expect(getStateFromPath(getPathFromState(state, config), config)).toEqual(state); }); test.skip("handles differently ordered params v4", () => { const path = "5/foos/res/20", config = { screens: { Foe: { path: "/", initialRouteName: "Foo", screens: { Foo: "foo", Bis: { path: "foos/:id", parse: { id: Number } }, Bas: { path: ":id/foos/res/:pwd", parse: { id: Number, pwd: Number } } } } } }, state = { routes: [ { name: "Foe", state: { index: 1, routes: [ { name: "Foo" }, { name: "Bas", params: { id: 5, pwd: 20 }, path } ] } } ] }; expect(getStateFromPath(path, config)).toEqual(state), expect(getStateFromPath(getPathFromState(state, config), config)).toEqual( changePath(state, "/5/foos/res/20") ); }); test.skip("handles simple optional params", () => { const path = "/foos/5", config = { screens: { Foe: { path: "/", initialRouteName: "Foo", screens: { Foo: "foo", Bis: { path: "foo/:id", parse: { id: Number } }, Bas: { path: "foos/:id/:nip?", parse: { id: Number, nip: Number } } } } } }, state = { routes: [ { name: "Foe", state: { index: 1, routes: [ { name: "Foo" }, { name: "Bas", params: { id: 5 }, path } ] } } ] }; expect(getStateFromPath(path, config)).toEqual(state), expect(getStateFromPath(getPathFromState(state, config), config)).toEqual(state); }); test.skip("handle 2 optional params at the end v1", () => { const path = "/foos/5", config = { screens: { Foe: { path: "/", initialRouteName: "Foo", screens: { Foo: "foo", Bis: { path: "foo/:id", parse: { id: Number } }, Bas: { path: "foos/:id/:nip?/:pwd?", parse: { id: Number, nip: Number } } } } } }, state = { routes: [ { name: "Foe", state: { index: 1, routes: [ { name: "Foo" }, { name: "Bas", params: { id: 5 }, path } ] } } ] }; expect(getStateFromPath(path, config)).toEqual(state), expect(getStateFromPath(getPathFromState(state, config), config)).toEqual(state); }); test.skip("handle 2 optional params at the end v2", () => { const path = "/foos/5/10", config = { screens: { Foe: { path: "/", initialRouteName: "Foo", screens: { Foo: "foo", Bis: { path: "foo/:id", parse: { id: Number } }, Bas: { path: "foos/:id/:nip?/:pwd?", parse: { id: Number, nip: Number } } } } } }, state = { routes: [ { name: "Foe", state: { index: 1, routes: [ { name: "Foo" }, { name: "Bas", params: { id: 5, nip: 10 }, path } ] } } ] }; expect(getStateFromPath(path, config)).toEqual(state), expect(getStateFromPath(getPathFromState(state, config), config)).toEqual(state); }); test.skip("handle 2 optional params at the end v3", () => { const path = "/foos/5/10/15", config = { screens: { Foe: { path: "/", initialRouteName: "Foo", screens: { Foo: "foo", Bis: { path: "foo/:id", parse: { id: Number } }, Bas: { path: "foos/:id/:nip?/:pwd?", parse: { id: Number, nip: Number, pwd: Number } } } } } }, state = { routes: [ { name: "Foe", state: { index: 1, routes: [ { name: "Foo" }, { name: "Bas", params: { id: 5, nip: 10, pwd: 15 }, path } ] } } ] }; expect(getStateFromPath(path, config)).toEqual(state), expect(getStateFromPath(getPathFromState(state, config), config)).toEqual(state); }); test.skip("handle optional params in the middle v1", () => { const path = "/foos/5/10", config = { screens: { Foe: { path: "/", initialRouteName: "Foo", screens: { Foo: "foo", Bis: { path: "foo/:id", parse: { id: Number } }, Bas: { path: "foos/:id/:nip?/:pwd", parse: { id: Number, nip: Number, pwd: Number } } } } } }, state = { routes: [ { name: "Foe", state: { index: 1, routes: [ { name: "Foo" }, { name: "Bas", params: { id: 5, pwd: 10 }, path } ] } } ] }; expect(getStateFromPath(path, config)).toEqual(state), expect(getStateFromPath(getPathFromState(state, config), config)).toEqual(state); }); test.skip("handle optional params in the middle v2", () => { const path = "/foos/5/10/15", config = { screens: { Foe: { path: "/", initialRouteName: "Foo", screens: { Foo: "foo", Bis: { path: "foo/:id", parse: { id: Number } }, Bas: { path: "foos/:id/:nip?/:pwd", parse: { id: Number, nip: Number, pwd: Number } } } } } }, state = { routes: [ { name: "Foe", state: { index: 1, routes: [ { name: "Foo" }, { name: "Bas", params: { id: 5, nip: 10, pwd: 15 }, path } ] } } ] }; expect(getStateFromPath(path, config)).toEqual(state), expect(getStateFromPath(getPathFromState(state, config), config)).toEqual(state); }); test.skip("handle optional params in the middle v3", () => { const path = "/foos/5/10/15", config = { screens: { Foe: { path: "/", initialRouteName: "Foo", screens: { Foo: "foo", Bis: { path: "foo/:id", parse: { id: Number } }, Bas: { path: "foos/:id/:nip?/:pwd/:smh", parse: { id: Number, nip: Number, pwd: Number, smh: Number } } } } } }, state = { routes: [ { name: "Foe", state: { index: 1, routes: [ { name: "Foo" }, { name: "Bas", params: { id: 5, pwd: 10, smh: 15 }, path } ] } } ] }; expect(getStateFromPath(path, config)).toEqual(state), expect(getStateFromPath(getPathFromState(state, config), config)).toEqual(state); }); test.skip("handle optional params in the middle v4", () => { const path = "/foos/5/10", config = { screens: { Foe: { path: "/", initialRouteName: "Foo", screens: { Foo: "foo", Bis: { path: "foo/:id", parse: { id: Number } }, Bas: { path: "foos/:nip?/:pwd/:smh?/:id", parse: { id: Number, nip: Number, pwd: Number, smh: Number } } } } } }, state = { routes: [ { name: "Foe", state: { index: 1, routes: [ { name: "Foo" }, { name: "Bas", params: { pwd: 5, id: 10 }, path } ] } } ] }; expect(getStateFromPath(path, config)).toEqual(state), expect(getStateFromPath(getPathFromState(state, config), config)).toEqual(state); }); test.skip("handle optional params in the middle v5", () => { const path = "/foos/5/10/15", config = { screens: { Foe: { path: "/", initialRouteName: "Foo", screens: { Foo: "foo", Bis: { path: "foo/:id", parse: { id: Number } }, Bas: { path: "foos/:nip?/:pwd/:smh?/:id", parse: { id: Number, nip: Number, pwd: Number, smh: Number } } } } } }, state = { routes: [ { name: "Foe", state: { index: 1, routes: [ { name: "Foo" }, { name: "Bas", params: { nip: 5, pwd: 10, id: 15 }, path } ] } } ] }; expect(getStateFromPath(path, config)).toEqual(state), expect(getStateFromPath(getPathFromState(state, config), config)).toEqual(state); }); test.skip("handle optional params in the beginning v1", () => { const path = "5/10/foos/15", config = { screens: { Foe: { path: "/", initialRouteName: "Foo", screens: { Foo: "foo", Bis: { path: "foo/:id", parse: { id: Number } }, Bas: { path: ":nip?/:pwd/foos/:smh?/:id", parse: { id: Number, nip: Number, pwd: Number, smh: Number } } } } } }, state = { routes: [ { name: "Foe", state: { index: 1, routes: [ { name: "Foo" }, { name: "Bas", params: { nip: 5, pwd: 10, id: 15 }, path } ] } } ] }; expect(getStateFromPath(path, config)).toEqual(state), expect(getStateFromPath(getPathFromState(state, config), config)).toEqual( changePath(state, "/5/10/foos/15") ); }); test.skip("handle optional params in the beginning v2", () => { const path = "5/10/foos/15", config = { screens: { Foe: { path: "/", initialRouteName: "Foo", screens: { Foo: "foo", Bis: { path: "foo/:id", parse: { id: Number } }, Bas: { path: ":nip?/:smh?/:pwd/foos/:id", parse: { id: Number, nip: Number, pwd: Number, smh: Number } } } } } }, state = { routes: [ { name: "Foe", state: { index: 1, routes: [ { name: "Foo" }, { name: "Bas", params: { nip: 5, pwd: 10, id: 15 }, path } ] } } ] }; expect(getStateFromPath(path, config)).toEqual(state), expect(getStateFromPath(getPathFromState(state, config), config)).toEqual( changePath(state, "/5/10/foos/15") ); }); test.skip("merges parent patterns if needed", () => { const path = "foo/42/baz/babel", config = { screens: { Foo: { path: "foo/:bar", parse: { bar: Number }, screens: { Baz: "baz/:qux" } } } }, state = { routes: [ { name: "Foo", params: { bar: 42 }, state: { routes: [ { name: "Baz", params: { qux: "babel" }, path } ] } } ] }; expect(getStateFromPath(path, config)).toEqual(state), expect(getStateFromPath(getPathFromState(state, config), config)).toEqual( changePath(state, "/foo/42/baz/babel") ); }); test.skip("ignores extra slashes in the pattern", () => { const path = "/bar/42", config = { screens: { Foo: { screens: { Bar: { path: "/bar//:id/" } } } } }, state = { routes: [ { name: "Foo", state: { routes: [ { name: "Bar", params: { id: "42" }, path } ] } } ] }; expect(getStateFromPath(path, config)).toEqual(state), expect(getStateFromPath(getPathFromState(state, config), config)).toEqual(state); }); test.skip("matches wildcard patterns at root", () => { const path = "/test/bar/42/whatever", config = { screens: { 404: "*", Foo: { screens: { Bar: { path: "/bar/:id/" } } } } }, state = { routes: [{ name: "404", path }] }; expect(getStateFromPath(path, config)).toEqual(state), expect(getStateFromPath(getPathFromState(state, config), config)).toEqual( changePath(state, "/404") ); }); test.skip("matches wildcard patterns at nested level", () => { const path = "/bar/42/whatever/baz/initt", config = { screens: { Foo: { screens: { Bar: { path: "/bar/:id/", screens: { 404: "*" } } } } } }, state = { routes: [ { name: "Foo", state: { routes: [ { name: "Bar", params: { id: "42" }, state: { routes: [{ name: "404", path }] } } ] } } ] }; expect(getStateFromPath(path, config)).toEqual(state), expect(getStateFromPath(getPathFromState(state, config), config)).toEqual( changePath(state, "/bar/42/404") ); }); test.skip("matches wildcard patterns at nested level with exact", () => { const path = "/whatever", config = { screens: { Foo: { screens: { Bar: { path: "/bar/:id/", screens: { 404: { path: "*", exact: !0 } } }, Baz: {} } } } }, state = { routes: [ { name: "Foo", state: { routes: [ { name: "Bar", state: { routes: [{ name: "404", path }] } } ] } } ] }; expect(getStateFromPath(path, config)).toEqual(state), expect(getStateFromPath(getPathFromState(state, config), config)).toEqual( changePath(state, "/404") ); }); test.skip("tries to match wildcard patterns at the end", () => { const path = "/bar/42/test", config = { screens: { Foo: { screens: { Bar: { path: "/bar/:id/", screens: { 404: "*", UserProfile: ":userSlug", Test: "test" } } } } } }, state = { routes: [ { name: "Foo", state: { routes: [ { name: "Bar", params: { id: "42" }, state: { routes: [{ name: "Test", path }] } } ] } } ] }; expect(getStateFromPath(path, config)).toEqual(state), expect(getStateFromPath(getPathFromState(state, config), config)).toEqual(state); }); test.skip("uses nearest parent wildcard match for unmatched paths", () => { const path = "/bar/42/baz/test", config = { screens: { Foo: { screens: { Bar: { path: "/bar/:id/", screens: { Baz: "baz" } }, 404: "*" } } } }, state = { routes: [ { name: "Foo", state: { routes: [{ name: "404", path }] } } ] }; expect(getStateFromPath(path, config)).toEqual(state), expect(getStateFromPath(getPathFromState(state, config), config)).toEqual( changePath(state, "/404") ); }); test.skip("matches screen with overlapping initial path and wildcard", () => { const path = "/bar/42/baz/test/whatever", config = { screens: { Foo: { screens: { Bar: { path: "/bar/:id/", screens: { Baz: "baz" } }, Baz: "/bar/:id/*" } } } }, state = { routes: [ { name: "Foo", state: { routes: [{ name: "Baz", params: { id: "42" }, path }] } } ] }; expect(getStateFromPath(path, config)).toEqual(state), expect(getStateFromPath(getPathFromState(state, config), config)).toEqual( changePath(state, "/bar/42/Baz") ); }); test("throws if two screens map to the same pattern", () => { const path = "/bar/42/baz/test"; expect( () => getStateFromPath(path, { screens: { Foo: { screens: { Bar: { path: "/bar/:id/", screens: { Baz: "baz" } }, Bax: "/bar/:id/baz" } } } }) ).toThrow( "Found conflicting screens with the same pattern. The pattern 'bar/:id/baz' resolves to both 'Foo > Bax' and 'Foo > Bar > Baz'. Patterns must be unique and cannot resolve to more than one screen." ), expect( () => getStateFromPath(path, { screens: { Foo: { screens: { Bar: { path: "/bar/:id/", screens: { Baz: "" } } } } } }) ).not.toThrow(); }); test("correctly applies initialRouteName for config with similar rou