5
5
* LICENSE file in the root directory of this source tree.
6
6
*/
7
7
8
+ import { fromPartial } from '@total-typescript/shoehorn' ;
8
9
import {
9
10
generateRoutesCode ,
10
11
genChunkName ,
11
12
generateRoutePropFilename ,
12
13
} from '../codegenRoutes' ;
13
14
import type { RouteConfig } from '@docusaurus/types' ;
14
15
16
+ function route ( routeConfig : Partial < RouteConfig > ) : RouteConfig {
17
+ return fromPartial ( routeConfig ) ;
18
+ }
19
+
15
20
describe ( 'generateRoutePropFilename' , ( ) => {
16
21
it ( 'generate filename based on route path' , ( ) => {
17
22
expect (
@@ -206,9 +211,7 @@ describe('loadRoutes', () => {
206
211
} ,
207
212
] ,
208
213
} ;
209
- expect (
210
- generateRoutesCode ( [ nestedRouteConfig ] , '/' , 'ignore' ) ,
211
- ) . toMatchSnapshot ( ) ;
214
+ expect ( generateRoutesCode ( [ nestedRouteConfig ] ) ) . toMatchSnapshot ( ) ;
212
215
} ) ;
213
216
214
217
it ( 'loads flat route config' , ( ) => {
@@ -243,17 +246,15 @@ describe('loadRoutes', () => {
243
246
] ,
244
247
} ,
245
248
} ;
246
- expect (
247
- generateRoutesCode ( [ flatRouteConfig ] , '/' , 'ignore' ) ,
248
- ) . toMatchSnapshot ( ) ;
249
+ expect ( generateRoutesCode ( [ flatRouteConfig ] ) ) . toMatchSnapshot ( ) ;
249
250
} ) ;
250
251
251
252
it ( 'rejects invalid route config' , ( ) => {
252
253
const routeConfigWithoutPath = {
253
254
component : 'hello/world.js' ,
254
255
} as RouteConfig ;
255
256
256
- expect ( ( ) => generateRoutesCode ( [ routeConfigWithoutPath ] , '/' , 'ignore' ) )
257
+ expect ( ( ) => generateRoutesCode ( [ routeConfigWithoutPath ] ) )
257
258
. toThrowErrorMatchingInlineSnapshot ( `
258
259
"Invalid route config: path must be a string and component is required.
259
260
{"component":"hello/world.js"}"
@@ -263,9 +264,8 @@ describe('loadRoutes', () => {
263
264
path : '/hello/world' ,
264
265
} as RouteConfig ;
265
266
266
- expect ( ( ) =>
267
- generateRoutesCode ( [ routeConfigWithoutComponent ] , '/' , 'ignore' ) ,
268
- ) . toThrowErrorMatchingInlineSnapshot ( `
267
+ expect ( ( ) => generateRoutesCode ( [ routeConfigWithoutComponent ] ) )
268
+ . toThrowErrorMatchingInlineSnapshot ( `
269
269
"Invalid route config: path must be a string and component is required.
270
270
{"path":"/hello/world"}"
271
271
` ) ;
@@ -277,6 +277,56 @@ describe('loadRoutes', () => {
277
277
component : 'hello/world.js' ,
278
278
} as RouteConfig ;
279
279
280
- expect ( generateRoutesCode ( [ routeConfig ] , '/' , 'ignore' ) ) . toMatchSnapshot ( ) ;
280
+ expect ( generateRoutesCode ( [ routeConfig ] ) ) . toMatchSnapshot ( ) ;
281
+ } ) ;
282
+
283
+ it ( 'generates an entry for each route and handle hash collisions' , ( ) => {
284
+ // See bug https://github.com/facebook/docusaurus/issues/10718#issuecomment-2507635907
285
+ const routeConfigs = [
286
+ route ( {
287
+ path : '/docs' ,
288
+ component : '@theme/Root' ,
289
+ routes : [
290
+ route ( {
291
+ path : '/docs' ,
292
+ component : '@theme/Version' ,
293
+ children : [ ] ,
294
+ } ) ,
295
+ ] ,
296
+ } ) ,
297
+ route ( {
298
+ path : '/docs' ,
299
+ component : '@theme/Root' ,
300
+ routes : [
301
+ route ( {
302
+ path : '/docs' ,
303
+ component : '@theme/Version' ,
304
+ children : [ ] ,
305
+ } ) ,
306
+ ] ,
307
+ } ) ,
308
+ ] ;
309
+
310
+ const result = generateRoutesCode ( routeConfigs ) ;
311
+
312
+ // We absolutely want to have 2 entries here, even if routes are the same
313
+ // One should not override the other
314
+ expect ( Object . keys ( result . routesChunkNames ) ) . toHaveLength ( 4 ) ;
315
+ expect ( result . routesChunkNames ) . toMatchInlineSnapshot ( `
316
+ {
317
+ "/docs-611": {
318
+ "__comp": "__comp---theme-version-6-f-8-19f",
319
+ },
320
+ "/docs-96a": {
321
+ "__comp": "__comp---theme-root-1-dd-d3a",
322
+ },
323
+ "/docs-d3d": {
324
+ "__comp": "__comp---theme-version-6-f-8-19f",
325
+ },
326
+ "/docs-e4f": {
327
+ "__comp": "__comp---theme-root-1-dd-d3a",
328
+ },
329
+ }
330
+ ` ) ;
281
331
} ) ;
282
332
} ) ;
0 commit comments