liquid 4.0.3 → 5.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (125) hide show
  1. checksums.yaml +4 -4
  2. data/History.md +54 -0
  3. data/README.md +6 -0
  4. data/lib/liquid/block.rb +31 -14
  5. data/lib/liquid/block_body.rb +166 -54
  6. data/lib/liquid/condition.rb +41 -20
  7. data/lib/liquid/context.rb +107 -52
  8. data/lib/liquid/document.rb +47 -9
  9. data/lib/liquid/drop.rb +4 -2
  10. data/lib/liquid/errors.rb +20 -18
  11. data/lib/liquid/expression.rb +29 -34
  12. data/lib/liquid/extensions.rb +2 -0
  13. data/lib/liquid/file_system.rb +6 -4
  14. data/lib/liquid/forloop_drop.rb +11 -4
  15. data/lib/liquid/i18n.rb +5 -3
  16. data/lib/liquid/interrupts.rb +3 -1
  17. data/lib/liquid/lexer.rb +30 -23
  18. data/lib/liquid/locales/en.yml +3 -1
  19. data/lib/liquid/parse_context.rb +20 -4
  20. data/lib/liquid/parse_tree_visitor.rb +2 -2
  21. data/lib/liquid/parser.rb +30 -18
  22. data/lib/liquid/parser_switching.rb +17 -3
  23. data/lib/liquid/partial_cache.rb +24 -0
  24. data/lib/liquid/profiler/hooks.rb +26 -14
  25. data/lib/liquid/profiler.rb +67 -86
  26. data/lib/liquid/range_lookup.rb +13 -3
  27. data/lib/liquid/register.rb +6 -0
  28. data/lib/liquid/resource_limits.rb +47 -8
  29. data/lib/liquid/standardfilters.rb +95 -46
  30. data/lib/liquid/static_registers.rb +44 -0
  31. data/lib/liquid/strainer_factory.rb +36 -0
  32. data/lib/liquid/strainer_template.rb +53 -0
  33. data/lib/liquid/tablerowloop_drop.rb +6 -4
  34. data/lib/liquid/tag/disableable.rb +22 -0
  35. data/lib/liquid/tag/disabler.rb +21 -0
  36. data/lib/liquid/tag.rb +28 -6
  37. data/lib/liquid/tags/assign.rb +24 -10
  38. data/lib/liquid/tags/break.rb +8 -3
  39. data/lib/liquid/tags/capture.rb +11 -8
  40. data/lib/liquid/tags/case.rb +40 -27
  41. data/lib/liquid/tags/comment.rb +5 -3
  42. data/lib/liquid/tags/continue.rb +8 -3
  43. data/lib/liquid/tags/cycle.rb +25 -14
  44. data/lib/liquid/tags/decrement.rb +6 -3
  45. data/lib/liquid/tags/echo.rb +34 -0
  46. data/lib/liquid/tags/for.rb +68 -44
  47. data/lib/liquid/tags/if.rb +39 -23
  48. data/lib/liquid/tags/ifchanged.rb +11 -10
  49. data/lib/liquid/tags/include.rb +34 -47
  50. data/lib/liquid/tags/increment.rb +7 -3
  51. data/lib/liquid/tags/raw.rb +14 -11
  52. data/lib/liquid/tags/render.rb +84 -0
  53. data/lib/liquid/tags/table_row.rb +23 -19
  54. data/lib/liquid/tags/unless.rb +23 -15
  55. data/lib/liquid/template.rb +53 -72
  56. data/lib/liquid/template_factory.rb +9 -0
  57. data/lib/liquid/tokenizer.rb +18 -10
  58. data/lib/liquid/usage.rb +8 -0
  59. data/lib/liquid/utils.rb +13 -3
  60. data/lib/liquid/variable.rb +46 -41
  61. data/lib/liquid/variable_lookup.rb +11 -6
  62. data/lib/liquid/version.rb +2 -1
  63. data/lib/liquid.rb +17 -5
  64. data/test/integration/assign_test.rb +74 -5
  65. data/test/integration/blank_test.rb +11 -8
  66. data/test/integration/block_test.rb +47 -1
  67. data/test/integration/capture_test.rb +18 -10
  68. data/test/integration/context_test.rb +609 -5
  69. data/test/integration/document_test.rb +4 -2
  70. data/test/integration/drop_test.rb +67 -83
  71. data/test/integration/error_handling_test.rb +73 -61
  72. data/test/integration/expression_test.rb +46 -0
  73. data/test/integration/filter_test.rb +53 -42
  74. data/test/integration/hash_ordering_test.rb +5 -3
  75. data/test/integration/output_test.rb +26 -24
  76. data/test/integration/parsing_quirks_test.rb +19 -7
  77. data/test/integration/{render_profiling_test.rb → profiler_test.rb} +84 -25
  78. data/test/integration/security_test.rb +30 -21
  79. data/test/integration/standard_filter_test.rb +385 -281
  80. data/test/integration/tag/disableable_test.rb +59 -0
  81. data/test/integration/tag_test.rb +45 -0
  82. data/test/integration/tags/break_tag_test.rb +4 -2
  83. data/test/integration/tags/continue_tag_test.rb +4 -2
  84. data/test/integration/tags/echo_test.rb +13 -0
  85. data/test/integration/tags/for_tag_test.rb +107 -51
  86. data/test/integration/tags/if_else_tag_test.rb +5 -3
  87. data/test/integration/tags/include_tag_test.rb +70 -54
  88. data/test/integration/tags/increment_tag_test.rb +4 -2
  89. data/test/integration/tags/liquid_tag_test.rb +116 -0
  90. data/test/integration/tags/raw_tag_test.rb +14 -11
  91. data/test/integration/tags/render_tag_test.rb +213 -0
  92. data/test/integration/tags/standard_tag_test.rb +38 -31
  93. data/test/integration/tags/statements_test.rb +23 -21
  94. data/test/integration/tags/table_row_test.rb +2 -0
  95. data/test/integration/tags/unless_else_tag_test.rb +4 -2
  96. data/test/integration/template_test.rb +132 -124
  97. data/test/integration/trim_mode_test.rb +78 -44
  98. data/test/integration/variable_test.rb +74 -32
  99. data/test/test_helper.rb +113 -22
  100. data/test/unit/block_unit_test.rb +19 -24
  101. data/test/unit/condition_unit_test.rb +79 -77
  102. data/test/unit/file_system_unit_test.rb +6 -4
  103. data/test/unit/i18n_unit_test.rb +7 -5
  104. data/test/unit/lexer_unit_test.rb +11 -9
  105. data/test/{integration → unit}/parse_tree_visitor_test.rb +16 -2
  106. data/test/unit/parser_unit_test.rb +37 -35
  107. data/test/unit/partial_cache_unit_test.rb +128 -0
  108. data/test/unit/regexp_unit_test.rb +17 -15
  109. data/test/unit/static_registers_unit_test.rb +156 -0
  110. data/test/unit/strainer_factory_unit_test.rb +100 -0
  111. data/test/unit/strainer_template_unit_test.rb +82 -0
  112. data/test/unit/tag_unit_test.rb +5 -3
  113. data/test/unit/tags/case_tag_unit_test.rb +3 -1
  114. data/test/unit/tags/for_tag_unit_test.rb +4 -2
  115. data/test/unit/tags/if_tag_unit_test.rb +3 -1
  116. data/test/unit/template_factory_unit_test.rb +12 -0
  117. data/test/unit/template_unit_test.rb +19 -10
  118. data/test/unit/tokenizer_unit_test.rb +26 -19
  119. data/test/unit/variable_unit_test.rb +51 -49
  120. metadata +76 -50
  121. data/lib/liquid/strainer.rb +0 -66
  122. data/lib/liquid/truffle.rb +0 -5
  123. data/test/truffle/truffle_test.rb +0 -9
  124. data/test/unit/context_unit_test.rb +0 -489
  125. data/test/unit/strainer_unit_test.rb +0 -164
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'test_helper'
2
4
 
3
5
  module SecurityFilter
@@ -14,65 +16,72 @@ class SecurityTest < Minitest::Test
14
16
  end
15
17
 
16
18
  def test_no_instance_eval
17
- text = %( {{ '1+1' | instance_eval }} )
19
+ text = %( {{ '1+1' | instance_eval }} )
18
20
  expected = %( 1+1 )
19
21
 
20
- assert_equal expected, Template.parse(text).render!(@assigns)
22
+ assert_equal(expected, Template.parse(text).render!(@assigns))
21
23
  end
22
24
 
23
25
  def test_no_existing_instance_eval
24
- text = %( {{ '1+1' | __instance_eval__ }} )
26
+ text = %( {{ '1+1' | __instance_eval__ }} )
25
27
  expected = %( 1+1 )
26
28
 
27
- assert_equal expected, Template.parse(text).render!(@assigns)
29
+ assert_equal(expected, Template.parse(text).render!(@assigns))
28
30
  end
29
31
 
30
32
  def test_no_instance_eval_after_mixing_in_new_filter
31
- text = %( {{ '1+1' | instance_eval }} )
33
+ text = %( {{ '1+1' | instance_eval }} )
32
34
  expected = %( 1+1 )
33
35
 
34
- assert_equal expected, Template.parse(text).render!(@assigns)
36
+ assert_equal(expected, Template.parse(text).render!(@assigns))
35
37
  end
36
38
 
37
39
  def test_no_instance_eval_later_in_chain
38
- text = %( {{ '1+1' | add_one | instance_eval }} )
40
+ text = %( {{ '1+1' | add_one | instance_eval }} )
39
41
  expected = %( 1+1 + 1 )
40
42
 
41
- assert_equal expected, Template.parse(text).render!(@assigns, filters: SecurityFilter)
43
+ assert_equal(expected, Template.parse(text).render!(@assigns, filters: SecurityFilter))
42
44
  end
43
45
 
44
- def test_does_not_add_filters_to_symbol_table
46
+ def test_does_not_permanently_add_filters_to_symbol_table
45
47
  current_symbols = Symbol.all_symbols
46
48
 
47
- test = %( {{ "some_string" | a_bad_filter }} )
49
+ # MRI imprecisely marks objects found on the C stack, which can result
50
+ # in uninitialized memory being marked. This can even result in the test failing
51
+ # deterministically for a given compilation of ruby. Using a separate thread will
52
+ # keep these writes of the symbol pointer on a separate stack that will be garbage
53
+ # collected after Thread#join.
54
+ Thread.new do
55
+ test = %( {{ "some_string" | a_bad_filter }} )
56
+ Template.parse(test).render!
57
+ nil
58
+ end.join
48
59
 
49
- template = Template.parse(test)
50
- assert_equal [], (Symbol.all_symbols - current_symbols)
60
+ GC.start
51
61
 
52
- template.render!
53
- assert_equal [], (Symbol.all_symbols - current_symbols)
62
+ assert_equal([], (Symbol.all_symbols - current_symbols))
54
63
  end
55
64
 
56
65
  def test_does_not_add_drop_methods_to_symbol_table
57
66
  current_symbols = Symbol.all_symbols
58
67
 
59
68
  assigns = { 'drop' => Drop.new }
60
- assert_equal "", Template.parse("{{ drop.custom_method_1 }}", assigns).render!
61
- assert_equal "", Template.parse("{{ drop.custom_method_2 }}", assigns).render!
62
- assert_equal "", Template.parse("{{ drop.custom_method_3 }}", assigns).render!
69
+ assert_equal("", Template.parse("{{ drop.custom_method_1 }}", assigns).render!)
70
+ assert_equal("", Template.parse("{{ drop.custom_method_2 }}", assigns).render!)
71
+ assert_equal("", Template.parse("{{ drop.custom_method_3 }}", assigns).render!)
63
72
 
64
- assert_equal [], (Symbol.all_symbols - current_symbols)
73
+ assert_equal([], (Symbol.all_symbols - current_symbols))
65
74
  end
66
75
 
67
76
  def test_max_depth_nested_blocks_does_not_raise_exception
68
77
  depth = Liquid::Block::MAX_DEPTH
69
- code = "{% if true %}" * depth + "rendered" + "{% endif %}" * depth
70
- assert_equal "rendered", Template.parse(code).render!
78
+ code = "{% if true %}" * depth + "rendered" + "{% endif %}" * depth
79
+ assert_equal("rendered", Template.parse(code).render!)
71
80
  end
72
81
 
73
82
  def test_more_than_max_depth_nested_blocks_raises_exception
74
83
  depth = Liquid::Block::MAX_DEPTH + 1
75
- code = "{% if true %}" * depth + "rendered" + "{% endif %}" * depth
84
+ code = "{% if true %}" * depth + "rendered" + "{% endif %}" * depth
76
85
  assert_raises(Liquid::StackLevelError) do
77
86
  Template.parse(code).render!
78
87
  end