…lines 1–27 unchanged (27 lines)
28 for template_name in [123, None, "", "#", "#name"]:
29 with (
30 self.subTest(template_name=template_name),
31 self.assertRaisesMessage(TemplateDoesNotExist, str(template_name)),
32 ):
33 engine.get_template(template_name)
34
35 def test_full_template_from_loader(self):
36 template = engine.get_template("partial_examples.html")
37 rendered = template.render({})
38
39 # Check the partial was rendered twice
40 self.assertEqual(2, rendered.count("TEST-PARTIAL-CONTENT"))
…lines 41–141 unchanged (101 lines)
142 partial = engine.get_template("partial_examples.html#test-partial")
143 with self.assertWarnsMessage(
144 RuntimeWarning,
145 "PartialTemplate.source is only available when template "
146 "debugging is enabled.",
147 ):
148 self.assertEqual(partial.template.source, "")
149
150
151class RobustPartialHandlingTests(TestCase):
152
153 def override_get_template(self, **kwargs):
154 class TemplateWithCustomAttrs:
…lines 155–251 unchanged (97 lines)
252
253 expected = """{% partialdef inline-partial inline %}
254INLINE-CONTENT
255{% endpartialdef %}"""
256 self.assertEqual(partial_proxy.source.strip(), expected.strip())
257
258 def test_find_partial_source_fallback_cases(self):
259 cases = {"None offsets": (None, None), "Out of bounds offsets": (10, 20)}
260 for name, (source_start, source_end) in cases.items():
261 with self.subTest(name):
262 partial = PartialTemplate(
263 NodeList(),
264 Origin("test"),
265 "test",
266 source_start=source_start,
267 source_end=source_end,
268 )
269 result = partial.find_partial_source("nonexistent-partial")
270 self.assertEqual(result, "")
271
272 @setup(
273 {
274 "empty_partial_template": ("{% partialdef empty %}{% endpartialdef %}"),
275 },
276 debug_only=True,
277 )
278 def test_find_partial_source_empty_partial(self):
279 template = self.engine.get_template("empty_partial_template")
280 partial_proxy = template.extra_data["partials"]["empty"]
281
282 result = partial_proxy.find_partial_source(template.source)
283 self.assertEqual(result, "{% partialdef empty %}{% endpartialdef %}")
284
285 @setup(
286 {
287 "consecutive_partials_template": (
288 "{% partialdef empty %}{% endpartialdef %}"
…lines 289–293 unchanged (5 lines)
294 def test_find_partial_source_multiple_consecutive_partials(self):
295 template = self.engine.get_template("consecutive_partials_template")
296
297 empty_proxy = template.extra_data["partials"]["empty"]
298 other_proxy = template.extra_data["partials"]["other"]
299
300 empty_result = empty_proxy.find_partial_source(template.source)
301 self.assertEqual(empty_result, "{% partialdef empty %}{% endpartialdef %}")
302
303 other_result = other_proxy.find_partial_source(template.source)
304 self.assertEqual(other_result, "{% partialdef other %}...{% endpartialdef %}")
305
306 def test_partials_with_duplicate_names(self):
307 test_cases = [
308 (
309 "nested",
…lines 310–346 unchanged (37 lines)
347 debug_only=True,
348 )
349 def test_find_partial_source_supports_named_end_tag(self):
350 template = self.engine.get_template("named_end_tag_template")
351 partial_proxy = template.extra_data["partials"]["thing"]
352
353 result = partial_proxy.find_partial_source(template.source)
354 self.assertEqual(
355 result, "{% partialdef thing %}CONTENT{% endpartialdef thing %}"
356 )
357
358 @setup(
359 {
…lines 360–367 unchanged (8 lines)
368 def test_find_partial_source_supports_nested_partials(self):
369 template = self.engine.get_template("nested_partials_basic_template")
370
371 empty_proxy = template.extra_data["partials"]["outer"]
372 other_proxy = template.extra_data["partials"]["inner"]
373
374 outer_result = empty_proxy.find_partial_source(template.source)
375 self.assertEqual(
376 outer_result,
377 (
378 "{% partialdef outer %}{% partialdef inner %}"
379 "...{% endpartialdef %}{% endpartialdef %}"
380 ),
381 )
382
383 inner_result = other_proxy.find_partial_source(template.source)
384 self.assertEqual(inner_result, "{% partialdef inner %}...{% endpartialdef %}")
385
386 @setup(
387 {
388 "nested_partials_named_end_template": (
389 "{% partialdef outer %}"
…lines 390–395 unchanged (6 lines)
396 def test_find_partial_source_supports_nested_partials_and_named_end_tags(self):
397 template = self.engine.get_template("nested_partials_named_end_template")
398
399 empty_proxy = template.extra_data["partials"]["outer"]
400 other_proxy = template.extra_data["partials"]["inner"]
401
402 outer_result = empty_proxy.find_partial_source(template.source)
403 self.assertEqual(
404 outer_result,
405 (
406 "{% partialdef outer %}{% partialdef inner %}"
407 "...{% endpartialdef inner %}{% endpartialdef outer %}"
408 ),
409 )
410
411 inner_result = other_proxy.find_partial_source(template.source)
412 self.assertEqual(
413 inner_result, "{% partialdef inner %}...{% endpartialdef inner %}"
414 )
415
416 @setup(
417 {
…lines 418–425 unchanged (8 lines)
426 def test_find_partial_source_supports_nested_partials_and_mixed_end_tags_1(self):
427 template = self.engine.get_template("nested_partials_mixed_end_1_template")
428
429 empty_proxy = template.extra_data["partials"]["outer"]
430 other_proxy = template.extra_data["partials"]["inner"]
431
432 outer_result = empty_proxy.find_partial_source(template.source)
433 self.assertEqual(
434 outer_result,
435 (
436 "{% partialdef outer %}{% partialdef inner %}"
437 "...{% endpartialdef %}{% endpartialdef outer %}"
438 ),
439 )
440
441 inner_result = other_proxy.find_partial_source(template.source)
442 self.assertEqual(inner_result, "{% partialdef inner %}...{% endpartialdef %}")
443
444 @setup(
445 {
446 "nested_partials_mixed_end_2_template": (
447 "{% partialdef outer %}"
…lines 448–453 unchanged (6 lines)
454 def test_find_partial_source_supports_nested_partials_and_mixed_end_tags_2(self):
455 template = self.engine.get_template("nested_partials_mixed_end_2_template")
456
457 empty_proxy = template.extra_data["partials"]["outer"]
458 other_proxy = template.extra_data["partials"]["inner"]
459
460 outer_result = empty_proxy.find_partial_source(template.source)
461 self.assertEqual(
462 outer_result,
463 (
464 "{% partialdef outer %}{% partialdef inner %}"
465 "...{% endpartialdef inner %}{% endpartialdef %}"
466 ),
467 )
468
469 inner_result = other_proxy.find_partial_source(template.source)
470 self.assertEqual(
471 inner_result, "{% partialdef inner %}...{% endpartialdef inner %}"
472 )
473
474 @setup(
475 {
476 "partial_embedded_in_verbatim": (
477 "{% verbatim %}\n"
478 "{% partialdef testing-name %}\n"
479 "<p>Should be ignored</p>"
480 "{% endpartialdef testing-name %}\n"
481 "{% endverbatim %}\n"
482 "{% partialdef testing-name %}\n"
483 "<p>Content</p>\n"
484 "{% endpartialdef %}\n"
485 ),
486 },
487 debug_only=True,
488 )
489 def test_partial_template_embedded_in_verbatim(self):
490 template = self.engine.get_template("partial_embedded_in_verbatim")
491 partial_template = template.extra_data["partials"]["testing-name"]
492 self.assertEqual(
493 partial_template.source,
494 "{% partialdef testing-name %}\n<p>Content</p>\n{% endpartialdef %}",
495 )
496
497 @setup(
498 {
499 "partial_debug_source": (
500 "{% partialdef testing-name %}\n"
501 "<p>Content</p>\n"
502 "{% endpartialdef %}\n"
503 ),
504 },
505 debug_only=True,
506 )
507 def test_partial_source_uses_offsets_in_debug(self):
508 template = self.engine.get_template("partial_debug_source")
509 partial_template = template.extra_data["partials"]["testing-name"]
510
511 self.assertEqual(partial_template._source_start, 0)
512 self.assertEqual(partial_template._source_end, 64)
513 expected = template.source[
514 partial_template._source_start : partial_template._source_end
515 ]
516 self.assertEqual(partial_template.source, expected)
517
518 @setup(
519 {
520 "partial_embedded_in_named_verbatim": (
521 "{% verbatim block1 %}\n"
522 "{% partialdef testing-name %}\n"
523 "{% endverbatim block1 %}\n"
524 "{% partialdef testing-name %}\n"
525 "<p>Named Content</p>\n"
526 "{% endpartialdef %}\n"
527 ),
528 },
529 debug_only=True,
530 )
531 def test_partial_template_embedded_in_named_verbatim(self):
532 template = self.engine.get_template("partial_embedded_in_named_verbatim")
533 partial_template = template.extra_data["partials"]["testing-name"]
534 self.assertEqual(
535 "{% partialdef testing-name %}\n<p>Named Content</p>\n{% endpartialdef %}",
536 partial_template.source,
537 )
538
539 @setup(
540 {
541 "partial_embedded_in_comment_block": (
542 "{% comment %}\n"
543 "{% partialdef testing-name %}\n"
544 "{% endcomment %}\n"
545 "{% partialdef testing-name %}\n"
546 "<p>Comment Content</p>\n"
547 "{% endpartialdef %}\n"
548 ),
549 },
550 debug_only=True,
551 )
552 def test_partial_template_embedded_in_comment_block(self):
553 template = self.engine.get_template("partial_embedded_in_comment_block")
554 partial_template = template.extra_data["partials"]["testing-name"]
555 self.assertEqual(
556 partial_template.source,
557 "{% partialdef testing-name %}\n"
558 "<p>Comment Content</p>\n"
559 "{% endpartialdef %}",
560 )
561
562 @setup(
563 {
564 "partial_embedded_in_inline_comment": (
565 "{# {% partialdef testing-name %} #}\n"
566 "{% partialdef testing-name %}\n"
567 "<p>Inline Comment Content</p>\n"
568 "{% endpartialdef %}\n"
569 ),
570 },
571 debug_only=True,
572 )
573 def test_partial_template_embedded_in_inline_comment(self):
574 template = self.engine.get_template("partial_embedded_in_inline_comment")
575 partial_template = template.extra_data["partials"]["testing-name"]
576 self.assertEqual(
577 partial_template.source,
578 "{% partialdef testing-name %}\n"
579 "<p>Inline Comment Content</p>\n"
580 "{% endpartialdef %}",
581 )
582
583 @setup(
584 {
585 "partial_contains_fake_end_inside_verbatim": (
586 "{% partialdef testing-name %}\n"
587 "{% verbatim %}{% endpartialdef %}{% endverbatim %}\n"
588 "<p>Body</p>\n"
589 "{% endpartialdef %}\n"
590 ),
591 },
592 debug_only=True,
593 )
594 def test_partial_template_contains_fake_end_inside_verbatim(self):
595 template = self.engine.get_template("partial_contains_fake_end_inside_verbatim")
596 partial_template = template.extra_data["partials"]["testing-name"]
597 self.assertEqual(
598 partial_template.source,
599 "{% partialdef testing-name %}\n"
600 "{% verbatim %}{% endpartialdef %}{% endverbatim %}\n"
601 "<p>Body</p>\n"
602 "{% endpartialdef %}",
603 )
604