66from django .template .exceptions import TemplateSyntaxError
77
88from django_bird .templatetags .tags .slot import parse_slot_name
9+ from tests .conftest import TestComponent
10+ from tests .conftest import TestComponentCase
911
1012
1113@pytest .mark .parametrize (
@@ -30,100 +32,235 @@ def test_parse_slot_name_no_args():
3032
3133class TestTemplateTag :
3234 @pytest .mark .parametrize (
33- "template,context,expected " ,
35+ "component_content " ,
3436 [
35- ("{{ slot }}" , {"slot" : "test" }, "test" ),
36- ("{% bird:slot %}{% endbird:slot %}" , {"slot" : "test" }, "test" ),
37- ("{% bird:slot default %}{% endbird:slot %}" , {"slot" : "test" }, "test" ),
38- ("{% bird:slot 'default' %}{% endbird:slot %}" , {"slot" : "test" }, "test" ),
39- ('{% bird:slot "default" %}{% endbird:slot %}' , {"slot" : "test" }, "test" ),
40- (
41- "{% bird:slot name='default' %}{% endbird:slot %}" ,
42- {"slot" : "test" },
43- "test" ,
44- ),
45- (
46- '{% bird:slot name="default" %}{% endbird:slot %}' ,
47- {"slot" : "test" },
48- "test" ,
49- ),
50- (
51- "{% bird:slot name='not-default' %}{% endbird:slot %}" ,
52- {"slot" : "test" },
53- "" ,
37+ "{{ slot }}" ,
38+ "{% bird:slot %}{% endbird:slot %}" ,
39+ "{% bird:slot default %}{% endbird:slot %}" ,
40+ "{% bird:slot 'default' %}{% endbird:slot %}" ,
41+ '{% bird:slot "default" %}{% endbird:slot %}' ,
42+ "{% bird:slot name=default %}{% endbird:slot %}" ,
43+ "{% bird:slot name='default' %}{% endbird:slot %}" ,
44+ '{% bird:slot name="default" %}{% endbird:slot %}' ,
45+ ],
46+ )
47+ def test_default_slot (self , component_content , templates_dir , normalize_whitespace ):
48+ test_case = TestComponentCase (
49+ component = TestComponent (
50+ name = "test" ,
51+ content = component_content ,
5452 ),
55- (
56- "{% bird:slot outer %}Outer {% bird:slot inner %}Inner{% endbird:slot %} Content{% endbird:slot %}" ,
57- {"slots" : {"outer" : "Replaced Content" }},
58- "Replaced Content" ,
53+ template_content = "{% bird test %}Content{% endbird %}" ,
54+ template_context = {"slot" : "Content" },
55+ expected = "Content" ,
56+ )
57+ test_case .component .create (templates_dir )
58+
59+ template = Template (test_case .template_content )
60+ rendered = template .render (Context (test_case .template_context ))
61+
62+ assert normalize_whitespace (rendered ) == test_case .expected
63+
64+ def test_default_content (self , templates_dir , normalize_whitespace ):
65+ test_case = TestComponentCase (
66+ component = TestComponent (
67+ name = "test" ,
68+ content = """
69+ <button>
70+ {% bird:slot leading-icon %}
71+ <span>Default icon</span>
72+ {% endbird:slot %}
73+
74+ {% bird:slot %}
75+ Click me
76+ {% endbird:slot %}
77+ </button>
78+ """ ,
5979 ),
60- (
61- "{% bird:slot outer %}Outer {% bird:slot inner %}Inner{% endbird:slot %} Content{% endbird:slot %}" ,
62- {"slots" : {"inner" : "Replaced Content" }},
63- "Outer Replaced Content Content" ,
80+ template_content = "{% bird test %}{% endbird %}" ,
81+ expected = "<button><span>Default icon</span>Click me</button>" ,
82+ )
83+ test_case .component .create (templates_dir )
84+
85+ template = Template (test_case .template_content )
86+ rendered = template .render (Context ({}))
87+
88+ assert normalize_whitespace (rendered ) == test_case .expected
89+
90+ def test_default_content_override (self , templates_dir , normalize_whitespace ):
91+ test_case = TestComponentCase (
92+ component = TestComponent (
93+ name = "test" ,
94+ content = """
95+ <button>
96+ {% bird:slot leading-icon %}
97+ <span>Default icon</span>
98+ {% endbird:slot %}
99+
100+ {% bird:slot %}
101+ Click me
102+ {% endbird:slot %}
103+ </button>
104+ """ ,
64105 ),
65- (
66- "{% bird:slot outer %}Outer {% bird:slot inner %}Inner Default{% endbird:slot %} Content{% endbird:slot %}" ,
67- {
68- "slots" : {
69- "outer" : "Replaced {% bird:slot inner %}{% endbird:slot %} Outer" ,
70- "inner" : "Replaced Inner" ,
71- },
72- },
73- "Replaced Replaced Inner Outer" ,
106+ template_content = """
107+ {% bird test %}
108+ {% bird:slot leading-icon %}→{% endbird:slot %}
109+ Submit
110+ {% endbird %}
111+ """ ,
112+ expected = "<button>→ Submit</button>" ,
113+ )
114+ test_case .component .create (templates_dir )
115+
116+ template = Template (test_case .template_content )
117+ rendered = template .render (Context ({}))
118+
119+ assert normalize_whitespace (rendered ) == test_case .expected
120+
121+ @pytest .mark .parametrize (
122+ "component_content" ,
123+ [
124+ "{{ slots.named_slot }}" ,
125+ "{% bird:slot named_slot %}{% endbird:slot %}" ,
126+ "{% bird:slot name=named_slot %}{% endbird:slot %}" ,
127+ ],
128+ )
129+ def test_named_slot (self , component_content , templates_dir , normalize_whitespace ):
130+ test_case = TestComponentCase (
131+ component = TestComponent (
132+ name = "test" ,
133+ content = component_content ,
74134 ),
75- (
76- "{{ slot }}" ,
77- {
78- "slot" : "Replaced {% bird:slot inner %}{% endbird:slot %} Outer" ,
79- "slots" : {
80- "inner" : "Replaced Inner" ,
81- },
135+ template_content = """
136+ {% bird test %}
137+ {% bird:slot named_slot %}{% endbird:slot %}
138+ {% endbird %}
139+ """ ,
140+ template_context = {
141+ "slots" : {
142+ "named_slot" : "Content" ,
82143 },
83- "Replaced Replaced Inner Outer" ,
84- ),
85- (
86- "{% bird:slot %}{% endbird:slot %}" ,
87- {},
88- "" ,
89- ),
90- (
91- "{% bird:slot %}Default content{% endbird:slot %}" ,
92- {},
93- "Default content" ,
144+ },
145+ expected = "Content" ,
146+ )
147+ test_case .component .create (templates_dir )
148+
149+ template = Template (test_case .template_content )
150+ rendered = template .render (Context (test_case .template_context ))
151+
152+ assert normalize_whitespace (rendered ) == test_case .expected
153+
154+ @pytest .mark .parametrize (
155+ "test_case" ,
156+ [
157+ TestComponentCase (
158+ description = "Outer slot replacement" ,
159+ component = TestComponent (
160+ name = "test" ,
161+ content = """
162+ {% bird:slot outer %}
163+ Outer {% bird:slot inner %}Inner{% endbird:slot %} Content
164+ {% endbird:slot %}
165+ """ ,
166+ ),
167+ template_content = """
168+ {% bird test %}
169+ {% bird:slot outer %}Replaced Content{% endbird:slot %}
170+ {% endbird %}
171+ """ ,
172+ expected = "Replaced Content" ,
94173 ),
95- (
96- "{% bird:slot 'mal formed' %}{% endbird:slot %}" ,
97- {"slots" : {"mal formed" : "content" }},
98- "content" ,
174+ TestComponentCase (
175+ description = "Inner slot replacement" ,
176+ component = TestComponent (
177+ name = "test" ,
178+ content = """
179+ {% bird:slot outer %}
180+ Outer {% bird:slot inner %}Inner{% endbird:slot %} Content
181+ {% endbird:slot %}
182+ """ ,
183+ ),
184+ template_content = """
185+ {% bird test %}
186+ {% bird:slot inner %}Replaced Content{% endbird:slot %}
187+ {% endbird %}
188+ """ ,
189+ expected = "Outer Replaced Content Content" ,
99190 ),
100- (
101- "{% bird:slot CaseSensitive %}{% endbird:slot %}" ,
102- {"slots" : {"CaseSensitive" : "Upper" , "casesensitive" : "Lower" }},
103- "Upper" ,
191+ TestComponentCase (
192+ description = "Both slots replaced" ,
193+ component = TestComponent (
194+ name = "test" ,
195+ content = """
196+ {% bird:slot outer %}
197+ Outer {% bird:slot inner %}Inner{% endbird:slot %} Content
198+ {% endbird:slot %}
199+ """ ,
200+ ),
201+ template_content = """
202+ {% bird test %}
203+ {% bird:slot outer %}
204+ New {% bird:slot inner %}Nested{% endbird:slot %} Text
205+ {% endbird:slot %}
206+ {% endbird %}
207+ """ ,
208+ expected = "New Nested Text" ,
104209 ),
105- (
106- "{% bird:slot %}{% endbird:slot %}" ,
107- {"slots" : {"default" : 42 }},
108- "42" ,
210+ ],
211+ ids = lambda x : x .description ,
212+ )
213+ def test_nested_slots (self , test_case , templates_dir , normalize_whitespace ):
214+ test_case .component .create (templates_dir )
215+
216+ template = Template (test_case .template_content )
217+ rendered = template .render (Context (test_case .template_context ))
218+
219+ assert normalize_whitespace (rendered ) == test_case .expected
220+
221+ @pytest .mark .parametrize (
222+ "test_case" ,
223+ [
224+ TestComponentCase (
225+ description = "Variable in slot" ,
226+ component = TestComponent (
227+ name = "test" ,
228+ content = "{% bird:slot %}{% endbird:slot %}" ,
229+ ),
230+ template_content = "{% bird test %}{{ message }}{% endbird %}" ,
231+ template_context = {"message" : "Hello World" },
232+ expected = "Hello World" ,
109233 ),
110- (
111- "{% bird:slot %}{% endbird:slot %}" ,
112- {"slots" : {"default" : "<b>Bold</b>" }},
113- "<b>Bold</b>" ,
234+ TestComponentCase (
235+ description = "Nested variable in slot" ,
236+ component = TestComponent (
237+ name = "test" ,
238+ content = "{% bird:slot %}{% endbird:slot %}" ,
239+ ),
240+ template_content = "{% bird test %}{{ user.name }}{% endbird %}" ,
241+ template_context = {"user" : {"name" : "John" }},
242+ expected = "John" ,
114243 ),
115- (
116- "{% bird:slot unicode_slot %}{% endbird:slot %}" ,
117- {"slots" : {"unicode_slot" : "こんにちは" }},
118- "こんにちは" ,
244+ TestComponentCase (
245+ description = "Template tag in slot" ,
246+ component = TestComponent (
247+ name = "test" ,
248+ content = "{% bird:slot %}{% endbird:slot %}" ,
249+ ),
250+ template_content = "{% bird test %}{% if show %}Show{% endif %}{% endbird %}" ,
251+ template_context = {"show" : True },
252+ expected = "Show" ,
119253 ),
120254 ],
255+ ids = lambda x : x .description ,
121256 )
122- def test_rendering (self , template , context , expected , create_bird_template ):
123- create_bird_template ("test" , template )
124- t = Template (f"{{% bird test %}}{ template } {{% endbird %}}" )
125- rendered = t .render (context = Context (context ))
126- assert rendered == expected
257+ def test_template_content (self , test_case , templates_dir , normalize_whitespace ):
258+ test_case .component .create (templates_dir )
259+
260+ template = Template (test_case .template_content )
261+ rendered = template .render (Context (test_case .template_context ))
262+
263+ assert normalize_whitespace (rendered ) == test_case .expected
127264
128265 def test_too_many_args (self ):
129266 with pytest .raises (TemplateSyntaxError ):
0 commit comments