diff --git a/tests/router/index.spec.ts b/tests/router/index.spec.ts new file mode 100644 index 0000000..eb8aee6 --- /dev/null +++ b/tests/router/index.spec.ts @@ -0,0 +1,168 @@ + +import { describe, it, expect, beforeEach } from "vitest"; +import router from "~/router/index"; + +describe("Router Integration Tests", () => { + beforeEach(async () => { + await router.push("/"); + await router.isReady(); + }); + + it("creates a router instance", () => { + expect(router).toBeDefined(); + expect(router).toHaveProperty("currentRoute"); + expect(router).toHaveProperty("push"); + expect(router).toHaveProperty("replace"); + }); + + it("has hash history mode", () => { + expect(router.options.history.base).toContain("#"); + }); + + it("has 2 routes configured", () => { + const routes = router.getRoutes(); + expect(routes).toHaveLength(2); + }); + + it("has home route at root path", () => { + const routes = router.getRoutes(); + const homeRoute = routes.find(route => route.path === "/"); + + expect(homeRoute).toBeDefined(); + expect(homeRoute?.name).toBe("home"); + }); + + it("has about route", () => { + const routes = router.getRoutes(); + const aboutRoute = routes.find(route => route.path === "/about"); + + expect(aboutRoute).toBeDefined(); + expect(aboutRoute?.name).toBe("about"); + }); + + it("navigates to home route", async () => { + await router.push("/"); + await router.isReady(); + + expect(router.currentRoute.value.path).toBe("/"); + expect(router.currentRoute.value.name).toBe("home"); + }); + + it("navigates to about route", async () => { + await router.push("/about"); + await router.isReady(); + + expect(router.currentRoute.value.path).toBe("/about"); + expect(router.currentRoute.value.name).toBe("about"); + }); + + it("navigates using route name for home", async () => { + await router.push({ name: "home" }); + await router.isReady(); + + expect(router.currentRoute.value.name).toBe("home"); + expect(router.currentRoute.value.path).toBe("/"); + }); + + it("navigates using route name for about", async () => { + await router.push({ name: "about" }); + await router.isReady(); + + expect(router.currentRoute.value.name).toBe("about"); + expect(router.currentRoute.value.path).toBe("/about"); + }); + + it("resolves home route correctly", () => { + const resolved = router.resolve("/"); + + expect(resolved.name).toBe("home"); + expect(resolved.path).toBe("/"); + }); + + it("resolves about route correctly", () => { + const resolved = router.resolve("/about"); + + expect(resolved.name).toBe("about"); + expect(resolved.path).toBe("/about"); + }); + + it("has HomeView component for home route", () => { + const routes = router.getRoutes(); + const homeRoute = routes.find(route => route.path === "/"); + + expect(homeRoute?.components?.default).toBeDefined(); + }); + + it("has lazy loaded component for about route", () => { + const routes = router.getRoutes(); + const aboutRoute = routes.find(route => route.path === "/about"); + + expect(aboutRoute?.components).toBeDefined(); + }); + + it("checks if home route exists", () => { + expect(router.hasRoute("home")).toBe(true); + }); + + it("checks if about route exists", () => { + expect(router.hasRoute("about")).toBe(true); + }); + + it("does not have undefined routes", () => { + expect(router.hasRoute("nonexistent")).toBe(false); + }); + + it("maintains navigation history", async () => { + await router.push("/"); + await router.push("/about"); + + expect(router.currentRoute.value.path).toBe("/about"); + + router.back(); + await router.isReady(); + + expect(router.back).toBeDefined(); + }); + + it("handles programmatic navigation with replace", async () => { + await router.push("/"); + await router.replace("/about"); + await router.isReady(); + + expect(router.currentRoute.value.path).toBe("/about"); + }); + + it("matches routes case-sensitively", () => { + const routes = router.getRoutes(); + const upperCaseRoute = routes.find(route => route.path === "/ABOUT"); + + expect(upperCaseRoute).toBeUndefined(); + }); + + it("provides route metadata access", () => { + const routes = router.getRoutes(); + + routes.forEach(route => { + expect(route).toHaveProperty("path"); + expect(route).toHaveProperty("name"); + expect(route).toHaveProperty("meta"); + }); + }); + + it("is ready after initialization", async () => { + const ready = await router.isReady(); + + // Note: isReady() returns void when resolved + expect(ready).toBeUndefined(); + }); + + it("handles navigation to current route", async () => { + await router.push("/"); + + try { + await router.push("/"); + } catch (error: any) { + expect(error.message).toContain("Avoided redundant navigation to current location"); + } + }); +});