1+ #!/usr/bin/env python
2+ # -*- coding: utf-8 -*-
3+ """
4+ Test for get_undeclared_template_variables method
5+
6+ This test demonstrates the correct behavior of get_undeclared_template_variables:
7+ 1. Before rendering - finds all template variables
8+ 2. After rendering with incomplete context - finds missing variables
9+ 3. After rendering with complete context - returns empty set
10+ """
11+
12+ from docxtpl import DocxTemplate
13+
14+ def test_before_render ():
15+ """Test that get_undeclared_template_variables finds all variables before rendering"""
16+ print ("=== Test 1: Before render ===" )
17+ tpl = DocxTemplate ('templates/get_undeclared_variables.docx' )
18+ undeclared = tpl .get_undeclared_template_variables ()
19+ print (f"Variables found: { undeclared } " )
20+
21+ # Should find all variables
22+ expected_vars = {
23+ 'name' , 'age' , 'email' , 'is_student' , 'has_degree' , 'degree_field' ,
24+ 'skills' , 'projects' , 'company_name' , 'page_number' , 'generation_date' , 'author'
25+ }
26+
27+ if undeclared == expected_vars :
28+ print ("PASS: Found all expected variables before render" )
29+ else :
30+ print (f"FAIL: Expected { expected_vars } , got { undeclared } " )
31+
32+ return undeclared == expected_vars
33+
34+ def test_after_incomplete_render ():
35+ """Test that get_undeclared_template_variables finds missing variables after incomplete render"""
36+ print ("\n === Test 2: After incomplete render ===" )
37+ tpl = DocxTemplate ('templates/get_undeclared_variables.docx' )
38+
39+ # Provide only some variables (missing several)
40+ context = {
41+ 'name' : 'John Doe' ,
42+ 'age' : 25 ,
43+ 'email' : 'john@example.com' ,
44+ 'is_student' : True ,
45+ 'skills' : ['Python' , 'Django' ],
46+ 'company_name' : 'Test Corp' ,
47+ 'author' : 'Test Author'
48+ }
49+
50+ tpl .render (context )
51+ undeclared = tpl .get_undeclared_template_variables (context = context )
52+ print (f"Missing variables: { undeclared } " )
53+
54+ # Should find missing variables
55+ expected_missing = {
56+ 'has_degree' , 'degree_field' , 'projects' , 'page_number' , 'generation_date'
57+ }
58+
59+ if undeclared == expected_missing :
60+ print ("PASS: Found missing variables after incomplete render" )
61+ else :
62+ print (f"FAIL: Expected missing { expected_missing } , got { undeclared } " )
63+
64+ return undeclared == expected_missing
65+
66+ def test_after_complete_render ():
67+ """Test that get_undeclared_template_variables returns empty set after complete render"""
68+ print ("\n === Test 3: After complete render ===" )
69+ tpl = DocxTemplate ('templates/get_undeclared_variables.docx' )
70+
71+ # Provide all variables
72+ context = {
73+ 'name' : 'John Doe' ,
74+ 'age' : 25 ,
75+ 'email' : 'john@example.com' ,
76+ 'is_student' : True ,
77+ 'has_degree' : True ,
78+ 'degree_field' : 'Computer Science' ,
79+ 'skills' : ['Python' , 'Django' , 'JavaScript' ],
80+ 'projects' : [
81+ {'name' : 'Project A' , 'year' : 2023 , 'description' : 'A great project' },
82+ {'name' : 'Project B' , 'year' : 2024 , 'description' : 'Another great project' }
83+ ],
84+ 'company_name' : 'Test Corp' ,
85+ 'page_number' : 1 ,
86+ 'generation_date' : '2024-01-15' ,
87+ 'author' : 'Test Author'
88+ }
89+
90+ tpl .render (context )
91+ undeclared = tpl .get_undeclared_template_variables (context = context )
92+ print (f"Undeclared variables: { undeclared } " )
93+
94+ # Should return empty set
95+ if undeclared == set ():
96+ print ("PASS: No undeclared variables after complete render" )
97+ else :
98+ print (f"FAIL: Expected empty set, got { undeclared } " )
99+
100+ return undeclared == set ()
101+
102+ def test_with_custom_jinja_env ():
103+ """Test that get_undeclared_template_variables works with custom Jinja environment"""
104+ print ("\n === Test 4: With custom Jinja environment ===" )
105+ from jinja2 import Environment
106+
107+ tpl = DocxTemplate ('templates/get_undeclared_variables.docx' )
108+ custom_env = Environment ()
109+
110+ undeclared = tpl .get_undeclared_template_variables (jinja_env = custom_env )
111+ print (f"Variables found with custom env: { undeclared } " )
112+
113+ # Should find all variables
114+ expected_vars = {
115+ 'name' , 'age' , 'email' , 'is_student' , 'has_degree' , 'degree_field' ,
116+ 'skills' , 'projects' , 'company_name' , 'page_number' , 'generation_date' , 'author'
117+ }
118+
119+ if undeclared == expected_vars :
120+ print ("PASS: Custom Jinja environment works correctly" )
121+ else :
122+ print (f"FAIL: Expected { expected_vars } , got { undeclared } " )
123+
124+ return undeclared == expected_vars
125+
126+ if __name__ == "__main__" :
127+ print ("Testing get_undeclared_template_variables method..." )
128+ print ("=" * 50 )
129+
130+ # Run all tests
131+ test1_passed = test_before_render ()
132+ test2_passed = test_after_incomplete_render ()
133+ test3_passed = test_after_complete_render ()
134+ test4_passed = test_with_custom_jinja_env ()
135+
136+ print ("\n " + "=" * 50 )
137+ print ("SUMMARY:" )
138+ print (f"Test 1 (Before render): { 'PASS' if test1_passed else 'FAIL' } " )
139+ print (f"Test 2 (After incomplete render): { 'PASS' if test2_passed else 'FAIL' } " )
140+ print (f"Test 3 (After complete render): { 'PASS' if test3_passed else 'FAIL' } " )
141+ print (f"Test 4 (Custom Jinja env): { 'PASS' if test4_passed else 'FAIL' } " )
142+
143+ all_passed = test1_passed and test2_passed and test3_passed and test4_passed
144+
145+ if all_passed :
146+ print ("ALL TESTS PASSED!" )
147+ else :
148+ print ("SOME TESTS FAILED!" )
149+
150+ print ("\n Note: This test demonstrates that get_undeclared_template_variables" )
151+ print ("now correctly analyzes the original template, not the rendered document." )
0 commit comments