1- from  dataclasses  import  dataclass 
1+ from  dataclasses  import  dataclass ,  field 
22from  pathlib  import  Path 
33from  typing  import  Any 
44
@@ -25,6 +25,7 @@ class JinjaTestCase:
2525    template : str 
2626    variables : dict [str , Any ]
2727    expected : str 
28+     expected_variables : list [str ] =  field (default_factory = list )
2829
2930
3031@dataclass  
@@ -41,24 +42,28 @@ class JinjaTestCaseFailing:
4142        template = "Hello {{ name }}" ,
4243        variables = {"name" : "Infrahub" },
4344        expected = "Hello Infrahub" ,
45+         expected_variables = ["name" ],
4446    ),
4547    JinjaTestCase (
4648        name = "hello-if-defined" ,
4749        template = "Hello {% if name is undefined %}stranger{% else %}{{name}}{% endif %}" ,
4850        variables = {"name" : "OpsMill" },
4951        expected = "Hello OpsMill" ,
52+         expected_variables = ["name" ],
5053    ),
5154    JinjaTestCase (
5255        name = "hello-if-undefined" ,
5356        template = "Hello {% if name is undefined %}stranger{% else %}{{name}}{% endif %}" ,
5457        variables = {},
5558        expected = "Hello stranger" ,
59+         expected_variables = ["name" ],
5660    ),
5761    JinjaTestCase (
5862        name = "netutils-ip-addition" ,
5963        template = "IP={{ ip_address|ip_addition(200) }}" ,
6064        variables = {"ip_address" : "192.168.12.15" },
6165        expected = "IP=192.168.12.215" ,
66+         expected_variables = ["ip_address" ],
6267    ),
6368]
6469
@@ -68,10 +73,9 @@ class JinjaTestCaseFailing:
6873    [pytest .param (tc , id = tc .name ) for  tc  in  SUCCESSFUL_STRING_TEST_CASES ], 
6974) 
7075async  def  test_render_string (test_case : JinjaTestCase ) ->  None :
71-     jinja  =  Jinja2Template ()
72-     assert  test_case .expected  ==  await  jinja .render_from_string (
73-         template = test_case .template , variables = test_case .variables 
74-     )
76+     jinja  =  Jinja2Template (template = test_case .template )
77+     assert  test_case .expected  ==  await  jinja .render (variables = test_case .variables )
78+     assert  test_case .expected_variables  ==  jinja .get_variables ()
7579
7680
7781SUCCESSFUL_FILE_TEST_CASES  =  [
@@ -80,12 +84,14 @@ async def test_render_string(test_case: JinjaTestCase) -> None:
8084        template = "hello-world.j2" ,
8185        variables = {"name" : "Infrahub" },
8286        expected = "Hello Infrahub" ,
87+         expected_variables = ["name" ],
8388    ),
8489    JinjaTestCase (
8590        name = "netutils-convert-address" ,
8691        template = "ip_report.j2" ,
8792        variables = {"address" : "192.168.18.40/255.255.255.0" },
8893        expected = "IP Address: 192.168.18.40/24" ,
94+         expected_variables = ["address" ],
8995    ),
9096]
9197
@@ -95,10 +101,9 @@ async def test_render_string(test_case: JinjaTestCase) -> None:
95101    [pytest .param (tc , id = tc .name ) for  tc  in  SUCCESSFUL_FILE_TEST_CASES ], 
96102) 
97103async  def  test_render_template_from_file (test_case : JinjaTestCase ) ->  None :
98-     jinja  =  Jinja2Template (template_directory = TEMPLATE_DIRECTORY )
99-     assert  test_case .expected  ==  await  jinja .render_from_file (
100-         template = Path (test_case .template ), variables = test_case .variables 
101-     )
104+     jinja  =  Jinja2Template (template = Path (test_case .template ), template_directory = TEMPLATE_DIRECTORY )
105+     assert  test_case .expected  ==  await  jinja .render (variables = test_case .variables )
106+     assert  test_case .expected_variables  ==  jinja .get_variables ()
102107
103108
104109FAILING_STRING_TEST_CASES  =  [
@@ -142,9 +147,9 @@ async def test_render_template_from_file(test_case: JinjaTestCase) -> None:
142147    [pytest .param (tc , id = tc .name ) for  tc  in  FAILING_STRING_TEST_CASES ], 
143148) 
144149async  def  test_render_string_errors (test_case : JinjaTestCaseFailing ) ->  None :
145-     jinja  =  Jinja2Template (template_directory = TEMPLATE_DIRECTORY )
150+     jinja  =  Jinja2Template (template = test_case . template ,  template_directory = TEMPLATE_DIRECTORY )
146151    with  pytest .raises (test_case .error .__class__ ) as  exc :
147-         await  jinja .render_from_string ( template = test_case . template ,  variables = test_case .variables )
152+         await  jinja .render ( variables = test_case .variables )
148153
149154    _compare_errors (expected = test_case .error , received = exc .value )
150155
@@ -189,6 +194,23 @@ async def test_render_string_errors(test_case: JinjaTestCaseFailing) -> None:
189194            base_template = "imports-missing-file.html" ,
190195        ),
191196    ),
197+     JinjaTestCaseFailing (
198+         name = "invalid-variable-input" ,
199+         template = "report.html" ,
200+         variables = {"servers" : [{"name" : "server1" , "ip" : {"primary" : "172.18.12.1" }}, {"name" : "server1" }]},
201+         error = JinjaTemplateUndefinedError (
202+             message = "'dict object' has no attribute 'ip'" ,
203+             errors = [
204+                 UndefinedJinja2Error (
205+                     frame = Frame (filename = f"{ TEMPLATE_DIRECTORY }  , lineno = 5 , name = "top-level template code" ),
206+                     syntax = Syntax (
207+                         code = "<html>\n <body>\n <ul>\n {% for server in servers %}\n     <li>{{server.name}}: {{ server.ip.primary }}</li>\n {% endfor %}\n </ul>\n \n </body>\n \n </html>\n " ,  # noqa E501 
208+                         lexer = "" ,
209+                     ),
210+                 )
211+             ],
212+         ),
213+     ),
192214]
193215
194216
@@ -197,18 +219,18 @@ async def test_render_string_errors(test_case: JinjaTestCaseFailing) -> None:
197219    [pytest .param (tc , id = tc .name ) for  tc  in  FAILING_FILE_TEST_CASES ], 
198220) 
199221async  def  test_manage_file_based_errors (test_case : JinjaTestCaseFailing ) ->  None :
200-     jinja  =  Jinja2Template (template_directory = TEMPLATE_DIRECTORY )
222+     jinja  =  Jinja2Template (template = Path ( test_case . template ),  template_directory = TEMPLATE_DIRECTORY )
201223    with  pytest .raises (test_case .error .__class__ ) as  exc :
202-         await  jinja .render_from_file ( template = Path ( test_case . template ),  variables = test_case .variables )
224+         await  jinja .render ( variables = test_case .variables )
203225
204226    _compare_errors (expected = test_case .error , received = exc .value )
205227
206228
207229async  def  test_manage_unhandled_error () ->  None :
208-     jinja  =  Jinja2Template ()
230+     jinja  =  Jinja2Template (template = "Hello {{ number | divide_by_zero }}" )
209231    jinja ._filters ["divide_by_zero" ] =  _divide_by_zero 
210232    with  pytest .raises (JinjaTemplateError ) as  exc :
211-         await  jinja .render_from_string ( template = "Hello {{ number | divide_by_zero }}" ,  variables = {"number" : 1 })
233+         await  jinja .render ( variables = {"number" : 1 })
212234
213235    assert  exc .value .message  ==  "division by zero" 
214236
0 commit comments