UNPKG

one

Version:

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

2,707 lines 62.3 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 route names", () => {
  const path = "/weekly-earnings", config = {
    screens: {
      RootTabs: {
        screens: {
          HomeTab: {
            screens: {
              Home: "",
              WeeklyEarnings: "weekly-earnings",
              EventDetails: "event-details/:eventId"
            }
          },
          EarningsTab: {
            initialRouteName: "Earnings",
            path: "earnings",
            screens: {
              Earnings: "",
              WeeklyEarnings: "weekly-earnings"
            }
          }
        }
      }
    }
  }, state = {
    routes: [
      {
        name: "RootTabs",
        state: {
          routes: [
            {
              name: "HomeTab",
              state: {
                routes: [
                  {
                    name: "WeeklyEarnings",
                    path
                  }
                ]
              }
            }
          ]
        }
      }
    ]
  };
  expect(getStateFromPath(path, config)).toEqual(state), expect(
    getStateFromPath(getPathFromState(state, config), config)
  ).toEqual(state);
});
test("correctly applies initialRouteName for config with similar route names v2", () => {
  const path = "/earnings/weekly-earnings", config = {
    screens: {
      RootTabs: {
        screens: {
          HomeTab: {
            initialRouteName: "Home",
            screens: {
              Home: "",
              WeeklyEarnings: "weekly-earnings"
            }
          },
          EarningsTab: {
            initialRouteName: "Earnings",
            path: "earnings",
            screens: {
              Earnings: "",
              WeeklyEarnings: "weekly-earnings"
            }
          }
        }
      }
    }
  }, state = {
    routes: [
      {
        name: "RootTabs",
        state: {
          routes: [
            {
              name: "EarningsTab",
              state: {
                index: 1,
                routes: [
                  {
                    name: "Earnings"
                  },
                  {
                    name: "WeeklyEarnings",
                    path
                  }
                ]
              }
            }
          ]
        }
      }
    ]
  };
  expect(getStateFromPath(path, config)).toEqual(state), expect(
    getStateFromPath(getPathFromState(state, config), config)
  ).toEqual(state);
});
test.skip("throws when invalid properties are specified in the config", () => {
  expect(
    () => getStateFromPath("", {
      path: 42,
      Foo: "foo",
      Bar: {
        path: "bar"
      }
    })
  ).toThrowErrorMatchingInlineSnapshot(`
    "Found invalid properties in the configuration:
    - path (expected 'string', got 'number')
    - Foo (extraneous)
    - Bar (extraneous)

    You can only specify the following properties:
    - path (string)
    - initialRouteName (string)
    - screens (object)

    If you want to specify configuration for screens, you need to specify them under a 'screens' property.

    See https://reactnavigation.org/docs/configuring-links for more details on how to specify a linking configuration."
  `), expect(
    () => getStateFromPath("", {
      screens: {
        Foo: "foo",
        Bar: {
          path: "bar"
        },
        Baz: {
          Qux: {
            path: "qux"
          }
        }
      }
    })
  ).toThrowErrorMatchingInlineSnapshot(`
"Found invalid properties in the configuration:
- Qux (extraneous)

You can only specify the following properties:
- path (string)
- initialRouteName (string)
- screens (object)
- alias (array)
- exact (boolean)
- stringify (object)
- parse (object)

If you want to specify configuration for screens, you need to specify them under a 'screens' property.

See https://reactnavigation.org/docs/configuring-links for more details on how to specify a linking configuration."
`), expect(
    () => getStateFromPath("", {
      path: "foo/:id"
    })
  ).toThrowErrorMatchingInlineSnapshot(
    `"Found invalid path 'foo/:id'. The 'path' in the top-level configuration cannot contain patterns for params."`
  );
});
test.skip("encodes special characters in params", () => {
  const paramWithValidSymbols = "User09-A_Z~!$&'()*+,;=:@__", invalidSymbols = "#?[]{}%<>||", queryString = "user#email@gmail.com=2&4", path = `users/id/${paramWithValidSymbols}${encodeURIComponent(
    invalidSymbols
  )}?query=${encodeURIComponent(queryString)}`, config = {
    path: "users",
    screens: {
      Users: {
        screens: {
          User: "id/:id"
        }
      }
    }
  }, state = {
    routes: [
      {
        name: "Users",
        state: {
          routes: [
            {
              name: "User",
              params: {
                id: `${paramWithValidSymbols}${invalidSymbols}`,
                query: queryString
              }
            }
          ]
        }
      }
    ]
  };
  expect(getPathFromState(state, config)).toBe(`/${path}`), expect(getPathFromState(getStateFromPath(path, config), config)).toBe(
    `/${path}`
  );
});
test.skip("resolves nested path params with same name to correct screen", () => {
  const path = "/foo/42/bar/43", config = {
    initialRouteName: "Foo",
    screens: {
      Foo: {
        path: "foo/:id",
        screens: {
          Bar: {
            path: "bar/:id"
          }
        }
      }
    }
  }, state = {
    routes: [
      {
        name: "Foo",
        params: { id: "42" },
        state: {
          routes: [
            {
              name: "Bar",
              params: { id: "43" },
              path
            }
          ]
        }
      }
    ]
  };
  expect(getStateFromPath(path, config)).toEqual(state);
});
test("parses / same as empty string", () => {
  const config = {
    screens: {
      Foo: {
        path: "/"
      },
      Bar: {
        path: "bar"
      }
    }
  };
  expect(getStateFromPath("/", config)).toEqual(
    getStateFromPath("", config)
  );
});
test.skip("matches regexp patterns when provided", () => {
  const config = {
    screens: {
      Foo: {
        path: "foo/:id(\\d+)",
        parse: {
          id: Number
        }
      },
      Bar: {
        path: "foo/:id([a-z]+)"
      },
      Baz: {
        path: "foo/:id(\\d+)/:name([a-z]+)"
      },
      Qux: {
        path: "foo/:id(@[a-z]+)",
        parse: {
          id: (id) => id.slice(1)
        }
      },
      Quy: {
        path: "foo/bar/:category"
      },
      Quz: {
        path: "foo/bar/:special([a-z]+)"
      },
      Quu: {
        path: "foo/bar/baz"
      },
      NotFound: {
        path: "foo/bar/*"
      }
    }
  };
  expect(getStateFromPath("foo/42", config)).toEqual({
    routes: [
      {
        name: "Foo",
        params: { id: 42 },
        path: "foo/42"
      }
    ]
  }), expect(getStateFromPath("foo/bar", config)).toEqual({
    routes: [
      {
        name: "Bar",
        params: { id: "bar" },
        path: "foo/bar"
      }
    ]
  }), expect(getStateFromPath("foo/42/bar", config)).toEqual({
    routes: [
      {
        name: "Baz",
        params: { id: "42", name: "bar" },
        path: "foo/42/bar"
      }
    ]
  }), expect(getStateFromPath("foo/@bar", config)).toEqual({
    routes: [
      {
        name: "Qux",
        params: { id: "bar" },
        path: "foo/@bar"
      }
    ]
  }), expect(getStateFromPath("foo/@bar", config)).toEqual({
    routes: [
      {
        name: "Qux",
        params: { id: "bar" },
        path: "foo/@bar"
      }
    ]
  }), expect(getStateFromPath("foo/42a", config)).toBeUndefined(), expect(getStateFromPath("foo/bar/123", config)).toEqual({
    routes: [
      {
        name: "Quy",
        params: { category: "123" },
        path: "foo/bar/123"
      }
    ]
  }), expect(getStateFromPath("foo/bar/test", config)).toEqual({
    routes: [
      {
        name: "Quz",
        params: { special: "test" },
        path: "foo/bar/test"
      }
    ]
  }), expect(getStateFromPath("foo/bar/baz", config)).toEqual({
    routes: [
      {
        name: "Quu",
        path: "foo/bar/baz"
      }
    ]
  }), expect(getStateFromPath("foo/bar/hello/world", config)).toEqual({
    routes: [{ name: "NotFound", path: "foo/bar/hello/world" }]
  });
});
test("regexp pattern doesn't match slash", () => {
  const config = {
    screens: {
      Foo: {
        path: "foo/:id([a-z]+\\/)"
      }
    }
  };
  expect(getStateFromPath("foo/bar/", config)).toBeUndefined(), expect(getStateFromPath("foo/bar/baz", config)).toBeUndefined(), expect(getStateFromPath("foo/bar/baz/qux", config)).toBeUndefined();
});
test.skip("handles alias for paths", () => {
  const config = {
    screens: {
      Foo: {
        path: "foo",
        alias: ["first"],
        screens: {
          Baz: {
            path: "baz/:id?",
            parse: {
              id: (value) => value.replace(/@/, "")
            },
            alias: [
              {
                path: "second/:id",
                exact: !0
              },
              "third",
              {
                path: "fourth/:id",
                parse: {
                  id: (value) => value.replace(/\$/, "")
                }
              }
            ]
          },
          Qux: {
            path: "qux/:id"
          }
        }
      }
    }
  };
  expect(getStateFromPath("foo", config)).toEqual({
    routes: [{ name: "Foo", path: "foo" }]
  }), expect(getPathFromState(getStateFromPath("foo", config), config)).toBe(
    "/foo"
  ), expect(getStateFromPath("first", config)).toEqual({
    routes: [{ name: "Foo", path: "first" }]
  }), expect(
    getPathFromState(getStateFromPath("first", config), config)
  ).toBe("/foo"), expect(getStateFromPath("foo/baz/@$test", config)).toEqual({
    routes: [
      {
        name: "Foo",
        state: {
          routes: [
            {
              name: "Baz",
              params: { id: "$test" },
              path: "foo/baz/@$test"
            }
          ]
        }
      }
    ]
  }), expect(
    getPathFromState(getStateFromPath("foo/baz/@$test", config), config)
  ).toBe("/foo/baz/$test"), expect(getStateFromPath("second/42", config)).toEqual({
    routes: [
      {
        name: "Foo",
        state: {
          routes: [
            {
              name: "Baz",
              params: { id: "42" },
              path: "second/42"
            }
          ]
        }
      }
    ]
  }), expect(
    getPathFromState(getStateFromPath("second/42", config), config)
  ).toBe("/foo/baz/42"), expect(getStateFromPath("foo/third", config)).toEqual({
    routes: [
      {
        name: "Foo",
        state: {
          routes: [
            {
              name: "Baz",
              path: "foo/third"
            }
          ]
        }
      }
    ]
  }), expect(
    getPathFromState(getStateFromPath("foo/third", config), config)
  ).toBe("/foo/baz"), expect(getStateFromPath("foo/fourth/@$test", config)).toEqual({
    routes: [
      {
        name: "Foo",
        state: {
          routes: [
            {
              name: "Baz",
              params: { id: "@test" },
              path: "foo/fourth/@$test"
            }
          ]
        }
      }
    ]
  }), expect(
    getPathFromState(
      getStateFromPath("foo/fourth/@$test", config),
      config
    )
  ).toBe("/foo/baz/@test"), expect(getStateFromPath("foo/qux/42", config)).toEqual({
    routes: [
      {
        name: "Foo",
        state: {
          routes: [
            {
              name: "Qux",
              params: { id: "42" },
              path: "foo/qux/42"
            }
          ]
        }
      }
    ]
  }), expect(
    getPathFromState(getStateFromPath("foo/qux/42", config), config)
  ).toBe("/foo/qux/42");
});
test.skip("throws if screen has alias but no path", () => {
  expect(
    () => getStateFromPath("", {
      screens: {
        Foo: {
          alias: ["bar"]
        }
      }
    })
  ).toThrow(
    "Screen 'Foo' doesn't specify a 'path'. A 'path' needs to be specified in order to use 'alias'."
  );
});
//# sourceMappingURL=getStateFromPath.test.js.map