11import { describe , it , expect , vi , afterEach , beforeAll } from "vitest" ;
2+ import { nestedCompositionPathFixture } from "../compiler/nestedCompositionPath.testFixture" ;
23import { loadCompositions } from "./compositionLoader" ;
34import { applyVariableBindings } from "./applyVariableBindings" ;
45
@@ -48,10 +49,13 @@ beforeAll(() => {
4849
4950describe ( "loadCompositions external hosts" , ( ) => {
5051 it ( "loads external children in one pass without fetching their parent again" , async ( ) => {
52+ const base = document . createElement ( "base" ) ;
53+ base . href = "https://example.com/" ;
54+ document . head . appendChild ( base ) ;
5155 const host = appendExternalHost ( "https://example.com/scenes/outer.html" , "outer" ) ;
5256 const fetchMock = vi . spyOn ( globalThis , "fetch" ) . mockImplementation ( async ( input ) => {
5357 const html = String ( input ) . endsWith ( "outer.html" )
54- ? '<html><body><div data-composition-id="outer"><div data-composition-id="inner" data-composition-src="inner.html"></div></div></body></html>'
58+ ? '<html><body><div data-composition-id="outer"><div data-composition-id="inner" data-composition-src="scenes/ inner.html"></div></div></body></html>'
5559 : '<html><body><div data-composition-id="inner"><p>Inner content</p></div></body></html>' ;
5660 return new Response ( html , { status : 200 } ) ;
5761 } ) ;
@@ -63,6 +67,27 @@ describe("loadCompositions external hosts", () => {
6367 ] ) ;
6468 } ) ;
6569
70+ it ( "matches bundled root-relative child paths from a nested composition directory" , async ( ) => {
71+ const files = nestedCompositionPathFixture ;
72+ const base = document . createElement ( "base" ) ;
73+ base . href = "https://example.com/project/" ;
74+ document . head . appendChild ( base ) ;
75+ document . body . innerHTML = files [ "index.html" ] ! ;
76+ const fetchMock = vi . spyOn ( globalThis , "fetch" ) . mockImplementation ( async ( input ) => {
77+ const relative = new URL ( String ( input ) ) . pathname . slice ( "/project/" . length ) ;
78+ const content = files [ relative ] ;
79+ return new Response ( content ?? "Not found" , { status : content === undefined ? 404 : 200 } ) ;
80+ } ) ;
81+ const onDiagnostic = vi . fn ( ) ;
82+ await loadFixture ( { onDiagnostic } ) ;
83+ expect ( document . querySelector ( "[data-proof]" ) ?. textContent ) . toBe ( "Project-root card" ) ;
84+ expect ( fetchMock . mock . calls . map ( ( [ url ] ) => url ) ) . toEqual ( [
85+ "https://example.com/project/compositions/scene.html" ,
86+ "https://example.com/project/compositions/cards/card.html" ,
87+ ] ) ;
88+ expect ( onDiagnostic ) . not . toHaveBeenCalled ( ) ;
89+ } ) ;
90+
6691 it ( "loads external children introduced by a template mount" , async ( ) => {
6792 document . body . innerHTML = `<template id="outer-template"><div data-composition-id="outer"><div data-composition-id="inner" data-composition-src="https://example.com/inner.html"></div></div></template><div data-composition-id="outer"></div>` ;
6893 const fetchMock = vi
@@ -98,6 +123,9 @@ describe("loadCompositions external hosts", () => {
98123 } ) ;
99124
100125 it ( "refuses a circular nested external reference without fetching it again" , async ( ) => {
126+ const base = document . createElement ( "base" ) ;
127+ base . href = "https://example.com/" ;
128+ document . head . appendChild ( base ) ;
101129 const host = appendExternalHost ( "https://example.com/loop.html" , "loop" ) ;
102130 const fetchMock = vi
103131 . spyOn ( globalThis , "fetch" )
@@ -159,7 +187,7 @@ describe("loadCompositions external hosts", () => {
159187
160188 afterEach ( ( ) => {
161189 document . body . innerHTML = "" ;
162- document . head . querySelectorAll ( "style, link" ) . forEach ( ( node ) => node . remove ( ) ) ;
190+ document . head . querySelectorAll ( "style, link, base " ) . forEach ( ( node ) => node . remove ( ) ) ;
163191 delete ( window as Window & { gsap ?: unknown ; __selectedTitle ?: unknown } ) . gsap ;
164192 delete ( window as Window & { gsap ?: unknown ; __selectedTitle ?: unknown } ) . __selectedTitle ;
165193 delete ( window as Window & { __hyperframes ?: unknown } ) . __hyperframes ;
0 commit comments