liquid 4.0.3 → 5.0.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 +33 -0
  3. data/README.md +6 -0
  4. data/lib/liquid.rb +17 -5
  5. data/lib/liquid/block.rb +31 -14
  6. data/lib/liquid/block_body.rb +164 -54
  7. data/lib/liquid/condition.rb +39 -18
  8. data/lib/liquid/context.rb +106 -51
  9. data/lib/liquid/document.rb +47 -9
  10. data/lib/liquid/drop.rb +4 -2
  11. data/lib/liquid/errors.rb +20 -18
  12. data/lib/liquid/expression.rb +29 -34
  13. data/lib/liquid/extensions.rb +2 -0
  14. data/lib/liquid/file_system.rb +6 -4
  15. data/lib/liquid/forloop_drop.rb +11 -4
  16. data/lib/liquid/i18n.rb +5 -3
  17. data/lib/liquid/interrupts.rb +3 -1
  18. data/lib/liquid/lexer.rb +30 -23
  19. data/lib/liquid/locales/en.yml +3 -1
  20. data/lib/liquid/parse_context.rb +16 -4
  21. data/lib/liquid/parse_tree_visitor.rb +2 -2
  22. data/lib/liquid/parser.rb +30 -18
  23. data/lib/liquid/parser_switching.rb +17 -3
  24. data/lib/liquid/partial_cache.rb +24 -0
  25. data/lib/liquid/profiler.rb +67 -86
  26. data/lib/liquid/profiler/hooks.rb +26 -14
  27. data/lib/liquid/range_lookup.rb +5 -3
  28. data/lib/liquid/register.rb +6 -0
  29. data/lib/liquid/resource_limits.rb +47 -8
  30. data/lib/liquid/standardfilters.rb +63 -44
  31. data/lib/liquid/static_registers.rb +44 -0
  32. data/lib/liquid/strainer_factory.rb +36 -0
  33. data/lib/liquid/strainer_template.rb +53 -0
  34. data/lib/liquid/tablerowloop_drop.rb +6 -4
  35. data/lib/liquid/tag.rb +28 -6
  36. data/lib/liquid/tag/disableable.rb +22 -0
  37. data/lib/liquid/tag/disabler.rb +21 -0
  38. data/lib/liquid/tags/assign.rb +24 -10
  39. data/lib/liquid/tags/break.rb +8 -3
  40. data/lib/liquid/tags/capture.rb +11 -8
  41. data/lib/liquid/tags/case.rb +33 -27
  42. data/lib/liquid/tags/comment.rb +5 -3
  43. data/lib/liquid/tags/continue.rb +8 -3
  44. data/lib/liquid/tags/cycle.rb +25 -14
  45. data/lib/liquid/tags/decrement.rb +6 -3
  46. data/lib/liquid/tags/echo.rb +26 -0
  47. data/lib/liquid/tags/for.rb +68 -44
  48. data/lib/liquid/tags/if.rb +35 -23
  49. data/lib/liquid/tags/ifchanged.rb +11 -10
  50. data/lib/liquid/tags/include.rb +34 -47
  51. data/lib/liquid/tags/increment.rb +7 -3
  52. data/lib/liquid/tags/raw.rb +14 -11
  53. data/lib/liquid/tags/render.rb +84 -0
  54. data/lib/liquid/tags/table_row.rb +23 -19
  55. data/lib/liquid/tags/unless.rb +15 -15
  56. data/lib/liquid/template.rb +55 -71
  57. data/lib/liquid/template_factory.rb +9 -0
  58. data/lib/liquid/tokenizer.rb +17 -9
  59. data/lib/liquid/usage.rb +8 -0
  60. data/lib/liquid/utils.rb +5 -3
  61. data/lib/liquid/variable.rb +46 -41
  62. data/lib/liquid/variable_lookup.rb +8 -6
  63. data/lib/liquid/version.rb +2 -1
  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 +608 -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 +339 -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 +118 -124
  97. data/test/integration/trim_mode_test.rb +78 -44
  98. data/test/integration/variable_test.rb +43 -32
  99. data/test/test_helper.rb +75 -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 +2 -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 +19 -17
  119. data/test/unit/variable_unit_test.rb +51 -49
  120. metadata +73 -47
  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
  class IfElseTagTest < Minitest::Test
@@ -43,7 +45,7 @@ class IfElseTagTest < Minitest::Test
43
45
 
44
46
  def test_comparison_of_strings_containing_and_or_or
45
47
  awful_markup = "a == 'and' and b == 'or' and c == 'foo and bar' and d == 'bar or baz' and e == 'foo' and foo and bar"
46
- assigns = { 'a' => 'and', 'b' => 'or', 'c' => 'foo and bar', 'd' => 'bar or baz', 'e' => 'foo', 'foo' => true, 'bar' => true }
48
+ assigns = { 'a' => 'and', 'b' => 'or', 'c' => 'foo and bar', 'd' => 'bar or baz', 'e' => 'foo', 'foo' => true, 'bar' => true }
47
49
  assert_template_result(' YES ', "{% if #{awful_markup} %} YES {% endif %}", assigns)
48
50
  end
49
51
 
@@ -132,7 +134,7 @@ class IfElseTagTest < Minitest::Test
132
134
  end
133
135
 
134
136
  def test_syntax_error_no_variable
135
- assert_raises(SyntaxError){ assert_template_result('', '{% if jerry == 1 %}') }
137
+ assert_raises(SyntaxError) { assert_template_result('', '{% if jerry == 1 %}') }
136
138
  end
137
139
 
138
140
  def test_syntax_error_no_expression
@@ -182,7 +184,7 @@ class IfElseTagTest < Minitest::Test
182
184
  tests.each do |vals, expected|
183
185
  a, b, c = vals
184
186
  assigns = { 'a' => a, 'b' => b, 'c' => c }
185
- assert_template_result expected.to_s, tpl, assigns, assigns.to_s
187
+ assert_template_result(expected.to_s, tpl, assigns, assigns.to_s)
186
188
  end
187
189
  end
188
190
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'test_helper'
2
4
 
3
5
  class TestFileSystem
@@ -6,6 +8,9 @@ class TestFileSystem
6
8
  when "product"
7
9
  "Product: {{ product.title }} "
8
10
 
11
+ when "product_alias"
12
+ "Product: {{ product.title }} "
13
+
9
14
  when "locale_variables"
10
15
  "Locale: {{echo1}} {{echo2}}"
11
16
 
@@ -40,16 +45,16 @@ class TestFileSystem
40
45
  end
41
46
 
42
47
  class OtherFileSystem
43
- def read_template_file(template_path)
48
+ def read_template_file(_template_path)
44
49
  'from OtherFileSystem'
45
50
  end
46
51
  end
47
52
 
48
53
  class CountingFileSystem
49
54
  attr_reader :count
50
- def read_template_file(template_path)
55
+ def read_template_file(_template_path)
51
56
  @count ||= 0
52
- @count += 1
57
+ @count += 1
53
58
  'from CountingFileSystem'
54
59
  end
55
60
  end
@@ -59,15 +64,16 @@ class CustomInclude < Liquid::Tag
59
64
 
60
65
  def initialize(tag_name, markup, tokens)
61
66
  markup =~ Syntax
62
- @template_name = $1
67
+ @template_name = Regexp.last_match(1)
63
68
  super
64
69
  end
65
70
 
66
71
  def parse(tokens)
67
72
  end
68
73
 
69
- def render(context)
70
- @template_name[1..-2]
74
+ def render_to_output_buffer(_context, output)
75
+ output << @template_name[1..-2]
76
+ output
71
77
  end
72
78
  end
73
79
 
@@ -79,61 +85,71 @@ class IncludeTagTest < Minitest::Test
79
85
  end
80
86
 
81
87
  def test_include_tag_looks_for_file_system_in_registers_first
82
- assert_equal 'from OtherFileSystem',
83
- Template.parse("{% include 'pick_a_source' %}").render!({}, registers: { file_system: OtherFileSystem.new })
88
+ assert_equal('from OtherFileSystem',
89
+ Template.parse("{% include 'pick_a_source' %}").render!({}, registers: { file_system: OtherFileSystem.new }))
84
90
  end
85
91
 
86
92
  def test_include_tag_with
87
- assert_template_result "Product: Draft 151cm ",
88
- "{% include 'product' with products[0] %}", "products" => [ { 'title' => 'Draft 151cm' }, { 'title' => 'Element 155cm' } ]
93
+ assert_template_result("Product: Draft 151cm ",
94
+ "{% include 'product' with products[0] %}", "products" => [{ 'title' => 'Draft 151cm' }, { 'title' => 'Element 155cm' }])
95
+ end
96
+
97
+ def test_include_tag_with_alias
98
+ assert_template_result("Product: Draft 151cm ",
99
+ "{% include 'product_alias' with products[0] as product %}", "products" => [{ 'title' => 'Draft 151cm' }, { 'title' => 'Element 155cm' }])
100
+ end
101
+
102
+ def test_include_tag_for_alias
103
+ assert_template_result("Product: Draft 151cm Product: Element 155cm ",
104
+ "{% include 'product_alias' for products as product %}", "products" => [{ 'title' => 'Draft 151cm' }, { 'title' => 'Element 155cm' }])
89
105
  end
90
106
 
91
107
  def test_include_tag_with_default_name
92
- assert_template_result "Product: Draft 151cm ",
93
- "{% include 'product' %}", "product" => { 'title' => 'Draft 151cm' }
108
+ assert_template_result("Product: Draft 151cm ",
109
+ "{% include 'product' %}", "product" => { 'title' => 'Draft 151cm' })
94
110
  end
95
111
 
96
112
  def test_include_tag_for
97
- assert_template_result "Product: Draft 151cm Product: Element 155cm ",
98
- "{% include 'product' for products %}", "products" => [ { 'title' => 'Draft 151cm' }, { 'title' => 'Element 155cm' } ]
113
+ assert_template_result("Product: Draft 151cm Product: Element 155cm ",
114
+ "{% include 'product' for products %}", "products" => [{ 'title' => 'Draft 151cm' }, { 'title' => 'Element 155cm' }])
99
115
  end
100
116
 
101
117
  def test_include_tag_with_local_variables
102
- assert_template_result "Locale: test123 ", "{% include 'locale_variables' echo1: 'test123' %}"
118
+ assert_template_result("Locale: test123 ", "{% include 'locale_variables' echo1: 'test123' %}")
103
119
  end
104
120
 
105
121
  def test_include_tag_with_multiple_local_variables
106
- assert_template_result "Locale: test123 test321",
107
- "{% include 'locale_variables' echo1: 'test123', echo2: 'test321' %}"
122
+ assert_template_result("Locale: test123 test321",
123
+ "{% include 'locale_variables' echo1: 'test123', echo2: 'test321' %}")
108
124
  end
109
125
 
110
126
  def test_include_tag_with_multiple_local_variables_from_context
111
- assert_template_result "Locale: test123 test321",
127
+ assert_template_result("Locale: test123 test321",
112
128
  "{% include 'locale_variables' echo1: echo1, echo2: more_echos.echo2 %}",
113
- 'echo1' => 'test123', 'more_echos' => { "echo2" => 'test321' }
129
+ 'echo1' => 'test123', 'more_echos' => { "echo2" => 'test321' })
114
130
  end
115
131
 
116
132
  def test_included_templates_assigns_variables
117
- assert_template_result "bar", "{% include 'assignments' %}{{ foo }}"
133
+ assert_template_result("bar", "{% include 'assignments' %}{{ foo }}")
118
134
  end
119
135
 
120
136
  def test_nested_include_tag
121
- assert_template_result "body body_detail", "{% include 'body' %}"
137
+ assert_template_result("body body_detail", "{% include 'body' %}")
122
138
 
123
- assert_template_result "header body body_detail footer", "{% include 'nested_template' %}"
139
+ assert_template_result("header body body_detail footer", "{% include 'nested_template' %}")
124
140
  end
125
141
 
126
142
  def test_nested_include_with_variable
127
- assert_template_result "Product: Draft 151cm details ",
128
- "{% include 'nested_product_template' with product %}", "product" => { "title" => 'Draft 151cm' }
143
+ assert_template_result("Product: Draft 151cm details ",
144
+ "{% include 'nested_product_template' with product %}", "product" => { "title" => 'Draft 151cm' })
129
145
 
130
- assert_template_result "Product: Draft 151cm details Product: Element 155cm details ",
131
- "{% include 'nested_product_template' for products %}", "products" => [{ "title" => 'Draft 151cm' }, { "title" => 'Element 155cm' }]
146
+ assert_template_result("Product: Draft 151cm details Product: Element 155cm details ",
147
+ "{% include 'nested_product_template' for products %}", "products" => [{ "title" => 'Draft 151cm' }, { "title" => 'Element 155cm' }])
132
148
  end
133
149
 
134
150
  def test_recursively_included_template_does_not_produce_endless_loop
135
151
  infinite_file_system = Class.new do
136
- def read_template_file(template_path)
152
+ def read_template_file(_template_path)
137
153
  "-{% include 'loop' %}"
138
154
  end
139
155
  end
@@ -146,41 +162,41 @@ class IncludeTagTest < Minitest::Test
146
162
  end
147
163
 
148
164
  def test_dynamically_choosen_template
149
- assert_template_result "Test123", "{% include template %}", "template" => 'Test123'
150
- assert_template_result "Test321", "{% include template %}", "template" => 'Test321'
165
+ assert_template_result("Test123", "{% include template %}", "template" => 'Test123')
166
+ assert_template_result("Test321", "{% include template %}", "template" => 'Test321')
151
167
 
152
- assert_template_result "Product: Draft 151cm ", "{% include template for product %}",
153
- "template" => 'product', 'product' => { 'title' => 'Draft 151cm' }
168
+ assert_template_result("Product: Draft 151cm ", "{% include template for product %}",
169
+ "template" => 'product', 'product' => { 'title' => 'Draft 151cm' })
154
170
  end
155
171
 
156
172
  def test_include_tag_caches_second_read_of_same_partial
157
173
  file_system = CountingFileSystem.new
158
- assert_equal 'from CountingFileSystemfrom CountingFileSystem',
159
- Template.parse("{% include 'pick_a_source' %}{% include 'pick_a_source' %}").render!({}, registers: { file_system: file_system })
160
- assert_equal 1, file_system.count
174
+ assert_equal('from CountingFileSystemfrom CountingFileSystem',
175
+ Template.parse("{% include 'pick_a_source' %}{% include 'pick_a_source' %}").render!({}, registers: { file_system: file_system }))
176
+ assert_equal(1, file_system.count)
161
177
  end
162
178
 
163
179
  def test_include_tag_doesnt_cache_partials_across_renders
164
180
  file_system = CountingFileSystem.new
165
- assert_equal 'from CountingFileSystem',
166
- Template.parse("{% include 'pick_a_source' %}").render!({}, registers: { file_system: file_system })
167
- assert_equal 1, file_system.count
181
+ assert_equal('from CountingFileSystem',
182
+ Template.parse("{% include 'pick_a_source' %}").render!({}, registers: { file_system: file_system }))
183
+ assert_equal(1, file_system.count)
168
184
 
169
- assert_equal 'from CountingFileSystem',
170
- Template.parse("{% include 'pick_a_source' %}").render!({}, registers: { file_system: file_system })
171
- assert_equal 2, file_system.count
185
+ assert_equal('from CountingFileSystem',
186
+ Template.parse("{% include 'pick_a_source' %}").render!({}, registers: { file_system: file_system }))
187
+ assert_equal(2, file_system.count)
172
188
  end
173
189
 
174
190
  def test_include_tag_within_if_statement
175
- assert_template_result "foo_if_true", "{% if true %}{% include 'foo_if_true' %}{% endif %}"
191
+ assert_template_result("foo_if_true", "{% if true %}{% include 'foo_if_true' %}{% endif %}")
176
192
  end
177
193
 
178
194
  def test_custom_include_tag
179
195
  original_tag = Liquid::Template.tags['include']
180
196
  Liquid::Template.tags['include'] = CustomInclude
181
197
  begin
182
- assert_equal "custom_foo",
183
- Template.parse("{% include 'custom_foo' %}").render!
198
+ assert_equal("custom_foo",
199
+ Template.parse("{% include 'custom_foo' %}").render!)
184
200
  ensure
185
201
  Liquid::Template.tags['include'] = original_tag
186
202
  end
@@ -190,8 +206,8 @@ class IncludeTagTest < Minitest::Test
190
206
  original_tag = Liquid::Template.tags['include']
191
207
  Liquid::Template.tags['include'] = CustomInclude
192
208
  begin
193
- assert_equal "custom_foo_if_true",
194
- Template.parse("{% if true %}{% include 'custom_foo_if_true' %}{% endif %}").render!
209
+ assert_equal("custom_foo_if_true",
210
+ Template.parse("{% if true %}{% include 'custom_foo_if_true' %}{% endif %}").render!)
195
211
  ensure
196
212
  Liquid::Template.tags['include'] = original_tag
197
213
  end
@@ -202,7 +218,7 @@ class IncludeTagTest < Minitest::Test
202
218
 
203
219
  a = Liquid::Template.parse(' {% include "nested_template" %}')
204
220
  a.render!
205
- assert_empty a.errors
221
+ assert_empty(a.errors)
206
222
  end
207
223
 
208
224
  def test_passing_options_to_included_templates
@@ -210,13 +226,13 @@ class IncludeTagTest < Minitest::Test
210
226
  Template.parse("{% include template %}", error_mode: :strict).render!("template" => '{{ "X" || downcase }}')
211
227
  end
212
228
  with_error_mode(:lax) do
213
- assert_equal 'x', Template.parse("{% include template %}", error_mode: :strict, include_options_blacklist: true).render!("template" => '{{ "X" || downcase }}')
229
+ assert_equal('x', Template.parse("{% include template %}", error_mode: :strict, include_options_blacklist: true).render!("template" => '{{ "X" || downcase }}'))
214
230
  end
215
231
  assert_raises(Liquid::SyntaxError) do
216
232
  Template.parse("{% include template %}", error_mode: :strict, include_options_blacklist: [:locale]).render!("template" => '{{ "X" || downcase }}')
217
233
  end
218
234
  with_error_mode(:lax) do
219
- assert_equal 'x', Template.parse("{% include template %}", error_mode: :strict, include_options_blacklist: [:error_mode]).render!("template" => '{{ "X" || downcase }}')
235
+ assert_equal('x', Template.parse("{% include template %}", error_mode: :strict, include_options_blacklist: [:error_mode]).render!("template" => '{{ "X" || downcase }}'))
220
236
  end
221
237
  end
222
238
 
@@ -232,22 +248,22 @@ class IncludeTagTest < Minitest::Test
232
248
  end
233
249
 
234
250
  def test_including_via_variable_value
235
- assert_template_result "from TestFileSystem", "{% assign page = 'pick_a_source' %}{% include page %}"
251
+ assert_template_result("from TestFileSystem", "{% assign page = 'pick_a_source' %}{% include page %}")
236
252
 
237
- assert_template_result "Product: Draft 151cm ", "{% assign page = 'product' %}{% include page %}", "product" => { 'title' => 'Draft 151cm' }
253
+ assert_template_result("Product: Draft 151cm ", "{% assign page = 'product' %}{% include page %}", "product" => { 'title' => 'Draft 151cm' })
238
254
 
239
- assert_template_result "Product: Draft 151cm ", "{% assign page = 'product' %}{% include page for foo %}", "foo" => { 'title' => 'Draft 151cm' }
255
+ assert_template_result("Product: Draft 151cm ", "{% assign page = 'product' %}{% include page for foo %}", "foo" => { 'title' => 'Draft 151cm' })
240
256
  end
241
257
 
242
258
  def test_including_with_strict_variables
243
259
  template = Liquid::Template.parse("{% include 'simple' %}", error_mode: :warn)
244
260
  template.render(nil, strict_variables: true)
245
261
 
246
- assert_equal [], template.errors
262
+ assert_equal([], template.errors)
247
263
  end
248
264
 
249
265
  def test_break_through_include
250
- assert_template_result "1", "{% for i in (1..3) %}{{ i }}{% break %}{{ i }}{% endfor %}"
251
- assert_template_result "1", "{% for i in (1..3) %}{{ i }}{% include 'break' %}{{ i }}{% endfor %}"
266
+ assert_template_result("1", "{% for i in (1..3) %}{{ i }}{% break %}{{ i }}{% endfor %}")
267
+ assert_template_result("1", "{% for i in (1..3) %}{{ i }}{% include 'break' %}{{ i }}{% endfor %}")
252
268
  end
253
269
  end # IncludeTagTest
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'test_helper'
2
4
 
3
5
  class IncrementTagTest < Minitest::Test
@@ -13,11 +15,11 @@ class IncrementTagTest < Minitest::Test
13
15
  end
14
16
 
15
17
  def test_dec
16
- assert_template_result('9', '{%decrement port %}', { 'port' => 10 })
18
+ assert_template_result('9', '{%decrement port %}', 'port' => 10)
17
19
  assert_template_result('-1 -2', '{%decrement port %} {%decrement port%}', {})
18
20
  assert_template_result('1 5 2 2 5',
19
21
  '{%increment port %} {%increment starboard%} ' \
20
22
  '{%increment port %} {%decrement port%} ' \
21
- '{%decrement starboard %}', { 'port' => 1, 'starboard' => 5 })
23
+ '{%decrement starboard %}', 'port' => 1, 'starboard' => 5)
22
24
  end
23
25
  end
@@ -0,0 +1,116 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'test_helper'
4
+
5
+ class LiquidTagTest < Minitest::Test
6
+ include Liquid
7
+
8
+ def test_liquid_tag
9
+ assert_template_result('1 2 3', <<~LIQUID, 'array' => [1, 2, 3])
10
+ {%- liquid
11
+ echo array | join: " "
12
+ -%}
13
+ LIQUID
14
+
15
+ assert_template_result('1 2 3', <<~LIQUID, 'array' => [1, 2, 3])
16
+ {%- liquid
17
+ for value in array
18
+ echo value
19
+ unless forloop.last
20
+ echo " "
21
+ endunless
22
+ endfor
23
+ -%}
24
+ LIQUID
25
+
26
+ assert_template_result('4 8 12 6', <<~LIQUID, 'array' => [1, 2, 3])
27
+ {%- liquid
28
+ for value in array
29
+ assign double_value = value | times: 2
30
+ echo double_value | times: 2
31
+ unless forloop.last
32
+ echo " "
33
+ endunless
34
+ endfor
35
+
36
+ echo " "
37
+ echo double_value
38
+ -%}
39
+ LIQUID
40
+
41
+ assert_template_result('abc', <<~LIQUID)
42
+ {%- liquid echo "a" -%}
43
+ b
44
+ {%- liquid echo "c" -%}
45
+ LIQUID
46
+ end
47
+
48
+ def test_liquid_tag_errors
49
+ assert_match_syntax_error("syntax error (line 1): Unknown tag 'error'", <<~LIQUID)
50
+ {%- liquid error no such tag -%}
51
+ LIQUID
52
+
53
+ assert_match_syntax_error("syntax error (line 7): Unknown tag 'error'", <<~LIQUID)
54
+ {{ test }}
55
+
56
+ {%-
57
+ liquid
58
+ for value in array
59
+
60
+ error no such tag
61
+ endfor
62
+ -%}
63
+ LIQUID
64
+
65
+ assert_match_syntax_error("syntax error (line 2): Unknown tag '!!! the guards are vigilant'", <<~LIQUID)
66
+ {%- liquid
67
+ !!! the guards are vigilant
68
+ -%}
69
+ LIQUID
70
+
71
+ assert_match_syntax_error("syntax error (line 4): 'for' tag was never closed", <<~LIQUID)
72
+ {%- liquid
73
+ for value in array
74
+ echo 'forgot to close the for tag'
75
+ -%}
76
+ LIQUID
77
+ end
78
+
79
+ def test_line_number_is_correct_after_a_blank_token
80
+ assert_match_syntax_error("syntax error (line 3): Unknown tag 'error'", "{% liquid echo ''\n\n error %}")
81
+ assert_match_syntax_error("syntax error (line 3): Unknown tag 'error'", "{% liquid echo ''\n \n error %}")
82
+ end
83
+
84
+ def test_nested_liquid_tag
85
+ assert_template_result('good', <<~LIQUID)
86
+ {%- if true %}
87
+ {%- liquid
88
+ echo "good"
89
+ %}
90
+ {%- endif -%}
91
+ LIQUID
92
+ end
93
+
94
+ def test_cannot_open_blocks_living_past_a_liquid_tag
95
+ assert_match_syntax_error("syntax error (line 3): 'if' tag was never closed", <<~LIQUID)
96
+ {%- liquid
97
+ if true
98
+ -%}
99
+ {%- endif -%}
100
+ LIQUID
101
+ end
102
+
103
+ def test_cannot_close_blocks_created_before_a_liquid_tag
104
+ assert_match_syntax_error("syntax error (line 3): 'endif' is not a valid delimiter for liquid tags. use %}", <<~LIQUID)
105
+ {%- if true -%}
106
+ 42
107
+ {%- liquid endif -%}
108
+ LIQUID
109
+ end
110
+
111
+ def test_liquid_tag_in_raw
112
+ assert_template_result("{% liquid echo 'test' %}\n", <<~LIQUID)
113
+ {% raw %}{% liquid echo 'test' %}{% endraw %}
114
+ LIQUID
115
+ end
116
+ end
@@ -1,26 +1,29 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'test_helper'
2
4
 
3
5
  class RawTagTest < Minitest::Test
4
6
  include Liquid
5
7
 
6
8
  def test_tag_in_raw
7
- assert_template_result '{% comment %} test {% endcomment %}',
8
- '{% raw %}{% comment %} test {% endcomment %}{% endraw %}'
9
+ assert_template_result('{% comment %} test {% endcomment %}',
10
+ '{% raw %}{% comment %} test {% endcomment %}{% endraw %}')
9
11
  end
10
12
 
11
13
  def test_output_in_raw
12
- assert_template_result '{{ test }}', '{% raw %}{{ test }}{% endraw %}'
14
+ assert_template_result('{{ test }}', '{% raw %}{{ test }}{% endraw %}')
13
15
  end
14
16
 
15
17
  def test_open_tag_in_raw
16
- assert_template_result ' Foobar {% invalid ', '{% raw %} Foobar {% invalid {% endraw %}'
17
- assert_template_result ' Foobar invalid %} ', '{% raw %} Foobar invalid %} {% endraw %}'
18
- assert_template_result ' Foobar {{ invalid ', '{% raw %} Foobar {{ invalid {% endraw %}'
19
- assert_template_result ' Foobar invalid }} ', '{% raw %} Foobar invalid }} {% endraw %}'
20
- assert_template_result ' Foobar {% invalid {% {% endraw ', '{% raw %} Foobar {% invalid {% {% endraw {% endraw %}'
21
- assert_template_result ' Foobar {% {% {% ', '{% raw %} Foobar {% {% {% {% endraw %}'
22
- assert_template_result ' test {% raw %} {% endraw %}', '{% raw %} test {% raw %} {% {% endraw %}endraw %}'
23
- assert_template_result ' Foobar {{ invalid 1', '{% raw %} Foobar {{ invalid {% endraw %}{{ 1 }}'
18
+ assert_template_result(' Foobar {% invalid ', '{% raw %} Foobar {% invalid {% endraw %}')
19
+ assert_template_result(' Foobar invalid %} ', '{% raw %} Foobar invalid %} {% endraw %}')
20
+ assert_template_result(' Foobar {{ invalid ', '{% raw %} Foobar {{ invalid {% endraw %}')
21
+ assert_template_result(' Foobar invalid }} ', '{% raw %} Foobar invalid }} {% endraw %}')
22
+ assert_template_result(' Foobar {% invalid {% {% endraw ', '{% raw %} Foobar {% invalid {% {% endraw {% endraw %}')
23
+ assert_template_result(' Foobar {% {% {% ', '{% raw %} Foobar {% {% {% {% endraw %}')
24
+ assert_template_result(' test {% raw %} {% endraw %}', '{% raw %} test {% raw %} {% {% endraw %}endraw %}')
25
+ assert_template_result(' Foobar {{ invalid 1', '{% raw %} Foobar {{ invalid {% endraw %}{{ 1 }}')
26
+ assert_template_result(' Foobar {% foo {% bar %}', '{% raw %} Foobar {% foo {% bar %}{% endraw %}')
24
27
  end
25
28
 
26
29
  def test_invalid_raw