@@ -4,6 +4,7 @@ import { tmpdir } from "node:os";
44import { dirname , join } from "node:path" ;
55import { fileURLToPath } from "node:url" ;
66import { shaderManifestSchema , validateShaderManifestFile } from "./index.ts" ;
7+ import { buildTslPreviewModule } from "./tsl-preview-module.ts" ;
78
89const fixtureManifestPath = fileURLToPath (
910 new URL ( "../../../shaders/gradient-radial/shader.json" , import . meta. url ) ,
@@ -12,25 +13,30 @@ const sourcedFixtureManifestPath = fileURLToPath(
1213 new URL ( "../../../shaders/vignette-postprocess/shader.json" , import . meta. url ) ,
1314) ;
1415
15- function runTest ( name : string , callback : ( ) => void ) {
16- try {
17- callback ( ) ;
18- console . log ( `ok ${ name } ` ) ;
19- } catch ( error ) {
20- console . error ( `not ok ${ name } ` ) ;
21- throw error ;
16+ function runTest ( name : string , callback : ( ) => void | Promise < void > ) {
17+ const result = callback ( ) ;
18+ if ( result instanceof Promise ) {
19+ return result . then (
20+ ( ) => console . log ( `ok ${ name } ` ) ,
21+ ( error ) => {
22+ console . error ( `not ok ${ name } ` ) ;
23+ throw error ;
24+ } ,
25+ ) ;
2226 }
27+
28+ console . log ( `ok ${ name } ` ) ;
2329}
2430
25- runTest ( "validates the seed shader manifest" , ( ) => {
31+ await runTest ( "validates the seed shader manifest" , ( ) => {
2632 const manifest = validateShaderManifestFile ( fixtureManifestPath ) ;
2733
2834 assert . equal ( manifest . name , "gradient-radial" ) ;
2935 assert . equal ( manifest . recipes . length , 2 ) ;
3036 assert . ok ( manifest . compatibility . environments . includes ( "three" ) ) ;
3137} ) ;
3238
33- runTest ( "validates an adapted upstream shader manifest" , ( ) => {
39+ await runTest ( "validates an adapted upstream shader manifest" , ( ) => {
3440 const manifest = validateShaderManifestFile ( sourcedFixtureManifestPath ) ;
3541
3642 assert . equal ( manifest . name , "vignette-postprocess" ) ;
@@ -42,7 +48,7 @@ runTest("validates an adapted upstream shader manifest", () => {
4248 ) ;
4349} ) ;
4450
45- runTest ( "rejects invalid uniform defaults" , ( ) => {
51+ await runTest ( "rejects invalid uniform defaults" , ( ) => {
4652 const manifest = JSON . parse ( readFileSync ( fixtureManifestPath , "utf8" ) ) as Record < string , unknown > ;
4753 const uniforms = manifest . uniforms as Array < Record < string , unknown > > ;
4854
@@ -53,7 +59,7 @@ runTest("rejects invalid uniform defaults", () => {
5359 assert . equal ( result . success , false ) ;
5460} ) ;
5561
56- runTest ( "rejects adapted manifests without exact provenance" , ( ) => {
62+ await runTest ( "rejects adapted manifests without exact provenance" , ( ) => {
5763 const manifest = JSON . parse ( readFileSync ( fixtureManifestPath , "utf8" ) ) as Record < string , unknown > ;
5864
5965 manifest . provenance = {
@@ -69,7 +75,7 @@ runTest("rejects adapted manifests without exact provenance", () => {
6975 assert . equal ( result . success , false ) ;
7076} ) ;
7177
72- runTest ( "rejects missing referenced files" , ( ) => {
78+ await runTest ( "rejects missing referenced files" , ( ) => {
7379 const tempDirectory = mkdtempSync ( join ( tmpdir ( ) , "shaderbase-schema-" ) ) ;
7480 const shaderDirectory = join ( tempDirectory , "gradient-radial" ) ;
7581 const recipeDirectory = join ( shaderDirectory , "recipes" ) ;
@@ -104,7 +110,7 @@ runTest("rejects missing referenced files", () => {
104110 }
105111} ) ;
106112
107- runTest ( "defaults language to glsl when missing" , ( ) => {
113+ await runTest ( "defaults language to glsl when missing" , ( ) => {
108114 const manifest = JSON . parse ( readFileSync ( fixtureManifestPath , "utf8" ) ) as Record < string , unknown > ;
109115 delete manifest . language ;
110116
@@ -115,7 +121,7 @@ runTest("defaults language to glsl when missing", () => {
115121 }
116122} ) ;
117123
118- runTest ( "validates a TSL manifest" , ( ) => {
124+ await runTest ( "validates a TSL manifest" , ( ) => {
119125 const manifest = JSON . parse ( readFileSync ( fixtureManifestPath , "utf8" ) ) as Record < string , unknown > ;
120126 manifest . language = "tsl" ;
121127 manifest . tslEntry = "source.ts" ;
@@ -133,7 +139,7 @@ runTest("validates a TSL manifest", () => {
133139 }
134140} ) ;
135141
136- runTest ( "rejects TSL manifest without tslEntry" , ( ) => {
142+ await runTest ( "rejects TSL manifest without tslEntry" , ( ) => {
137143 const manifest = JSON . parse ( readFileSync ( fixtureManifestPath , "utf8" ) ) as Record < string , unknown > ;
138144 manifest . language = "tsl" ;
139145 delete manifest . files ;
@@ -142,4 +148,34 @@ runTest("rejects TSL manifest without tslEntry", () => {
142148 assert . equal ( result . success , false ) ;
143149} ) ;
144150
151+ await runTest ( "buildTslPreviewModule binds runtime imports inside createPreview" , async ( ) => {
152+ const previewModule = buildTslPreviewModule ( `
153+ import { color } from 'three/tsl';
154+ import { NodeMaterial } from 'three/webgpu';
155+
156+ export function createMaterial() {
157+ const material = new NodeMaterial();
158+ material.colorNode = color(0xff0000);
159+ return material;
160+ }
161+ ` ) ;
162+
163+ const module = await import ( `data:text/javascript,${ encodeURIComponent ( previewModule ) } ` ) ;
164+
165+ class FakeNodeMaterial {
166+ colorNode ?: number ;
167+ }
168+
169+ const preview = module . createPreview ( {
170+ THREE : { NodeMaterial : FakeNodeMaterial } ,
171+ TSL : { color : ( value : number ) => value } ,
172+ width : 512 ,
173+ height : 512 ,
174+ pipeline : "surface" ,
175+ } ) ;
176+
177+ assert . ok ( preview . material instanceof FakeNodeMaterial ) ;
178+ assert . equal ( ( preview . material as FakeNodeMaterial ) . colorNode , 0xff0000 ) ;
179+ } ) ;
180+
145181console . log ( "schema tests passed" ) ;
0 commit comments