11import p5 from '../../../src/app.js' ;
2- import { vi } from 'vitest' ;
2+ import { beforeEach , vi } from 'vitest' ;
33
44const mockUserError = vi . fn ( ) ;
5- vi . mock ( '../../../src/strands/strands_FES' , ( ) => ( {
6- userError : ( ...args ) => {
5+ vi . mock ( '../../../src/strands/strands_FES' , ( ) => {
6+ const userError = ( ...args ) => {
77 mockUserError ( ...args ) ;
88 const prefixedMessage = `[p5.strands ${ args [ 0 ] } ]: ${ args [ 1 ] } ` ;
99 throw new Error ( prefixedMessage ) ;
10- } ,
11- internalError : ( msg ) => { throw new Error ( `[p5.strands internal error]: ${ msg } ` ) ; }
12- } ) ) ;
10+ } ;
11+ return {
12+ userError,
13+ internalError : ( msg ) => { throw new Error ( `[p5.strands internal error]: ${ msg } ` ) ; } ,
14+ dimensionMismatchError : ( declaredDim , actualDim , varName ) => {
15+ userError (
16+ 'dimension mismatch' ,
17+ `Cannot assign a value of dimension ${ actualDim } to \`${ varName } \`, which expects dimension ${ declaredDim } .`
18+ ) ;
19+ } ,
20+ } ;
21+ } ) ;
1322
1423suite ( 'p5.Shader' , function ( ) {
1524 var myp5 ;
@@ -2608,6 +2617,48 @@ test('returns numbers for builtin globals outside hooks and a strandNode when ca
26082617 assert . approximately ( pixelColor [ 1 ] , 0 , 5 ) ;
26092618 assert . approximately ( pixelColor [ 2 ] , 0 , 5 ) ;
26102619 } ) ;
2620+
2621+ test ( 'reports a friendly error when assigning a scalar to a sharedVec3 (bridge)' , async ( ) => {
2622+ await myp5 . createCanvas ( 5 , 5 , myp5 . WEBGL ) ;
2623+
2624+ expect ( ( ) => {
2625+ myp5 . baseMaterialShader ( ) . modify ( ( ) => {
2626+ let worldPosX = myp5 . sharedVec3 ( ) ;
2627+ myp5 . getWorldInputs ( inputs => {
2628+ worldPosX = inputs . position . x ; // scalar → vec3 mismatch
2629+ return inputs ;
2630+ } ) ;
2631+ } , { myp5} ) ;
2632+ } ) . toThrow ( / d i m e n s i o n m i s m a t c h / ) ;
2633+ } ) ;
2634+
2635+ test ( 'reports a friendly error on dimension mismatch via swizzle write (bridgeSwizzle)' , async ( ) => {
2636+ await myp5 . createCanvas ( 5 , 5 , myp5 . WEBGL ) ;
2637+
2638+ expect ( ( ) => {
2639+ myp5 . baseMaterialShader ( ) . modify ( ( ) => {
2640+ let myVec = myp5 . sharedVec3 ( ) ;
2641+ myp5 . getWorldInputs ( inputs => {
2642+ myVec . xy = inputs . position ; // vec3 → 2-component swizzle mismatch
2643+ return inputs ;
2644+ } ) ;
2645+ } , { myp5} ) ;
2646+ } ) . toThrow ( / d i m e n s i o n m i s m a t c h / ) ;
2647+ } ) ;
2648+
2649+ test ( 'does not error when shared variable assignment dimensions match' , async ( ) => {
2650+ await myp5 . createCanvas ( 5 , 5 , myp5 . WEBGL ) ;
2651+
2652+ expect ( ( ) => {
2653+ myp5 . baseMaterialShader ( ) . modify ( ( ) => {
2654+ let myVec = myp5 . sharedVec3 ( ) ;
2655+ myp5 . getWorldInputs ( inputs => {
2656+ myVec = inputs . position ; // vec3 → vec3, OK
2657+ return inputs ;
2658+ } ) ;
2659+ } , { myp5} ) ;
2660+ } ) . not . toThrow ( ) ;
2661+ } ) ;
26112662 } ) ;
26122663
26132664 suite ( 'p5.strands error messages' , ( ) => {
@@ -2625,7 +2676,7 @@ test('returns numbers for builtin globals outside hooks and a strandNode when ca
26252676 assert . include ( err . message , '// noprotect' ) ;
26262677 } ;
26272678
2628- afterEach ( ( ) => {
2679+ beforeEach ( ( ) => {
26292680 mockUserError . mockClear ( ) ;
26302681 } ) ;
26312682
0 commit comments