|
14 | 14 |
|
15 | 15 | from nunavut import Namespace |
16 | 16 | from nunavut._namespace import build_namespace_tree # deprecated |
17 | | -from nunavut.jinja import DSDLCodeGenerator |
18 | | -from nunavut.jinja.jinja2.exceptions import TemplateAssertionError |
| 17 | +from nunavut.jinja import DSDLCodeGenerator, SupportGenerator |
| 18 | +from nunavut.jinja.jinja2.exceptions import TemplateAssertionError, UndefinedError |
19 | 19 | from nunavut.lang import Language, LanguageClassLoader, LanguageContextBuilder |
20 | 20 |
|
21 | 21 |
|
@@ -448,3 +448,75 @@ def test_filter_to_template_unique(gen_paths): |
448 | 448 | actual = foo_file.read() |
449 | 449 |
|
450 | 450 | assert expected == actual |
| 451 | + |
| 452 | + |
| 453 | +def test_support_generator_filter_isolation(gen_paths): # type: ignore |
| 454 | + """ |
| 455 | + Test that DSDL-specific filters are not available in SupportGenerator templates. |
| 456 | + This verifies that suggestion #2 (creating different environment objects per generator) |
| 457 | + is properly implemented, preventing filter leaking between generators. |
| 458 | + """ |
| 459 | + root_path = str(gen_paths.dsdl_dir / Path("uavcan")) |
| 460 | + output_path = gen_paths.out_dir / "filter_isolation" |
| 461 | + compound_types = read_namespace(root_path, []) |
| 462 | + language_context = LanguageContextBuilder().set_target_language("c").create() |
| 463 | + namespace = build_namespace_tree(compound_types, root_path, output_path, language_context) |
| 464 | + |
| 465 | + # Create a template that tries to use a DSDL-specific filter |
| 466 | + template_dir = gen_paths.out_dir / "filter_isolation_templates" |
| 467 | + template_dir.mkdir(parents=True, exist_ok=True) |
| 468 | + template_file = template_dir / "serialization.j2" |
| 469 | + |
| 470 | + # This template tries to use type_to_template, which should only be available in DSDLCodeGenerator |
| 471 | + with open(template_file, "w", encoding="utf-8") as f: |
| 472 | + f.write("{{ 'test' | type_to_template }}") |
| 473 | + |
| 474 | + # Create a SupportGenerator with this template |
| 475 | + from nunavut._utilities import ResourceType |
| 476 | + support_generator = SupportGenerator( |
| 477 | + namespace, |
| 478 | + resource_types=ResourceType.SERIALIZATION_SUPPORT.value, |
| 479 | + templates_dir=template_dir |
| 480 | + ) |
| 481 | + |
| 482 | + # Attempting to generate should fail because type_to_template filter is not available |
| 483 | + # in SupportGenerator's environment |
| 484 | + with pytest.raises((TemplateAssertionError, UndefinedError, AttributeError)) as exc_info: |
| 485 | + list(support_generator.generate_all()) |
| 486 | + |
| 487 | + # Verify the error message mentions the missing filter |
| 488 | + error_message = str(exc_info.value) |
| 489 | + assert "type_to_template" in error_message.lower() or "no filter" in error_message.lower() |
| 490 | + |
| 491 | + |
| 492 | +def test_dsdl_generator_has_dsdl_filters(gen_paths): # type: ignore |
| 493 | + """ |
| 494 | + Test that DSDL-specific filters ARE available in DSDLCodeGenerator templates. |
| 495 | + This is the positive test case for filter isolation. |
| 496 | + """ |
| 497 | + root_path = str(gen_paths.dsdl_dir / Path("uavcan")) |
| 498 | + output_path = gen_paths.out_dir / "dsdl_filter_test" |
| 499 | + compound_types = read_namespace(root_path, []) |
| 500 | + language_context = LanguageContextBuilder().set_target_language("c").create() |
| 501 | + namespace = build_namespace_tree(compound_types, root_path, output_path, language_context) |
| 502 | + |
| 503 | + # Create a template that uses DSDL-specific filters |
| 504 | + template_dir = gen_paths.out_dir / "dsdl_filter_test_templates" |
| 505 | + template_dir.mkdir(parents=True, exist_ok=True) |
| 506 | + template_file = template_dir / "Any.j2" |
| 507 | + |
| 508 | + # This template uses type_to_template, which should be available in DSDLCodeGenerator |
| 509 | + with open(template_file, "w", encoding="utf-8") as f: |
| 510 | + f.write("{{ T | type_to_template }}") |
| 511 | + |
| 512 | + # Create a DSDLCodeGenerator with this template |
| 513 | + dsdl_generator = DSDLCodeGenerator( |
| 514 | + namespace, |
| 515 | + templates_dir=template_dir |
| 516 | + ) |
| 517 | + |
| 518 | + # This should work without errors |
| 519 | + generated_files = list(dsdl_generator.generate_all()) |
| 520 | + |
| 521 | + # Verify that files were generated successfully |
| 522 | + assert len(generated_files) > 0 |
0 commit comments