11import { init } from "$lib/init.js" ;
22import { describe , test , expect , beforeAll , afterAll , beforeEach } from "vitest" ;
33import { render } from "@testing-library/svelte" ;
4+ import { createRawSnippet } from "svelte" ;
45import Fallback from "./Fallback.svelte" ;
56import { addMatchingRoute , addRoutes , createRouterTestSetup , createTestSnippet , ROUTING_UNIVERSES , ALL_HASHES } from "$test/test-utils.js" ;
67import { flushSync } from "svelte" ;
78import { resetRoutingOptions , setRoutingOptions } from "$lib/kernel/options.js" ;
8- import type { ExtendedRoutingOptions } from "$lib/types.js" ;
9+ import type { ExtendedRoutingOptions , RouterChildrenContext } from "$lib/types.js" ;
10+ import { location } from "$lib/kernel/Location.js" ;
911
1012function defaultPropsTests ( setup : ReturnType < typeof createRouterTestSetup > ) {
1113 const contentText = "Fallback content." ;
1214 const content = createTestSnippet ( contentText ) ;
13-
15+
1416 beforeEach ( ( ) => {
1517 // Fresh router instance for each test
1618 setup . init ( ) ;
1719 } ) ;
18-
20+
1921 afterAll ( ( ) => {
2022 // Clean disposal after all tests
2123 setup . dispose ( ) ;
2224 } ) ;
23-
25+
2426 test ( "Should render whenever the parent router matches no routes." , async ( ) => {
2527 // Arrange.
2628 const { hash, router, context } = setup ;
@@ -31,7 +33,7 @@ function defaultPropsTests(setup: ReturnType<typeof createRouterTestSetup>) {
3133 // Assert.
3234 await expect ( findByText ( contentText ) ) . resolves . toBeDefined ( ) ;
3335 } ) ;
34-
36+
3537 test ( "Should not render whenever the parent router matches at least one route." , async ( ) => {
3638 // Arrange.
3739 const { hash, router, context } = setup ;
@@ -163,6 +165,116 @@ function reactivityTests(setup: ReturnType<typeof createRouterTestSetup>) {
163165 } ) ;
164166}
165167
168+
169+ function fallbackChildrenSnippetContextTests ( setup : ReturnType < typeof createRouterTestSetup > ) {
170+ beforeEach ( ( ) => {
171+ // Fresh router instance for each test
172+ setup . init ( ) ;
173+ } ) ;
174+
175+ afterAll ( ( ) => {
176+ // Clean disposal after all tests
177+ setup . dispose ( ) ;
178+ } ) ;
179+
180+ test ( "Should pass RouterChildrenContext with correct structure to children snippet when fallback activates." , async ( ) => {
181+ // Arrange.
182+ const { hash, context } = setup ;
183+ let capturedContext : RouterChildrenContext ;
184+ const content = createRawSnippet < [ RouterChildrenContext ] > ( ( contextObj ) => {
185+ capturedContext = contextObj ( ) ;
186+ return { render : ( ) => '<div>Fallback Context Test</div>' } ;
187+ } ) ;
188+
189+ // Act.
190+ render ( Fallback , {
191+ props : { hash, children : content } ,
192+ context
193+ } ) ;
194+
195+ // Assert.
196+ expect ( capturedContext ! ) . toBeDefined ( ) ;
197+ expect ( capturedContext ! ) . toHaveProperty ( 'state' ) ;
198+ expect ( capturedContext ! ) . toHaveProperty ( 'rs' ) ;
199+ expect ( typeof capturedContext ! . rs ) . toBe ( 'object' ) ;
200+ } ) ;
201+
202+ test ( "Should provide current router state in children snippet context." , async ( ) => {
203+ // Arrange.
204+ const { hash, context } = setup ;
205+ let capturedContext : RouterChildrenContext ;
206+ const newState = { msg : "Test State" } ;
207+ location . navigate ( '/' , { state : newState } ) ;
208+ const content = createRawSnippet < [ RouterChildrenContext ] > ( ( contextObj ) => {
209+ capturedContext = contextObj ( ) ;
210+ return { render : ( ) => '<div>Fallback State Test</div>' } ;
211+ } ) ;
212+
213+ // Act.
214+ render ( Fallback , {
215+ props : { hash, children : content } ,
216+ context
217+ } ) ;
218+
219+ // Assert.
220+ expect ( capturedContext ! . state ) . toBeDefined ( ) ;
221+ expect ( capturedContext ! . state ) . toEqual ( newState ) ;
222+ } ) ;
223+
224+ test ( "Should provide route status record in children snippet context." , async ( ) => {
225+ // Arrange.
226+ const { hash, router, context } = setup ;
227+ let capturedContext : RouterChildrenContext ;
228+ const content = createRawSnippet < [ RouterChildrenContext ] > ( ( contextObj ) => {
229+ capturedContext = contextObj ( ) ;
230+ return { render : ( ) => '<div>Fallback RouteStatus Test</div>' } ;
231+ } ) ;
232+
233+ // Add some non-matching routes to verify structure
234+ addRoutes ( router , { nonMatching : 2 } ) ;
235+
236+ // Act.
237+ render ( Fallback , {
238+ props : { hash, children : content } ,
239+ context
240+ } ) ;
241+
242+ // Assert.
243+ expect ( capturedContext ! . rs ) . toBeDefined ( ) ;
244+ expect ( typeof capturedContext ! . rs ) . toBe ( 'object' ) ;
245+ expect ( Object . keys ( capturedContext ! . rs ) ) . toHaveLength ( 2 ) ;
246+ // Verify each route status has correct structure
247+ Object . keys ( capturedContext ! . rs ) . forEach ( key => {
248+ expect ( capturedContext ?. rs [ key ] ) . toHaveProperty ( 'match' ) ;
249+ expect ( typeof capturedContext ?. rs [ key ] . match ) . toBe ( 'boolean' ) ;
250+ } ) ;
251+ } ) ;
252+
253+ test ( "Should not render children snippet when parent router has matching routes." , async ( ) => {
254+ // Arrange.
255+ const { hash, router, context } = setup ;
256+ let capturedContext : RouterChildrenContext ;
257+ let callCount = 0 ;
258+ const content = createRawSnippet < [ RouterChildrenContext ] > ( ( contextObj ) => {
259+ capturedContext = contextObj ( ) ;
260+ callCount ++ ;
261+ return { render : ( ) => '<div>Should Not Render</div>' } ;
262+ } ) ;
263+
264+ // Add matching route to prevent fallback activation
265+ addMatchingRoute ( router ) ;
266+
267+ // Act.
268+ render ( Fallback , {
269+ props : { hash, children : content } ,
270+ context
271+ } ) ;
272+
273+ // Assert - snippet should not be called when routes are matching.
274+ expect ( callCount ) . toBe ( 0 ) ;
275+ } ) ;
276+ }
277+
166278describe ( "Routing Mode Assertions" , ( ) => {
167279 const contentText = "Fallback content." ;
168280 const content = createTestSnippet ( contentText ) ;
@@ -207,8 +319,8 @@ describe("Routing Mode Assertions", () => {
207319
208320 // Act & Assert
209321 expect ( ( ) => {
210- render ( Fallback , {
211- props : { hash, children : content } ,
322+ render ( Fallback , {
323+ props : { hash, children : content } ,
212324 } ) ;
213325 } ) . toThrow ( ) ;
214326 } ) ;
@@ -236,5 +348,9 @@ ROUTING_UNIVERSES.forEach(ru => {
236348 describe ( "Reactivity" , ( ) => {
237349 reactivityTests ( setup ) ;
238350 } ) ;
351+
352+ describe ( "Children Snippet Context" , ( ) => {
353+ fallbackChildrenSnippetContextTests ( setup ) ;
354+ } ) ;
239355 } ) ;
240356} ) ;
0 commit comments