test_runtime.py 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. import itertools
  2. from jinja2 import Template
  3. from jinja2.runtime import LoopContext
  4. TEST_IDX_TEMPLATE_STR_1 = (
  5. "[{% for i in lst|reverse %}(len={{ loop.length }},"
  6. " revindex={{ loop.revindex }}, index={{ loop.index }}, val={{ i }}){% endfor %}]"
  7. )
  8. TEST_IDX0_TEMPLATE_STR_1 = (
  9. "[{% for i in lst|reverse %}(len={{ loop.length }},"
  10. " revindex0={{ loop.revindex0 }}, index0={{ loop.index0 }}, val={{ i }})"
  11. "{% endfor %}]"
  12. )
  13. def test_loop_idx():
  14. t = Template(TEST_IDX_TEMPLATE_STR_1)
  15. lst = [10]
  16. excepted_render = "[(len=1, revindex=1, index=1, val=10)]"
  17. assert excepted_render == t.render(lst=lst)
  18. def test_loop_idx0():
  19. t = Template(TEST_IDX0_TEMPLATE_STR_1)
  20. lst = [10]
  21. excepted_render = "[(len=1, revindex0=0, index0=0, val=10)]"
  22. assert excepted_render == t.render(lst=lst)
  23. def test_loopcontext0():
  24. in_lst = []
  25. lc = LoopContext(reversed(in_lst), None)
  26. assert lc.length == len(in_lst)
  27. def test_loopcontext1():
  28. in_lst = [10]
  29. lc = LoopContext(reversed(in_lst), None)
  30. assert lc.length == len(in_lst)
  31. def test_loopcontext2():
  32. in_lst = [10, 11]
  33. lc = LoopContext(reversed(in_lst), None)
  34. assert lc.length == len(in_lst)
  35. def test_iterator_not_advanced_early():
  36. t = Template("{% for _, g in gs %}{{ loop.index }} {{ g|list }}\n{% endfor %}")
  37. out = t.render(
  38. gs=itertools.groupby([(1, "a"), (1, "b"), (2, "c"), (3, "d")], lambda x: x[0])
  39. )
  40. # groupby groups depend on the current position of the iterator. If
  41. # it was advanced early, the lists would appear empty.
  42. assert out == "1 [(1, 'a'), (1, 'b')]\n2 [(2, 'c')]\n3 [(3, 'd')]\n"
  43. def test_mock_not_pass_arg_marker():
  44. """If a callable class has a ``__getattr__`` that returns True-like
  45. values for arbitrary attrs, it should not be incorrectly identified
  46. as a ``pass_context`` function.
  47. """
  48. class Calc:
  49. def __getattr__(self, item):
  50. return object()
  51. def __call__(self, *args, **kwargs):
  52. return len(args) + len(kwargs)
  53. t = Template("{{ calc() }}")
  54. out = t.render(calc=Calc())
  55. # Would be "1" if context argument was passed.
  56. assert out == "0"