@@ -271,5 +271,163 @@ def test_regression_reference_members(self):
271271 # The constructor parameter SHOULD be a reference
272272 self .assertIn ("VIDL_vhBeginMarker(const std::string& _name)" , output )
273273
274+
275+ class TestVidlStorage (unittest .TestCase ):
276+
277+ def test_no_annotation_unchanged (self ):
278+ src = """
279+ // VIDL_GENERATE
280+ void foo( int a, std::vector<int> b );
281+ """
282+ out = vidl .generate_source (src )
283+ self .assertIn ("int a;" , out )
284+ self .assertIn ("std::vector<int> b;" , out )
285+ self .assertIn ("foo(int _a, std::vector<int> _b)" , out )
286+
287+ def test_single_storage_override (self ):
288+ src = """
289+ // VIDL_GENERATE
290+ // VIDL_STORAGE: b = MySpan<int>
291+ void foo( int a, std::vector<int> b );
292+ """
293+ out = vidl .generate_source (src )
294+ self .assertIn ("int a;" , out )
295+ self .assertIn ("MySpan<int> b;" , out )
296+ self .assertNotIn ("std::vector<int> b;" , out )
297+ self .assertIn ("foo(int _a, MySpan<int> _b)" , out )
298+
299+ def test_multiple_overrides_one_func (self ):
300+ src = """
301+ // VIDL_GENERATE
302+ // VIDL_STORAGE: a = ArenaA
303+ // VIDL_STORAGE: b = ArenaB
304+ void foo( int a, int b, int c );
305+ """
306+ out = vidl .generate_source (src )
307+ self .assertIn ("ArenaA a;" , out )
308+ self .assertIn ("ArenaB b;" , out )
309+ self .assertIn ("int c;" , out )
310+ self .assertIn ("foo(ArenaA _a, ArenaB _b, int _c)" , out )
311+
312+ def test_override_with_template_args (self ):
313+ src = """
314+ // VIDL_GENERATE
315+ // VIDL_STORAGE: data = vhArenaSpan< glm::mat4 >
316+ void foo( vhStateId id, std::vector< glm::mat4 > data );
317+ """
318+ out = vidl .generate_source (src )
319+ self .assertIn ("vhArenaSpan< glm::mat4 > data;" , out )
320+ self .assertIn ("vhStateId _id, vhArenaSpan< glm::mat4 > _data" , out )
321+
322+ def test_whitespace_tolerance (self ):
323+ src = """
324+ // VIDL_GENERATE
325+ //VIDL_STORAGE:b=MyType
326+ void foo( int a, int b );
327+ """
328+ out = vidl .generate_source (src )
329+ self .assertIn ("MyType b;" , out )
330+
331+ def test_annotation_scoped_to_one_block (self ):
332+ src = """
333+ // VIDL_GENERATE
334+ // VIDL_STORAGE: x = OverrideA
335+ void foo( int x );
336+
337+ // VIDL_GENERATE
338+ void bar( int x );
339+ """
340+ out = vidl .generate_source (src )
341+ self .assertIn ("OverrideA x;" , out )
342+ foo_idx = out .index ("VIDL_foo" )
343+ bar_idx = out .index ("VIDL_bar" )
344+ bar_section = out [bar_idx :]
345+ self .assertNotIn ("OverrideA" , bar_section )
346+ self .assertIn ("int x;" , bar_section )
347+
348+ def test_keyword_param_name_with_override (self ):
349+ src = """
350+ // VIDL_GENERATE
351+ // VIDL_STORAGE: class = MyClass
352+ void foo( int class );
353+ """
354+ out = vidl .generate_source (src )
355+ self .assertIn ("MyClass class_;" , out )
356+ self .assertIn ("MyClass _class_" , out )
357+
358+ def test_magic_constants_stable_with_override (self ):
359+ src_no = "// VIDL_GENERATE\n void foo( std::vector<int> a );"
360+ src_yes = (
361+ "// VIDL_GENERATE\n "
362+ "// VIDL_STORAGE: a = MySpan\n "
363+ "void foo( std::vector<int> a );"
364+ )
365+ m1 = re .search (r"kMagic = (\w+)" , vidl .generate_source (src_no )).group (1 )
366+ m2 = re .search (r"kMagic = (\w+)" , vidl .generate_source (src_yes )).group (1 )
367+ self .assertEqual (m1 , m2 )
368+
369+ def test_unknown_param_name_raises (self ):
370+ src = """
371+ // VIDL_GENERATE
372+ // VIDL_STORAGE: typo = MyType
373+ void foo( int a );
374+ """
375+ with self .assertRaises (ValueError ) as ctx :
376+ vidl .generate_source (src )
377+ msg = str (ctx .exception )
378+ self .assertIn ("typo" , msg )
379+ self .assertIn ("foo" , msg )
380+ self .assertIn ("a" , msg )
381+
382+ def test_duplicate_annotation_raises (self ):
383+ src = """
384+ // VIDL_GENERATE
385+ // VIDL_STORAGE: x = TypeA
386+ // VIDL_STORAGE: x = TypeB
387+ void foo( int x );
388+ """
389+ with self .assertRaises (ValueError ) as ctx :
390+ vidl .generate_source (src )
391+ msg = str (ctx .exception )
392+ self .assertIn ("duplicate" , msg )
393+ self .assertIn ("x" , msg )
394+ self .assertIn ("foo" , msg )
395+
396+ def test_default_value_preserved_with_override (self ):
397+ src = """
398+ // VIDL_GENERATE
399+ // VIDL_STORAGE: x = MyType
400+ void foo( int x = 5 );
401+ """
402+ out = vidl .generate_source (src )
403+ self .assertIn ("MyType x = 5;" , out )
404+
405+ def test_override_only_named_param_affected (self ):
406+ src = """
407+ // VIDL_GENERATE
408+ // VIDL_STORAGE: b = Overridden
409+ void foo( std::vector<int> a, std::vector<int> b, std::vector<float> c );
410+ """
411+ out = vidl .generate_source (src )
412+ self .assertIn ("std::vector<int> a;" , out )
413+ self .assertIn ("Overridden b;" , out )
414+ self .assertIn ("std::vector<float> c;" , out )
415+ self .assertNotIn ("std::vector<int> b;" , out )
416+
417+ def test_ctor_param_uses_override_not_reference (self ):
418+ # Without override, a reference param like `const std::vector<int>& v`
419+ # strips the & for the member type but keeps it in the ctor.
420+ # With an override the ctor must use the override type verbatim.
421+ src = """
422+ // VIDL_GENERATE
423+ // VIDL_STORAGE: v = MySpan
424+ void foo( const std::vector<int>& v );
425+ """
426+ out = vidl .generate_source (src )
427+ self .assertIn ("MySpan v;" , out )
428+ self .assertIn ("MySpan _v" , out )
429+ self .assertNotIn ("MySpan& _v" , out )
430+
431+
274432if __name__ == '__main__' :
275433 unittest .main ()
0 commit comments