Skip to content

Commit a314a4d

Browse files
committed
test(hybrid-routes): add unit tests for plus and directory route groups
Signed-off-by: Ryan Bower <rbower@qti.qualcomm.com>
1 parent 0fe4d8a commit a314a4d

1 file changed

Lines changed: 172 additions & 0 deletions

File tree

Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
1+
// Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
2+
// SPDX-License-Identifier: BSD-3-Clause-Clear
3+
4+
import {mkdir, mkdtemp, rm, writeFile} from "node:fs/promises"
5+
import {tmpdir} from "node:os"
6+
import {dirname, join} from "node:path"
7+
import {afterEach, describe, expect, test} from "vitest"
8+
9+
import {
10+
type ConfigRoute,
11+
type DefineRouteFunction,
12+
type DefineRoutesFunction,
13+
hybridRoutes,
14+
type RouteManifest,
15+
} from "./hybrid-routes"
16+
17+
let tempDir: string | undefined
18+
19+
afterEach(async () => {
20+
if (tempDir) {
21+
await rm(tempDir, {force: true, recursive: true})
22+
tempDir = undefined
23+
}
24+
})
25+
26+
describe("hybridRoutes", () => {
27+
test("plus route groups discover plus folders and route files", async () => {
28+
const appDir = await createAppRoutes([
29+
"_index.mdx",
30+
"api/page-frontmatter.mdx",
31+
"api/page-frontmatter.route.mdx",
32+
"guide+/route.mdx",
33+
"guide+/markdown.ts",
34+
"guide+/advanced+/deep-topic.ts",
35+
"plain/ignored.ts",
36+
])
37+
38+
const routes = hybridRoutes("routes", createDefineRoutes(), {
39+
appDir,
40+
routingStrategy: "react-router-directory-groups",
41+
})
42+
43+
expect(Object.keys(routes).sort()).toEqual([
44+
"routes/_index",
45+
"routes/api/page-frontmatter.route",
46+
"routes/guide+/advanced+/deep-topic",
47+
"routes/guide+/markdown",
48+
"routes/guide+/route",
49+
])
50+
expect(routes["routes/guide+/route"]).toMatchObject({
51+
file: "routes/guide+/route.mdx",
52+
parentId: "root",
53+
path: "guide",
54+
})
55+
expect(routes["routes/guide+/markdown"]).toMatchObject({
56+
file: "routes/guide+/markdown.ts",
57+
parentId: "routes/guide+/route",
58+
path: "markdown",
59+
})
60+
expect(routes["routes/guide+/advanced+/deep-topic"]).toMatchObject({
61+
file: "routes/guide+/advanced+/deep-topic.ts",
62+
parentId: "routes/guide+/route",
63+
path: "advanced/deep-topic",
64+
})
65+
expect(routes["routes/api/page-frontmatter.route"]).toMatchObject({
66+
file: "routes/api/page-frontmatter.route.mdx",
67+
parentId: "root",
68+
path: "api/page-frontmatter",
69+
})
70+
})
71+
72+
test("directory route groups discover plain nested route files", async () => {
73+
const appDir = await createAppRoutes([
74+
"_index.mdx",
75+
"api/page-frontmatter.mdx",
76+
"guide/route.mdx",
77+
"guide/markdown.ts",
78+
"guide/advanced/deep-topic.ts",
79+
"guide/_demos/ignored.mdx",
80+
])
81+
82+
const routes = hybridRoutes("routes", createDefineRoutes(), {
83+
appDir,
84+
routingStrategy: "react-router-directory-groups",
85+
})
86+
87+
expect(Object.keys(routes).sort()).toEqual([
88+
"routes/_index",
89+
"routes/api/page-frontmatter",
90+
"routes/guide/advanced/deep-topic",
91+
"routes/guide/markdown",
92+
"routes/guide/route",
93+
])
94+
expect(routes["routes/guide/route"]).toMatchObject({
95+
file: "routes/guide/route.mdx",
96+
parentId: "root",
97+
path: "guide",
98+
})
99+
expect(routes["routes/guide/markdown"]).toMatchObject({
100+
file: "routes/guide/markdown.ts",
101+
parentId: "routes/guide/route",
102+
path: "markdown",
103+
})
104+
expect(routes["routes/guide/advanced/deep-topic"]).toMatchObject({
105+
file: "routes/guide/advanced/deep-topic.ts",
106+
parentId: "routes/guide/route",
107+
path: "advanced/deep-topic",
108+
})
109+
expect(routes["routes/api/page-frontmatter"]).toMatchObject({
110+
file: "routes/api/page-frontmatter.mdx",
111+
parentId: "root",
112+
path: "api/page-frontmatter",
113+
})
114+
})
115+
})
116+
117+
async function createAppRoutes(routeFiles: string[]): Promise<string> {
118+
tempDir = await mkdtemp(join(tmpdir(), "hybrid-routes-test-"))
119+
const routesDir = join(tempDir, "routes")
120+
121+
for (const routeFile of routeFiles) {
122+
const filePath = join(routesDir, routeFile)
123+
await mkdir(dirname(filePath), {recursive: true})
124+
await writeFile(filePath, "", "utf-8")
125+
}
126+
127+
return tempDir
128+
}
129+
130+
function createDefineRoutes(): DefineRoutesFunction {
131+
return (callback) => {
132+
const routes: RouteManifest = {}
133+
const parentIds: string[] = []
134+
135+
const defineRoute: DefineRouteFunction = (
136+
path,
137+
file,
138+
optionsOrChildren,
139+
children,
140+
) => {
141+
const id = file.replace(/\.[^/.]+$/, "")
142+
const route: ConfigRoute = {file, id}
143+
const parentId = parentIds.at(-1)
144+
const options =
145+
typeof optionsOrChildren === "function" ? undefined : optionsOrChildren
146+
const childRoutes =
147+
typeof optionsOrChildren === "function" ? optionsOrChildren : children
148+
149+
if (path !== undefined) {
150+
route.path = path
151+
}
152+
if (options?.index) {
153+
route.index = true
154+
}
155+
if (parentId) {
156+
route.parentId = parentId
157+
}
158+
159+
routes[id] = route
160+
161+
if (childRoutes) {
162+
parentIds.push(id)
163+
childRoutes()
164+
parentIds.pop()
165+
}
166+
}
167+
168+
callback(defineRoute)
169+
170+
return routes
171+
}
172+
}

0 commit comments

Comments
 (0)