UNPKG

one

Version:

One is a new React Framework that makes Vite serve both native and web.

179 lines (165 loc) 5.34 kB
import { describe, expect, it } from 'vitest' import { getServerManifest } from './getServerManifest' import type { RouteNode } from '../router/Route' function makeRouteNode(overrides: Partial<RouteNode>): RouteNode { return { loadRoute: () => ({}), contextKey: '', route: '', children: [], dynamic: null, type: 'ssg', ...overrides, } as RouteNode } describe('getServerManifest route specificity', () => { it('static segment /blog/[slug] should come before fully dynamic /[a]/[b]', () => { // simulates: (site)/blog/[slug]+ssg.tsx vs (chat)/[serverId]/[channelId]/index.tsx const root = makeRouteNode({ route: '', children: [ // group (site) with blog/[slug] makeRouteNode({ route: '(site)', children: [ makeRouteNode({ route: 'blog/[slug]', contextKey: '(site)/blog/[slug]+ssg.tsx', type: 'ssg', dynamic: [{ name: 'slug', deep: false }], children: [], }), ], }), // group (chat) with [serverId]/[channelId] makeRouteNode({ route: '(chat)', children: [ makeRouteNode({ route: '[serverId]', dynamic: [{ name: 'serverId', deep: false }], children: [ makeRouteNode({ route: '[channelId]', dynamic: [{ name: 'channelId', deep: false }], children: [ makeRouteNode({ route: 'index', contextKey: '(chat)/[serverId]/[channelId]/index.tsx', type: 'spa', children: [], }), ], }), ], }), ], }), ], }) const manifest = getServerManifest(root) const pages = manifest.pageRoutes.map((r) => r.file) const blogIdx = pages.indexOf('(site)/blog/[slug]+ssg.tsx') const chatIdx = pages.indexOf('(chat)/[serverId]/[channelId]/index.tsx') expect(blogIdx).toBeGreaterThanOrEqual(0) expect(chatIdx).toBeGreaterThanOrEqual(0) // blog route (static first segment) must come before chat route (all dynamic) expect(blogIdx).toBeLessThan(chatIdx) }) it('/blog should come before /[slug]', () => { const root = makeRouteNode({ route: '', children: [ makeRouteNode({ route: 'blog', contextKey: 'blog.tsx', type: 'ssg', children: [], }), makeRouteNode({ route: '[slug]', contextKey: '[slug].tsx', type: 'ssr', dynamic: [{ name: 'slug', deep: false }], children: [], }), ], }) const manifest = getServerManifest(root) const pages = manifest.pageRoutes.map((r) => r.file) expect(pages.indexOf('blog.tsx')).toBeLessThan(pages.indexOf('[slug].tsx')) }) it('/blog/hello-world should match blog route first, not [serverId]/[channelId]', () => { const root = makeRouteNode({ route: '', children: [ makeRouteNode({ route: '(site)', children: [ makeRouteNode({ route: 'blog/[slug]', contextKey: '(site)/blog/[slug]+ssg.tsx', type: 'ssg', dynamic: [{ name: 'slug', deep: false }], children: [], }), ], }), makeRouteNode({ route: '(chat)', children: [ makeRouteNode({ route: '[serverId]', dynamic: [{ name: 'serverId', deep: false }], children: [ makeRouteNode({ route: '[channelId]', dynamic: [{ name: 'channelId', deep: false }], children: [ makeRouteNode({ route: 'index', contextKey: '(chat)/[serverId]/[channelId]/index.tsx', type: 'spa', children: [], }), ], }), ], }), ], }), ], }) const manifest = getServerManifest(root) // find first matching route for /blog/hello-world const pathname = '/blog/hello-world' const matched = manifest.pageRoutes.find((route) => { return new RegExp(route.namedRegex).test(pathname) }) expect(matched?.file).toBe('(site)/blog/[slug]+ssg.tsx') }) it('[slug] should come before [...catchAll]', () => { const root = makeRouteNode({ route: '', children: [ makeRouteNode({ route: '[...catchAll]', contextKey: '[...catchAll].tsx', type: 'ssr', dynamic: [{ name: 'catchAll', deep: true }], children: [], }), makeRouteNode({ route: '[slug]', contextKey: '[slug].tsx', type: 'ssr', dynamic: [{ name: 'slug', deep: false }], children: [], }), ], }) const manifest = getServerManifest(root) const pages = manifest.pageRoutes.map((r) => r.file) expect(pages.indexOf('[slug].tsx')).toBeLessThan(pages.indexOf('[...catchAll].tsx')) }) })