@@ -65,11 +65,41 @@ describe("skeleton/navigation", () => {
6565 it ( "finds the skeleton root and branch starts" , ( ) => {
6666 expect ( getSkeletonRootNode ( graph ) . nodeId ) . toBe ( 1 ) ;
6767 expect ( getBranchStart ( graph , 6 ) . nodeId ) . toBe ( 3 ) ;
68- expect ( getBranchStart ( graph , 3 ) . nodeId ) . toBe ( 3 ) ;
69- expect ( getBranchStart ( graph , 2 ) . nodeId ) . toBe ( 2 ) ;
68+ expect ( getBranchStart ( graph , 3 ) . nodeId ) . toBe ( 1 ) ;
69+ expect ( getBranchStart ( graph , 2 ) . nodeId ) . toBe ( 1 ) ;
7070 expect ( getBranchStart ( graph , 1 ) . nodeId ) . toBe ( 1 ) ;
7171 } ) ;
7272
73+ it ( "walks a degenerate, unbranched skeleton to the root" , ( ) => {
74+ const chainGraph = buildSpatiallyIndexedSkeletonNavigationGraph ( [
75+ makeNode ( 1 , undefined ) ,
76+ makeNode ( 2 , 1 ) ,
77+ makeNode ( 3 , 2 ) ,
78+ makeNode ( 4 , 3 ) ,
79+ ] ) ;
80+
81+ expect ( getBranchStart ( chainGraph , 4 ) . nodeId ) . toBe ( 1 ) ;
82+ expect ( getBranchStart ( chainGraph , 3 ) . nodeId ) . toBe ( 1 ) ;
83+ expect ( getBranchStart ( chainGraph , 2 ) . nodeId ) . toBe ( 1 ) ;
84+ expect ( getBranchStart ( chainGraph , 1 ) . nodeId ) . toBe ( 1 ) ;
85+ } ) ;
86+
87+ it ( "walks past a branch point to the previous branch point or root" , ( ) => {
88+ const nestedForkGraph = buildSpatiallyIndexedSkeletonNavigationGraph ( [
89+ makeNode ( 1 , undefined ) ,
90+ makeNode ( 2 , 1 ) ,
91+ makeNode ( 3 , 2 ) ,
92+ makeNode ( 4 , 2 ) ,
93+ makeNode ( 5 , 3 ) ,
94+ makeNode ( 6 , 3 ) ,
95+ ] ) ;
96+
97+ expect ( getBranchStart ( nestedForkGraph , 6 ) . nodeId ) . toBe ( 3 ) ;
98+ expect ( getBranchStart ( nestedForkGraph , 3 ) . nodeId ) . toBe ( 2 ) ;
99+ expect ( getBranchStart ( nestedForkGraph , 2 ) . nodeId ) . toBe ( 1 ) ;
100+ expect ( getBranchStart ( nestedForkGraph , 1 ) . nodeId ) . toBe ( 1 ) ;
101+ } ) ;
102+
73103 it ( "prefers a downstream branch over a leaf for branch-end navigation" , ( ) => {
74104 const preferenceGraph = buildSpatiallyIndexedSkeletonNavigationGraph ( [
75105 makeNode ( 1 , undefined ) ,
@@ -85,6 +115,21 @@ describe("skeleton/navigation", () => {
85115 expect ( getBranchEnd ( preferenceGraph , 2 ) . nodeId ) . toBe ( 2 ) ;
86116 } ) ;
87117
118+ it ( "randomly resolves ties between equally preferred branch-end candidates" , ( ) => {
119+ const tiedGraph = buildSpatiallyIndexedSkeletonNavigationGraph ( [
120+ makeNode ( 1 , undefined ) ,
121+ makeNode ( 2 , 1 ) ,
122+ makeNode ( 3 , 2 ) ,
123+ makeNode ( 4 , 2 ) ,
124+ makeNode ( 5 , 1 ) ,
125+ makeNode ( 6 , 5 ) ,
126+ makeNode ( 7 , 5 ) ,
127+ ] ) ;
128+
129+ expect ( getBranchEnd ( tiedGraph , 1 , { random : ( ) => 0 } ) . nodeId ) . toBe ( 2 ) ;
130+ expect ( getBranchEnd ( tiedGraph , 1 , { random : ( ) => 0.99 } ) . nodeId ) . toBe ( 5 ) ;
131+ } ) ;
132+
88133 it ( "orders flat-list rows in leaf-first pre-order" , ( ) => {
89134 const listGraph = buildSpatiallyIndexedSkeletonNavigationGraph ( [
90135 makeNode ( 1 , undefined ) ,
0 commit comments