Skip to content

Commit 8994fc1

Browse files
authored
test(router-core): add some missing unit-tests to the new processRouteTree (#5879)
1 parent cdd2de3 commit 8994fc1

File tree

1 file changed

+122
-6
lines changed

1 file changed

+122
-6
lines changed

packages/router-core/tests/new-process-route-tree.test.ts

Lines changed: 122 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
import { describe, expect, it } from 'vitest'
2-
import { findRouteMatch, processRouteTree } from '../src/new-process-route-tree'
2+
import {
3+
findFlatMatch,
4+
findRouteMatch,
5+
processRouteMasks,
6+
processRouteTree,
7+
} from '../src/new-process-route-tree'
38
import type { AnyRoute, RouteMask } from '../src'
49

510
function makeTree(routes: Array<string>) {
@@ -191,10 +196,92 @@ describe('findRouteMatch', () => {
191196
expect(findRouteMatch('/a/b/c/d/e', tree)?.route.id).toBe('/a/b/c/$')
192197
expect(findRouteMatch('/a/d/e', tree)?.route.id).toBe('/a/$')
193198
})
199+
200+
it('matching a single dynamic param is favored over matching any number of optional params', () => {
201+
const tree = makeTree(['/$a/z', '/{-$a}/{-$b}/{-$c}/{-$d}/{-$e}/z'])
202+
expect(findRouteMatch('/a/z', tree)?.route.id).toBe('/$a/z')
203+
expect(findRouteMatch('/a/b/z', tree)?.route.id).toBe(
204+
'/{-$a}/{-$b}/{-$c}/{-$d}/{-$e}/z',
205+
)
206+
})
207+
it('matching a single dynamic param is favored over matching any number of optional params (2)', () => {
208+
const tree = makeTree(['/{-$a}/$b', '/{-$a}'])
209+
expect(findRouteMatch('/a', tree)?.route.id).toBe('/{-$a}/$b')
210+
expect(findRouteMatch('/a/b', tree)?.route.id).toBe('/{-$a}/$b')
211+
})
212+
describe('optional param can be a route on its own, but matching a static or dynamic is preferred', () => {
213+
it('on its own', () => {
214+
const tree = makeTree(['/a/{-$b}/'])
215+
expect(findRouteMatch('/a/b', tree)?.route.id).toBe('/a/{-$b}/')
216+
})
217+
it('vs dynamic sibling', () => {
218+
const tree = makeTree(['/a/{-$b}/', '/a/$b'])
219+
expect(findRouteMatch('/a/b', tree)?.route.id).toBe('/a/$b')
220+
})
221+
it('vs dynamic child', () => {
222+
const tree = makeTree(['/a/{-$b}/', '/a/{-$b}/$c'])
223+
expect(findRouteMatch('/a/b', tree)?.route.id).toBe('/a/{-$b}/$c')
224+
})
225+
})
194226
})
195227
})
196228

197-
describe.todo('trailing slashes', () => {})
229+
describe('trailing slashes (index routes)', () => {
230+
describe('static routes', () => {
231+
it('an index route can be matched by a path with a trailing slash', () => {
232+
const tree = makeTree(['/a/'])
233+
expect(findRouteMatch('/a/', tree)?.route.id).toBe('/a/')
234+
})
235+
it('an index route can be matched by a path without a trailing slash', () => {
236+
const tree = makeTree(['/a/'])
237+
expect(findRouteMatch('/a', tree)?.route.id).toBe('/a/')
238+
})
239+
it('a non-index route CANNOT be matched by a path with a trailing slash', () => {
240+
const tree = makeTree(['/a'])
241+
expect(findRouteMatch('/a/', tree)).toBeNull()
242+
})
243+
it('a non-index route can be matched by a path without a trailing slash', () => {
244+
const tree = makeTree(['/a'])
245+
expect(findRouteMatch('/a', tree)?.route.id).toBe('/a')
246+
})
247+
})
248+
describe('dynamic routes', () => {
249+
it('an index route can be matched by a path with a trailing slash', () => {
250+
const tree = makeTree(['/$a/'])
251+
expect(findRouteMatch('/a/', tree)?.route.id).toBe('/$a/')
252+
})
253+
it('an index route can be matched by a path without a trailing slash', () => {
254+
const tree = makeTree(['/$a/'])
255+
expect(findRouteMatch('/a', tree)?.route.id).toBe('/$a/')
256+
})
257+
it('a non-index route CANNOT be matched by a path with a trailing slash', () => {
258+
const tree = makeTree(['/$a'])
259+
expect(findRouteMatch('/a/', tree)).toBeNull()
260+
})
261+
it('a non-index route can be matched by a path without a trailing slash', () => {
262+
const tree = makeTree(['/$a'])
263+
expect(findRouteMatch('/a', tree)?.route.id).toBe('/$a')
264+
})
265+
})
266+
describe('optional routes', () => {
267+
it('an index route can be matched by a path with a trailing slash', () => {
268+
const tree = makeTree(['/{-$a}/'])
269+
expect(findRouteMatch('/a/', tree)?.route.id).toBe('/{-$a}/')
270+
})
271+
it('an index route can be matched by a path without a trailing slash', () => {
272+
const tree = makeTree(['/{-$a}/'])
273+
expect(findRouteMatch('/a', tree)?.route.id).toBe('/{-$a}/')
274+
})
275+
it('a non-index route CANNOT be matched by a path with a trailing slash', () => {
276+
const tree = makeTree(['/{-$a}'])
277+
expect(findRouteMatch('/a/', tree)).toBeNull()
278+
})
279+
it('a non-index route can be matched by a path without a trailing slash', () => {
280+
const tree = makeTree(['/{-$a}'])
281+
expect(findRouteMatch('/a', tree)?.route.id).toBe('/{-$a}')
282+
})
283+
})
284+
})
198285

199286
describe('case sensitivity competition', () => {
200287
it('a case sensitive segment early on should not prevent a case insensitive match', () => {
@@ -702,16 +789,45 @@ describe('findRouteMatch', () => {
702789
})
703790
})
704791

705-
describe.todo('processRouteMasks', () => {
706-
it('processes a route masks list', () => {
707-
const routeTree = {} as AnyRoute
792+
describe('processRouteMasks', { sequential: true }, () => {
793+
const routeTree = {
794+
id: '__root__',
795+
isRoot: true,
796+
fullPath: '/',
797+
} as AnyRoute
798+
const { processedTree } = processRouteTree(routeTree)
799+
it('processes a route masks list into a segment tree', () => {
708800
const routeMasks: Array<RouteMask<AnyRoute>> = [
709801
{ from: '/a/b/c', routeTree },
710802
{ from: '/a/b/d', routeTree },
711803
{ from: '/a/$param/d', routeTree },
712804
{ from: '/a/{-$optional}/d', routeTree },
713805
{ from: '/a/b/{$}.txt', routeTree },
714806
]
715-
// expect(processRouteMasks(routeMasks)).toMatchInlineSnapshot()
807+
processRouteMasks(routeMasks, processedTree)
808+
const aBranch = processedTree.masksTree?.staticInsensitive?.get('a')
809+
expect(aBranch).toBeDefined()
810+
expect(aBranch?.staticInsensitive?.get('b')).toBeDefined()
811+
expect(aBranch?.dynamic).toHaveLength(1)
812+
expect(aBranch?.optional).toHaveLength(1)
813+
})
814+
it('can match static routes masks w/ `findFlatMatch`', () => {
815+
const res = findFlatMatch('/a/b/c', processedTree)
816+
expect(res?.route.from).toBe('/a/b/c')
817+
})
818+
it('can match dynamic route masks w/ `findFlatMatch`', () => {
819+
const res = findFlatMatch('/a/123/d', processedTree)
820+
expect(res?.route.from).toBe('/a/$param/d')
821+
expect(res?.params).toEqual({ param: '123' })
822+
})
823+
it('can match optional route masks w/ `findFlatMatch`', () => {
824+
const res = findFlatMatch('/a/d', processedTree)
825+
expect(res?.route.from).toBe('/a/{-$optional}/d')
826+
expect(res?.params).toEqual({})
827+
})
828+
it('can match prefix/suffix wildcard route masks w/ `findFlatMatch`', () => {
829+
const res = findFlatMatch('/a/b/file/path.txt', processedTree)
830+
expect(res?.route.from).toBe('/a/b/{$}.txt')
831+
expect(res?.params).toEqual({ '*': 'file/path', _splat: 'file/path' })
716832
})
717833
})

0 commit comments

Comments
 (0)