[REF] router: add TestRouter and improve tests

This commit is contained in:
Géry Debongnie
2019-07-25 23:17:34 +02:00
parent bb46346767
commit bf705fcd99
4 changed files with 74 additions and 20 deletions
+6 -2
View File
@@ -60,7 +60,8 @@ export class Router {
this.checkRoute(); this.checkRoute();
window.addEventListener("popstate", () => this.checkAndUpdateRoute()); this.checkAndUpdateRoute = this.checkAndUpdateRoute.bind(this);
window.addEventListener("popstate", this.checkAndUpdateRoute);
// setup link and directive // setup link and directive
env.qweb.addTemplate(LINK_TEMPLATE_NAME, LINK_TEMPLATE); env.qweb.addTemplate(LINK_TEMPLATE_NAME, LINK_TEMPLATE);
@@ -74,6 +75,9 @@ export class Router {
} }
destToUrl(dest: Destination): string { destToUrl(dest: Destination): string {
if ((!dest.path && !dest.name) || (dest.path && dest.name)) {
throw new Error(`Invalid destination: ${JSON.stringify(dest)}`);
}
return dest.path || this.routeToURL(this.routes[dest.name!].path, dest.params!); return dest.path || this.routeToURL(this.routes[dest.name!].path, dest.params!);
} }
@@ -112,7 +116,7 @@ export class Router {
this.currentParams = {}; this.currentParams = {};
} }
private checkAndUpdateRoute(): void { protected checkAndUpdateRoute(): void {
const initialName = this.currentRoute ? this.currentRoute.name : null; const initialName = this.currentRoute ? this.currentRoute.name : null;
this.checkRoute(); this.checkRoute();
const currentName = this.currentRoute ? this.currentRoute.name : null; const currentName = this.currentRoute ? this.currentRoute.name : null;
+17
View File
@@ -0,0 +1,17 @@
import { Router } from "../../src/router/Router";
import { QWeb } from "../../src/qweb/index";
export class TestRouter extends Router {
destroy() {
window.removeEventListener("popstate", this.checkAndUpdateRoute);
delete QWeb.DIRECTIVE_NAMES.routecomponent;
QWeb.DIRECTIVES = QWeb.DIRECTIVES.filter(d => d.name !== "routecomponent");
// remove component defined inroutes
for (let key in QWeb.components) {
if (key.startsWith("__component__")) {
delete QWeb.components[key];
}
}
}
}
+10 -10
View File
@@ -1,24 +1,24 @@
import { Component } from "../../src/component/component"; import { Component } from "../../src/component/component";
import { QWeb } from "../../src/qweb/index"; import { RouterEnv } from "../../src/router/Router";
import { Router, RouterEnv } from "../../src/router/Router";
import { makeTestEnv, makeTestFixture, nextTick } from "../helpers"; import { makeTestEnv, makeTestFixture, nextTick } from "../helpers";
import { TestRouter } from "./TestRouter";
describe("router directive t-routecomponent", () => { describe("router directive t-routecomponent", () => {
let fixture: HTMLElement; let fixture: HTMLElement;
let env: RouterEnv; let env: RouterEnv;
let router: TestRouter | null = null;
beforeEach(() => { beforeEach(() => {
fixture = makeTestFixture(); fixture = makeTestFixture();
env = <RouterEnv>makeTestEnv(); env = <RouterEnv>makeTestEnv();
delete QWeb.DIRECTIVE_NAMES.routecomponent;
QWeb.DIRECTIVES = QWeb.DIRECTIVES.filter(d => d.name !== "routecomponent");
for (let key in QWeb.components) {
delete QWeb.components[key];
}
}); });
afterEach(() => { afterEach(() => {
fixture.remove(); fixture.remove();
if (router) {
router.destroy();
}
router = null;
}); });
test("can render simple cases", async () => { test("can render simple cases", async () => {
@@ -42,7 +42,7 @@ describe("router directive t-routecomponent", () => {
{ name: "users", path: "/users", component: Users } { name: "users", path: "/users", component: Users }
]; ];
const router = new Router(env,routes, {mode: 'history'}) router = new TestRouter(env, routes, { mode: "history" });
router.navigate({ name: "about" }); router.navigate({ name: "about" });
const app = new App(env); const app = new App(env);
await app.mount(fixture); await app.mount(fixture);
@@ -69,7 +69,7 @@ describe("router directive t-routecomponent", () => {
} }
const routes = [{ name: "book", path: "/book/{{title}}", component: Book }]; const routes = [{ name: "book", path: "/book/{{title}}", component: Book }];
const router = new Router(env,routes, {mode: 'history'}) router = new TestRouter(env, routes, { mode: "history" });
router.navigate({ name: "book", params: { title: "1984" } }); router.navigate({ name: "book", params: { title: "1984" } });
const app = new App(env); const app = new App(env);
await app.mount(fixture); await app.mount(fixture);
@@ -96,7 +96,7 @@ describe("router directive t-routecomponent", () => {
} }
const routes = [{ name: "book", path: "/book/{{title}}/{{val.number}}", component: Book }]; const routes = [{ name: "book", path: "/book/{{title}}/{{val.number}}", component: Book }];
const router = new Router(env,routes, {mode: 'history'}) router = new TestRouter(env, routes, { mode: "history" });
router.navigate({ name: "book", params: { title: "1984", val: "123" } }); router.navigate({ name: "book", params: { title: "1984", val: "123" } });
const app = new App(env); const app = new App(env);
await app.mount(fixture); await app.mount(fixture);
+36 -3
View File
@@ -1,7 +1,23 @@
import { Router } from "../../src/router/Router"; import { Destination, Router, RouterEnv } from "../../src/router/Router";
import { makeTestEnv } from "../helpers";
import { TestRouter } from "./TestRouter";
let env: RouterEnv;
let router: TestRouter | null = null;
beforeEach(() => {
env = <RouterEnv>makeTestEnv();
});
afterEach(() => {
if (router) {
router.destroy();
}
router = null;
});
describe("routeToURL", () => { describe("routeToURL", () => {
const routeToURL = Router.prototype.routeToURL; const routeToURL = Router.prototype["routeToURL"];
test("simple non parameterized path", () => { test("simple non parameterized path", () => {
expect(routeToURL("/abc", {})).toBe("/abc"); expect(routeToURL("/abc", {})).toBe("/abc");
expect(routeToURL("/abc/def", {})).toBe("/abc/def"); expect(routeToURL("/abc/def", {})).toBe("/abc/def");
@@ -13,8 +29,25 @@ describe("routeToURL", () => {
}); });
}); });
describe("destToURL", () => {
test("validate destination shape", () => {
router = new TestRouter(env, [{ name: "someroute", path: "/some/path" }]);
expect(() => {
router!.destToUrl({ abc: 123 } as Destination);
}).toThrow('Invalid destination: {"abc":123}');
expect(() => {
router!.destToUrl({ name: "someroute" } as Destination);
}).not.toThrow();
expect(() => {
router!.destToUrl({ path: "/someroute", name: "otherroute" } as Destination);
}).toThrow();
});
});
describe("match routes", () => { describe("match routes", () => {
const matchRoute = Router.prototype.matchRoute; const matchRoute = Router.prototype["matchRoute"];
test("properly match simple routes", () => { test("properly match simple routes", () => {
// simple route // simple route
expect(matchRoute("/home", "/home")).toEqual({}); expect(matchRoute("/home", "/home")).toEqual({});