UNPKG

router-dom

Version:

A lightweight router for everyone

285 lines (254 loc) 10.3 kB
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Router Tests</title> <script type="module"> import { hydro, $ } from "hydro-js"; import { runTests } from "@web/test-runner-mocha"; import { expect } from "@esm-bundle/chai"; import Router from "../../dist/router.js"; const sleep = (time) => new Promise((resolve) => setTimeout(resolve, time)); runTests(() => { describe("router", () => { let router; beforeEach(async () => { router = new Router([ { path: "/", element: "<h1>Home</h1>", leave(params) { window.leaveHome = params; }, beforeEnter(params) { window.beforeEnterHome = params; }, afterEnter(params) { window.afterEnterHome = params; }, }, { path: "/a(\\?)?(.*)", element: "<h1>a</h1>", leave(params) { window.leaveA = params; }, beforeEnter(params) { window.beforeEnterA = params; }, afterEnter(params) { window.afterEnterA = params; }, }, { path: "/b/:id?", element: "<h1>b</h1>", leave(params) { window.leaveB = params; }, beforeEnter(params) { window.beforeEnterB = params; }, afterEnter(params) { window.afterEnterB = params; }, }, ]); router.go("/"); await sleep(50); delete window.leaveHome; delete window.leaveA; delete window.leaveB; delete window.beforeEnterHome; delete window.beforeEnterA; delete window.beforeEnterB; delete window.afterEnterHome; delete window.afterEnterA; delete window.afterEnterB; }); it("applies to the correct elements", () => { expect($("#home").getAttribute("href").startsWith("http")).to.be .false; expect($("#other").getAttribute("href").startsWith("http")).to.be .true; }); it("goes to the correct route when clicking on an element", () => { $("#home").click(); expect(location.pathname + location.search).to.equal("/"); $("#a").click(); expect(location.pathname + location.search).to.equal("/a"); $("#b").click(); expect(location.pathname + location.search).to.equal("/b"); $("#home").click(); expect(location.pathname + location.search).to.equal("/"); }); it("goes to the correct route when clicking on an element - with params", () => { $("#param").click(); expect(location.pathname).to.equal("/a"); expect(location.search).to.equal("?q=testing"); }); it("goes to the correct route when clicking on an element (API)", () => { router.go("/a?q=testing2"); expect(location.pathname).to.equal("/a"); expect(location.search).to.equal("?q=testing2"); }); it("goes to the correct route when clicking on an element - with params (API)", () => { router.go("/b", {}, "?q=testing3"); expect(location.pathname).to.equal("/b"); expect(location.search).to.equal("?q=testing3"); }); it("goes to the correct route (param with spaces) and returns the correct params", () => { router.go("/b?q=test value"); expect(location.pathname).to.equal("/b"); expect(location.search).to.equal("?q=test%20value"); expect(Router.getParams()).to.deep.equal({ q: "test value" }); }); it("sends data via API", () => { const data = { awesome: 42 }; router.go("/a", data); expect(history.state).to.deep.equal(data); }); it("sends data via element", () => { hydro.data = { awesome: 42 }; $("#data").click(); expect(history.state).to.deep.equal(hydro.data); }); it("renders into data-outlet", async () => { $("#a").click(); await sleep(50); expect($("[data-outlet]").textContent).to.include("a"); router.go("/b", data); await sleep(50); expect($("[data-outlet]").textContent).to.include("b"); }); it("does not navigate when route is the same", async () => { const props = { from: "/", to: "/a" }; $("#a").click(); await sleep(50); expect(window.beforeEnterA).to.deep.equal(props); delete window.beforeEnterA; $("#a").click(); await sleep(50); expect(window.beforeEnterA).to.be.undefined; $("#param").click(); await sleep(50); expect(window.beforeEnterA).to.not.be.undefined; }); it("calls the lifecycle hooks when navigating via API", async () => { const props = { from: "/", to: "/a" }; router.go("/a"); await sleep(50); expect(window.leaveHome).to.deep.equal(props); expect(window.beforeEnterA).to.deep.equal(props); expect(window.afterEnterA).to.deep.equal(props); expect(window.leaveA).to.be.undefined; expect(window.leaveB).to.be.undefined; expect(window.beforeEnterHome).to.be.undefined; expect(window.beforeEnterB).to.be.undefined; expect(window.afterEnterHome).to.be.undefined; expect(window.afterEnterB).to.be.undefined; }); it("calls the lifecycle hooks when navigating via click", async () => { const props = { from: "/", to: "/b/4", params: { id: "4" } }; $("#id").click(); await sleep(50); expect(window.leaveHome).to.deep.equal(props); expect(window.beforeEnterB).to.deep.equal(props); expect(window.afterEnterB).to.deep.equal(props); expect(window.leaveA).to.be.undefined; expect(window.leaveB).to.be.undefined; expect(window.beforeEnterHome).to.be.undefined; expect(window.beforeEnterA).to.be.undefined; expect(window.afterEnterHome).to.be.undefined; expect(window.afterEnterA).to.be.undefined; }); it("calls the lifecycle hooks when navigating via browser API", async () => { const props = { from: "/", to: "/b/4", params: { id: "4" } }; history.back(); await sleep(50); expect(window.leaveHome).to.deep.equal(props); expect(window.beforeEnterB).to.deep.equal(props); expect(window.afterEnterB).to.deep.equal(props); expect(window.leaveA).to.be.undefined; expect(window.leaveB).to.be.undefined; expect(window.beforeEnterHome).to.be.undefined; expect(window.beforeEnterA).to.be.undefined; expect(window.afterEnterHome).to.be.undefined; expect(window.afterEnterA).to.be.undefined; }); it("uses the errorHandler", async () => { router = new Router( [ { path: "/", leave() { throw "Route Error"; }, }, { path: "/a", }, ], { errorHandler(err) { window.err = err; }, } ); $("#a").click(); await sleep(50); expect(window.err).to.equal("Route Error"); delete window.err; }); describe("passes params and state when using the lifecycle hooks", () => { it("uses state and data - click", async () => { const props = { from: "/", to: "/a?q=testing", params: { q: "testing" }, state: { awesome: 42 }, }; $("#data").click(); await sleep(50); expect(window.leaveHome).to.deep.equal(props); }); it("uses state and data - API", async () => { const props = { from: "/", to: "/a?q=testing", params: { q: "testing" }, state: { awesome: 42 }, }; router.go("/a?q=testing", { awesome: 42 }); await sleep(50); expect(window.leaveHome).to.deep.equal(props); }); it("uses state and data - API - param", async () => { const props = { from: "/", to: "/a?q=testing", params: { q: "testing" }, state: { awesome: 42 }, }; router.go("/a", { awesome: 42 }, "?q=testing"); await sleep(50); expect(window.leaveHome).to.deep.equal(props); }); }); }); }); </script> </head> <body> <a id="home" href="/">Home</a> <a id="a" href="/a">a</a> <a id="b" href="/b">b</a> <a id="id" href="/b/4">b</a> <a id="other" href="https://krutsch.netlify.app">Page</a> <a id="param" href="/a?q=testing">a</a> <a id="data" href="/a?q=testing" data="data">a</a> <div data-outlet></div> </body> </html>