@@ -17,6 +17,83 @@ describe('generateNavigationTree', () => {
1717 all : async ( ) => items ,
1818 } as unknown as CollectionQueryBuilder < PageCollectionItemBase > )
1919
20+ const queryInOrder = ( items : Partial < PageCollectionItemBase > [ ] ) => ( {
21+ __params : { orderBy : [ 'caller order' ] } ,
22+ orWhere ( ) { return this } ,
23+ select ( ) { return this } ,
24+ all : async ( ) => items ,
25+ } as unknown as CollectionQueryBuilder < PageCollectionItemBase > )
26+
27+ it . each ( [ false , true ] ) ( 'skips leaf sibling searches with an explicit index: %s' , async ( withIndex ) => {
28+ const pages = Array . from ( { length : 100 } , ( _ , i ) => ( {
29+ title : `Page ${ i } ` ,
30+ path : `/guide/page-${ 100 - i } ` ,
31+ stem : `guide/page-${ 100 - i } ` ,
32+ } ) )
33+ const items = withIndex ? [ { title : 'Guide' , path : '/guide' , stem : 'guide/index' } , ...pages ] : pages
34+ const find = vi . spyOn ( Array . prototype , 'find' )
35+ try {
36+ const tree = await generateNavigationTree ( queryInOrder ( items ) )
37+ const searches = find . mock . calls . length
38+ expect ( searches ) . toBe ( pages . length + Number ( withIndex ) )
39+ expect ( tree [ 0 ] ?. children ?. map ( item => item . path ) ) . toEqual ( items . map ( item => item . path ) )
40+ }
41+ finally {
42+ find . mockRestore ( )
43+ }
44+ } )
45+
46+ it . each ( [ false , true ] ) ( 'merges a placeholder appended after a leaf, from metadata: %s' , async ( fromMetadata ) => {
47+ const tree = await generateNavigationTree ( queryInOrder ( [
48+ { title : 'First' , path : '/guide/first' , stem : 'guide/first' } ,
49+ fromMetadata
50+ ? { title : 'Placeholder' , path : '/guide/topic' , stem : 'guide/topic' , navigation : { page : false } }
51+ : { title : 'Child' , path : '/guide/topic/child' , stem : 'guide/topic/child' } ,
52+ { title : 'Topic' , path : '/guide/topic' , stem : 'guide/topic' } ,
53+ ] ) )
54+
55+ expect ( tree [ 0 ] ?. children ?. map ( item => item . path ) ) . toEqual ( [ '/guide/first' , '/guide/topic' ] )
56+ expect ( tree [ 0 ] ?. children ?. [ 1 ] ) . toMatchObject ( { title : 'Topic' , page : undefined } )
57+ expect ( tree [ 0 ] ?. children ?. [ 1 ] ?. children ?. map ( item => item . path ) ) . toEqual ( fromMetadata ? undefined : [ '/guide/topic/child' ] )
58+ } )
59+
60+ it . each ( [ false , true ] ) ( 'merges supplied duplicate placeholders in order, from directory config: %s' , async ( fromConfig ) => {
61+ const children = [ 'First' , 'Second' ] . map ( title => ( {
62+ title,
63+ path : '/guide/topic' ,
64+ page : false ,
65+ children : [ { title, path : `/guide/topic/${ title . toLowerCase ( ) } ` } ] ,
66+ } ) )
67+ const roots = fromConfig
68+ ? [
69+ { title : 'Config' , path : '/guide/.navigation' , stem : 'guide/.navigation' , meta : { children } } ,
70+ { title : 'Guide' , path : '/guide' , stem : 'guide/index' } ,
71+ ]
72+ : [ { title : 'Guide' , path : '/guide' , stem : 'guide' , navigation : { children } } ]
73+ const tree = await generateNavigationTree ( queryInOrder ( [
74+ ...roots ,
75+ { title : 'Replacement 1' , path : '/guide/topic' , stem : 'guide/topic' } ,
76+ { title : 'Replacement 2' , path : '/guide/topic' , stem : 'guide/topic' } ,
77+ ] ) )
78+
79+ expect ( tree [ 0 ] ?. children ?. map ( item => item . title ) ) . toEqual ( [ 'Replacement 1' , 'Replacement 2' ] )
80+ expect ( tree [ 0 ] ?. children ?. map ( item => item . page ) ) . toEqual ( [ undefined , undefined ] )
81+ expect ( tree [ 0 ] ?. children ?. map ( item => item . children ?. [ 0 ] ?. path ) ) . toEqual ( [ '/guide/topic/first' , '/guide/topic/second' ] )
82+ } )
83+
84+ it . each ( [ false , true ] ) ( 'preserves index merging and later siblings, child first: %s' , async ( childFirst ) => {
85+ const index = { title : 'Topic' , path : '/guide/topic' , stem : 'guide/topic/index' }
86+ const child = { title : 'First' , path : '/guide/topic/first' , stem : 'guide/topic/first' }
87+ const tree = await generateNavigationTree ( queryInOrder ( [
88+ ...( childFirst ? [ child , index ] : [ index , child ] ) ,
89+ { title : 'Second' , path : '/guide/topic/second' , stem : 'guide/topic/second' } ,
90+ ] ) )
91+
92+ expect ( tree [ 0 ] ?. children ?. [ 0 ] ?. children ?. map ( item => item . path ) ) . toEqual ( [
93+ '/guide/topic' , '/guide/topic/first' , '/guide/topic/second' ,
94+ ] )
95+ } )
96+
2097 it ( 'should generate a basic navigation tree' , async ( ) => {
2198 const items = [
2299 {
0 commit comments