liquid 4.0.3 → 5.4.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.
- checksums.yaml +4 -4
- data/History.md +89 -0
- data/README.md +10 -4
- data/lib/liquid/block.rb +31 -14
- data/lib/liquid/block_body.rb +169 -57
- data/lib/liquid/condition.rb +48 -21
- data/lib/liquid/context.rb +111 -52
- data/lib/liquid/document.rb +47 -9
- data/lib/liquid/drop.rb +4 -2
- data/lib/liquid/errors.rb +20 -18
- data/lib/liquid/expression.rb +28 -32
- data/lib/liquid/extensions.rb +2 -0
- data/lib/liquid/file_system.rb +6 -4
- data/lib/liquid/forloop_drop.rb +54 -4
- data/lib/liquid/i18n.rb +5 -3
- data/lib/liquid/interrupts.rb +3 -1
- data/lib/liquid/lexer.rb +30 -23
- data/lib/liquid/locales/en.yml +8 -5
- data/lib/liquid/parse_context.rb +20 -4
- data/lib/liquid/parse_tree_visitor.rb +2 -2
- data/lib/liquid/parser.rb +30 -18
- data/lib/liquid/parser_switching.rb +17 -3
- data/lib/liquid/partial_cache.rb +24 -0
- data/lib/liquid/profiler/hooks.rb +26 -14
- data/lib/liquid/profiler.rb +67 -86
- data/lib/liquid/range_lookup.rb +13 -3
- data/lib/liquid/registers.rb +51 -0
- data/lib/liquid/resource_limits.rb +47 -8
- data/lib/liquid/standardfilters.rb +551 -114
- data/lib/liquid/strainer_factory.rb +41 -0
- data/lib/liquid/strainer_template.rb +62 -0
- data/lib/liquid/tablerowloop_drop.rb +64 -5
- data/lib/liquid/tag/disableable.rb +22 -0
- data/lib/liquid/tag/disabler.rb +21 -0
- data/lib/liquid/tag.rb +28 -6
- data/lib/liquid/tags/assign.rb +36 -18
- data/lib/liquid/tags/break.rb +16 -3
- data/lib/liquid/tags/capture.rb +24 -18
- data/lib/liquid/tags/case.rb +61 -27
- data/lib/liquid/tags/comment.rb +18 -3
- data/lib/liquid/tags/continue.rb +16 -12
- data/lib/liquid/tags/cycle.rb +37 -25
- data/lib/liquid/tags/decrement.rb +22 -20
- data/lib/liquid/tags/echo.rb +41 -0
- data/lib/liquid/tags/for.rb +90 -87
- data/lib/liquid/tags/if.rb +50 -32
- data/lib/liquid/tags/ifchanged.rb +11 -10
- data/lib/liquid/tags/include.rb +49 -60
- data/lib/liquid/tags/increment.rb +23 -17
- data/lib/liquid/tags/inline_comment.rb +43 -0
- data/lib/liquid/tags/raw.rb +25 -11
- data/lib/liquid/tags/render.rb +109 -0
- data/lib/liquid/tags/table_row.rb +45 -19
- data/lib/liquid/tags/unless.rb +38 -19
- data/lib/liquid/template.rb +52 -72
- data/lib/liquid/template_factory.rb +9 -0
- data/lib/liquid/tokenizer.rb +18 -10
- data/lib/liquid/usage.rb +8 -0
- data/lib/liquid/utils.rb +13 -3
- data/lib/liquid/variable.rb +49 -44
- data/lib/liquid/variable_lookup.rb +18 -10
- data/lib/liquid/version.rb +2 -1
- data/lib/liquid.rb +18 -6
- metadata +20 -108
- data/lib/liquid/strainer.rb +0 -66
- data/lib/liquid/truffle.rb +0 -5
- data/test/fixtures/en_locale.yml +0 -9
- data/test/integration/assign_test.rb +0 -48
- data/test/integration/blank_test.rb +0 -106
- data/test/integration/block_test.rb +0 -12
- data/test/integration/capture_test.rb +0 -50
- data/test/integration/context_test.rb +0 -32
- data/test/integration/document_test.rb +0 -19
- data/test/integration/drop_test.rb +0 -273
- data/test/integration/error_handling_test.rb +0 -260
- data/test/integration/filter_test.rb +0 -178
- data/test/integration/hash_ordering_test.rb +0 -23
- data/test/integration/output_test.rb +0 -123
- data/test/integration/parse_tree_visitor_test.rb +0 -247
- data/test/integration/parsing_quirks_test.rb +0 -122
- data/test/integration/render_profiling_test.rb +0 -154
- data/test/integration/security_test.rb +0 -80
- data/test/integration/standard_filter_test.rb +0 -776
- data/test/integration/tags/break_tag_test.rb +0 -15
- data/test/integration/tags/continue_tag_test.rb +0 -15
- data/test/integration/tags/for_tag_test.rb +0 -410
- data/test/integration/tags/if_else_tag_test.rb +0 -188
- data/test/integration/tags/include_tag_test.rb +0 -253
- data/test/integration/tags/increment_tag_test.rb +0 -23
- data/test/integration/tags/raw_tag_test.rb +0 -31
- data/test/integration/tags/standard_tag_test.rb +0 -296
- data/test/integration/tags/statements_test.rb +0 -111
- data/test/integration/tags/table_row_test.rb +0 -64
- data/test/integration/tags/unless_else_tag_test.rb +0 -26
- data/test/integration/template_test.rb +0 -332
- data/test/integration/trim_mode_test.rb +0 -529
- data/test/integration/variable_test.rb +0 -96
- data/test/test_helper.rb +0 -116
- data/test/truffle/truffle_test.rb +0 -9
- data/test/unit/block_unit_test.rb +0 -58
- data/test/unit/condition_unit_test.rb +0 -166
- data/test/unit/context_unit_test.rb +0 -489
- data/test/unit/file_system_unit_test.rb +0 -35
- data/test/unit/i18n_unit_test.rb +0 -37
- data/test/unit/lexer_unit_test.rb +0 -51
- data/test/unit/parser_unit_test.rb +0 -82
- data/test/unit/regexp_unit_test.rb +0 -44
- data/test/unit/strainer_unit_test.rb +0 -164
- data/test/unit/tag_unit_test.rb +0 -21
- data/test/unit/tags/case_tag_unit_test.rb +0 -10
- data/test/unit/tags/for_tag_unit_test.rb +0 -13
- data/test/unit/tags/if_tag_unit_test.rb +0 -8
- data/test/unit/template_unit_test.rb +0 -78
- data/test/unit/tokenizer_unit_test.rb +0 -55
- data/test/unit/variable_unit_test.rb +0 -162
@@ -1,253 +0,0 @@
|
|
1
|
-
require 'test_helper'
|
2
|
-
|
3
|
-
class TestFileSystem
|
4
|
-
def read_template_file(template_path)
|
5
|
-
case template_path
|
6
|
-
when "product"
|
7
|
-
"Product: {{ product.title }} "
|
8
|
-
|
9
|
-
when "locale_variables"
|
10
|
-
"Locale: {{echo1}} {{echo2}}"
|
11
|
-
|
12
|
-
when "variant"
|
13
|
-
"Variant: {{ variant.title }}"
|
14
|
-
|
15
|
-
when "nested_template"
|
16
|
-
"{% include 'header' %} {% include 'body' %} {% include 'footer' %}"
|
17
|
-
|
18
|
-
when "body"
|
19
|
-
"body {% include 'body_detail' %}"
|
20
|
-
|
21
|
-
when "nested_product_template"
|
22
|
-
"Product: {{ nested_product_template.title }} {%include 'details'%} "
|
23
|
-
|
24
|
-
when "recursively_nested_template"
|
25
|
-
"-{% include 'recursively_nested_template' %}"
|
26
|
-
|
27
|
-
when "pick_a_source"
|
28
|
-
"from TestFileSystem"
|
29
|
-
|
30
|
-
when 'assignments'
|
31
|
-
"{% assign foo = 'bar' %}"
|
32
|
-
|
33
|
-
when 'break'
|
34
|
-
"{% break %}"
|
35
|
-
|
36
|
-
else
|
37
|
-
template_path
|
38
|
-
end
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
class OtherFileSystem
|
43
|
-
def read_template_file(template_path)
|
44
|
-
'from OtherFileSystem'
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
|
-
class CountingFileSystem
|
49
|
-
attr_reader :count
|
50
|
-
def read_template_file(template_path)
|
51
|
-
@count ||= 0
|
52
|
-
@count += 1
|
53
|
-
'from CountingFileSystem'
|
54
|
-
end
|
55
|
-
end
|
56
|
-
|
57
|
-
class CustomInclude < Liquid::Tag
|
58
|
-
Syntax = /(#{Liquid::QuotedFragment}+)(\s+(?:with|for)\s+(#{Liquid::QuotedFragment}+))?/o
|
59
|
-
|
60
|
-
def initialize(tag_name, markup, tokens)
|
61
|
-
markup =~ Syntax
|
62
|
-
@template_name = $1
|
63
|
-
super
|
64
|
-
end
|
65
|
-
|
66
|
-
def parse(tokens)
|
67
|
-
end
|
68
|
-
|
69
|
-
def render(context)
|
70
|
-
@template_name[1..-2]
|
71
|
-
end
|
72
|
-
end
|
73
|
-
|
74
|
-
class IncludeTagTest < Minitest::Test
|
75
|
-
include Liquid
|
76
|
-
|
77
|
-
def setup
|
78
|
-
Liquid::Template.file_system = TestFileSystem.new
|
79
|
-
end
|
80
|
-
|
81
|
-
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 })
|
84
|
-
end
|
85
|
-
|
86
|
-
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' } ]
|
89
|
-
end
|
90
|
-
|
91
|
-
def test_include_tag_with_default_name
|
92
|
-
assert_template_result "Product: Draft 151cm ",
|
93
|
-
"{% include 'product' %}", "product" => { 'title' => 'Draft 151cm' }
|
94
|
-
end
|
95
|
-
|
96
|
-
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' } ]
|
99
|
-
end
|
100
|
-
|
101
|
-
def test_include_tag_with_local_variables
|
102
|
-
assert_template_result "Locale: test123 ", "{% include 'locale_variables' echo1: 'test123' %}"
|
103
|
-
end
|
104
|
-
|
105
|
-
def test_include_tag_with_multiple_local_variables
|
106
|
-
assert_template_result "Locale: test123 test321",
|
107
|
-
"{% include 'locale_variables' echo1: 'test123', echo2: 'test321' %}"
|
108
|
-
end
|
109
|
-
|
110
|
-
def test_include_tag_with_multiple_local_variables_from_context
|
111
|
-
assert_template_result "Locale: test123 test321",
|
112
|
-
"{% include 'locale_variables' echo1: echo1, echo2: more_echos.echo2 %}",
|
113
|
-
'echo1' => 'test123', 'more_echos' => { "echo2" => 'test321' }
|
114
|
-
end
|
115
|
-
|
116
|
-
def test_included_templates_assigns_variables
|
117
|
-
assert_template_result "bar", "{% include 'assignments' %}{{ foo }}"
|
118
|
-
end
|
119
|
-
|
120
|
-
def test_nested_include_tag
|
121
|
-
assert_template_result "body body_detail", "{% include 'body' %}"
|
122
|
-
|
123
|
-
assert_template_result "header body body_detail footer", "{% include 'nested_template' %}"
|
124
|
-
end
|
125
|
-
|
126
|
-
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' }
|
129
|
-
|
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' }]
|
132
|
-
end
|
133
|
-
|
134
|
-
def test_recursively_included_template_does_not_produce_endless_loop
|
135
|
-
infinite_file_system = Class.new do
|
136
|
-
def read_template_file(template_path)
|
137
|
-
"-{% include 'loop' %}"
|
138
|
-
end
|
139
|
-
end
|
140
|
-
|
141
|
-
Liquid::Template.file_system = infinite_file_system.new
|
142
|
-
|
143
|
-
assert_raises(Liquid::StackLevelError) do
|
144
|
-
Template.parse("{% include 'loop' %}").render!
|
145
|
-
end
|
146
|
-
end
|
147
|
-
|
148
|
-
def test_dynamically_choosen_template
|
149
|
-
assert_template_result "Test123", "{% include template %}", "template" => 'Test123'
|
150
|
-
assert_template_result "Test321", "{% include template %}", "template" => 'Test321'
|
151
|
-
|
152
|
-
assert_template_result "Product: Draft 151cm ", "{% include template for product %}",
|
153
|
-
"template" => 'product', 'product' => { 'title' => 'Draft 151cm' }
|
154
|
-
end
|
155
|
-
|
156
|
-
def test_include_tag_caches_second_read_of_same_partial
|
157
|
-
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
|
161
|
-
end
|
162
|
-
|
163
|
-
def test_include_tag_doesnt_cache_partials_across_renders
|
164
|
-
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
|
168
|
-
|
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
|
172
|
-
end
|
173
|
-
|
174
|
-
def test_include_tag_within_if_statement
|
175
|
-
assert_template_result "foo_if_true", "{% if true %}{% include 'foo_if_true' %}{% endif %}"
|
176
|
-
end
|
177
|
-
|
178
|
-
def test_custom_include_tag
|
179
|
-
original_tag = Liquid::Template.tags['include']
|
180
|
-
Liquid::Template.tags['include'] = CustomInclude
|
181
|
-
begin
|
182
|
-
assert_equal "custom_foo",
|
183
|
-
Template.parse("{% include 'custom_foo' %}").render!
|
184
|
-
ensure
|
185
|
-
Liquid::Template.tags['include'] = original_tag
|
186
|
-
end
|
187
|
-
end
|
188
|
-
|
189
|
-
def test_custom_include_tag_within_if_statement
|
190
|
-
original_tag = Liquid::Template.tags['include']
|
191
|
-
Liquid::Template.tags['include'] = CustomInclude
|
192
|
-
begin
|
193
|
-
assert_equal "custom_foo_if_true",
|
194
|
-
Template.parse("{% if true %}{% include 'custom_foo_if_true' %}{% endif %}").render!
|
195
|
-
ensure
|
196
|
-
Liquid::Template.tags['include'] = original_tag
|
197
|
-
end
|
198
|
-
end
|
199
|
-
|
200
|
-
def test_does_not_add_error_in_strict_mode_for_missing_variable
|
201
|
-
Liquid::Template.file_system = TestFileSystem.new
|
202
|
-
|
203
|
-
a = Liquid::Template.parse(' {% include "nested_template" %}')
|
204
|
-
a.render!
|
205
|
-
assert_empty a.errors
|
206
|
-
end
|
207
|
-
|
208
|
-
def test_passing_options_to_included_templates
|
209
|
-
assert_raises(Liquid::SyntaxError) do
|
210
|
-
Template.parse("{% include template %}", error_mode: :strict).render!("template" => '{{ "X" || downcase }}')
|
211
|
-
end
|
212
|
-
with_error_mode(:lax) do
|
213
|
-
assert_equal 'x', Template.parse("{% include template %}", error_mode: :strict, include_options_blacklist: true).render!("template" => '{{ "X" || downcase }}')
|
214
|
-
end
|
215
|
-
assert_raises(Liquid::SyntaxError) do
|
216
|
-
Template.parse("{% include template %}", error_mode: :strict, include_options_blacklist: [:locale]).render!("template" => '{{ "X" || downcase }}')
|
217
|
-
end
|
218
|
-
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 }}')
|
220
|
-
end
|
221
|
-
end
|
222
|
-
|
223
|
-
def test_render_raise_argument_error_when_template_is_undefined
|
224
|
-
assert_raises(Liquid::ArgumentError) do
|
225
|
-
template = Liquid::Template.parse('{% include undefined_variable %}')
|
226
|
-
template.render!
|
227
|
-
end
|
228
|
-
assert_raises(Liquid::ArgumentError) do
|
229
|
-
template = Liquid::Template.parse('{% include nil %}')
|
230
|
-
template.render!
|
231
|
-
end
|
232
|
-
end
|
233
|
-
|
234
|
-
def test_including_via_variable_value
|
235
|
-
assert_template_result "from TestFileSystem", "{% assign page = 'pick_a_source' %}{% include page %}"
|
236
|
-
|
237
|
-
assert_template_result "Product: Draft 151cm ", "{% assign page = 'product' %}{% include page %}", "product" => { 'title' => 'Draft 151cm' }
|
238
|
-
|
239
|
-
assert_template_result "Product: Draft 151cm ", "{% assign page = 'product' %}{% include page for foo %}", "foo" => { 'title' => 'Draft 151cm' }
|
240
|
-
end
|
241
|
-
|
242
|
-
def test_including_with_strict_variables
|
243
|
-
template = Liquid::Template.parse("{% include 'simple' %}", error_mode: :warn)
|
244
|
-
template.render(nil, strict_variables: true)
|
245
|
-
|
246
|
-
assert_equal [], template.errors
|
247
|
-
end
|
248
|
-
|
249
|
-
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 %}"
|
252
|
-
end
|
253
|
-
end # IncludeTagTest
|
@@ -1,23 +0,0 @@
|
|
1
|
-
require 'test_helper'
|
2
|
-
|
3
|
-
class IncrementTagTest < Minitest::Test
|
4
|
-
include Liquid
|
5
|
-
|
6
|
-
def test_inc
|
7
|
-
assert_template_result('0', '{%increment port %}', {})
|
8
|
-
assert_template_result('0 1', '{%increment port %} {%increment port%}', {})
|
9
|
-
assert_template_result('0 0 1 2 1',
|
10
|
-
'{%increment port %} {%increment starboard%} ' \
|
11
|
-
'{%increment port %} {%increment port%} ' \
|
12
|
-
'{%increment starboard %}', {})
|
13
|
-
end
|
14
|
-
|
15
|
-
def test_dec
|
16
|
-
assert_template_result('9', '{%decrement port %}', { 'port' => 10 })
|
17
|
-
assert_template_result('-1 -2', '{%decrement port %} {%decrement port%}', {})
|
18
|
-
assert_template_result('1 5 2 2 5',
|
19
|
-
'{%increment port %} {%increment starboard%} ' \
|
20
|
-
'{%increment port %} {%decrement port%} ' \
|
21
|
-
'{%decrement starboard %}', { 'port' => 1, 'starboard' => 5 })
|
22
|
-
end
|
23
|
-
end
|
@@ -1,31 +0,0 @@
|
|
1
|
-
require 'test_helper'
|
2
|
-
|
3
|
-
class RawTagTest < Minitest::Test
|
4
|
-
include Liquid
|
5
|
-
|
6
|
-
def test_tag_in_raw
|
7
|
-
assert_template_result '{% comment %} test {% endcomment %}',
|
8
|
-
'{% raw %}{% comment %} test {% endcomment %}{% endraw %}'
|
9
|
-
end
|
10
|
-
|
11
|
-
def test_output_in_raw
|
12
|
-
assert_template_result '{{ test }}', '{% raw %}{{ test }}{% endraw %}'
|
13
|
-
end
|
14
|
-
|
15
|
-
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 }}'
|
24
|
-
end
|
25
|
-
|
26
|
-
def test_invalid_raw
|
27
|
-
assert_match_syntax_error(/tag was never closed/, '{% raw %} foo')
|
28
|
-
assert_match_syntax_error(/Valid syntax/, '{% raw } foo {% endraw %}')
|
29
|
-
assert_match_syntax_error(/Valid syntax/, '{% raw } foo %}{% endraw %}')
|
30
|
-
end
|
31
|
-
end
|
@@ -1,296 +0,0 @@
|
|
1
|
-
require 'test_helper'
|
2
|
-
|
3
|
-
class StandardTagTest < Minitest::Test
|
4
|
-
include Liquid
|
5
|
-
|
6
|
-
def test_no_transform
|
7
|
-
assert_template_result('this text should come out of the template without change...',
|
8
|
-
'this text should come out of the template without change...')
|
9
|
-
|
10
|
-
assert_template_result('blah', 'blah')
|
11
|
-
assert_template_result('<blah>', '<blah>')
|
12
|
-
assert_template_result('|,.:', '|,.:')
|
13
|
-
assert_template_result('', '')
|
14
|
-
|
15
|
-
text = %(this shouldnt see any transformation either but has multiple lines
|
16
|
-
as you can clearly see here ...)
|
17
|
-
assert_template_result(text, text)
|
18
|
-
end
|
19
|
-
|
20
|
-
def test_has_a_block_which_does_nothing
|
21
|
-
assert_template_result(%(the comment block should be removed .. right?),
|
22
|
-
%(the comment block should be removed {%comment%} be gone.. {%endcomment%} .. right?))
|
23
|
-
|
24
|
-
assert_template_result('', '{%comment%}{%endcomment%}')
|
25
|
-
assert_template_result('', '{%comment%}{% endcomment %}')
|
26
|
-
assert_template_result('', '{% comment %}{%endcomment%}')
|
27
|
-
assert_template_result('', '{% comment %}{% endcomment %}')
|
28
|
-
assert_template_result('', '{%comment%}comment{%endcomment%}')
|
29
|
-
assert_template_result('', '{% comment %}comment{% endcomment %}')
|
30
|
-
assert_template_result('', '{% comment %} 1 {% comment %} 2 {% endcomment %} 3 {% endcomment %}')
|
31
|
-
|
32
|
-
assert_template_result('', '{%comment%}{%blabla%}{%endcomment%}')
|
33
|
-
assert_template_result('', '{% comment %}{% blabla %}{% endcomment %}')
|
34
|
-
assert_template_result('', '{%comment%}{% endif %}{%endcomment%}')
|
35
|
-
assert_template_result('', '{% comment %}{% endwhatever %}{% endcomment %}')
|
36
|
-
assert_template_result('', '{% comment %}{% raw %} {{%%%%}} }} { {% endcomment %} {% comment {% endraw %} {% endcomment %}')
|
37
|
-
|
38
|
-
assert_template_result('foobar', 'foo{%comment%}comment{%endcomment%}bar')
|
39
|
-
assert_template_result('foobar', 'foo{% comment %}comment{% endcomment %}bar')
|
40
|
-
assert_template_result('foobar', 'foo{%comment%} comment {%endcomment%}bar')
|
41
|
-
assert_template_result('foobar', 'foo{% comment %} comment {% endcomment %}bar')
|
42
|
-
|
43
|
-
assert_template_result('foo bar', 'foo {%comment%} {%endcomment%} bar')
|
44
|
-
assert_template_result('foo bar', 'foo {%comment%}comment{%endcomment%} bar')
|
45
|
-
assert_template_result('foo bar', 'foo {%comment%} comment {%endcomment%} bar')
|
46
|
-
|
47
|
-
assert_template_result('foobar', 'foo{%comment%}
|
48
|
-
{%endcomment%}bar')
|
49
|
-
end
|
50
|
-
|
51
|
-
def test_hyphenated_assign
|
52
|
-
assigns = { 'a-b' => '1' }
|
53
|
-
assert_template_result('a-b:1 a-b:2', 'a-b:{{a-b}} {%assign a-b = 2 %}a-b:{{a-b}}', assigns)
|
54
|
-
end
|
55
|
-
|
56
|
-
def test_assign_with_colon_and_spaces
|
57
|
-
assigns = { 'var' => { 'a:b c' => { 'paged' => '1' } } }
|
58
|
-
assert_template_result('var2: 1', '{%assign var2 = var["a:b c"].paged %}var2: {{var2}}', assigns)
|
59
|
-
end
|
60
|
-
|
61
|
-
def test_capture
|
62
|
-
assigns = { 'var' => 'content' }
|
63
|
-
assert_template_result('content foo content foo ',
|
64
|
-
'{{ var2 }}{% capture var2 %}{{ var }} foo {% endcapture %}{{ var2 }}{{ var2 }}',
|
65
|
-
assigns)
|
66
|
-
end
|
67
|
-
|
68
|
-
def test_capture_detects_bad_syntax
|
69
|
-
assert_raises(SyntaxError) do
|
70
|
-
assert_template_result('content foo content foo ',
|
71
|
-
'{{ var2 }}{% capture %}{{ var }} foo {% endcapture %}{{ var2 }}{{ var2 }}',
|
72
|
-
{ 'var' => 'content' })
|
73
|
-
end
|
74
|
-
end
|
75
|
-
|
76
|
-
def test_case
|
77
|
-
assigns = { 'condition' => 2 }
|
78
|
-
assert_template_result(' its 2 ',
|
79
|
-
'{% case condition %}{% when 1 %} its 1 {% when 2 %} its 2 {% endcase %}',
|
80
|
-
assigns)
|
81
|
-
|
82
|
-
assigns = { 'condition' => 1 }
|
83
|
-
assert_template_result(' its 1 ',
|
84
|
-
'{% case condition %}{% when 1 %} its 1 {% when 2 %} its 2 {% endcase %}',
|
85
|
-
assigns)
|
86
|
-
|
87
|
-
assigns = { 'condition' => 3 }
|
88
|
-
assert_template_result('',
|
89
|
-
'{% case condition %}{% when 1 %} its 1 {% when 2 %} its 2 {% endcase %}',
|
90
|
-
assigns)
|
91
|
-
|
92
|
-
assigns = { 'condition' => "string here" }
|
93
|
-
assert_template_result(' hit ',
|
94
|
-
'{% case condition %}{% when "string here" %} hit {% endcase %}',
|
95
|
-
assigns)
|
96
|
-
|
97
|
-
assigns = { 'condition' => "bad string here" }
|
98
|
-
assert_template_result('',
|
99
|
-
'{% case condition %}{% when "string here" %} hit {% endcase %}',\
|
100
|
-
assigns)
|
101
|
-
end
|
102
|
-
|
103
|
-
def test_case_with_else
|
104
|
-
assigns = { 'condition' => 5 }
|
105
|
-
assert_template_result(' hit ',
|
106
|
-
'{% case condition %}{% when 5 %} hit {% else %} else {% endcase %}',
|
107
|
-
assigns)
|
108
|
-
|
109
|
-
assigns = { 'condition' => 6 }
|
110
|
-
assert_template_result(' else ',
|
111
|
-
'{% case condition %}{% when 5 %} hit {% else %} else {% endcase %}',
|
112
|
-
assigns)
|
113
|
-
|
114
|
-
assigns = { 'condition' => 6 }
|
115
|
-
assert_template_result(' else ',
|
116
|
-
'{% case condition %} {% when 5 %} hit {% else %} else {% endcase %}',
|
117
|
-
assigns)
|
118
|
-
end
|
119
|
-
|
120
|
-
def test_case_on_size
|
121
|
-
assert_template_result('', '{% case a.size %}{% when 1 %}1{% when 2 %}2{% endcase %}', 'a' => [])
|
122
|
-
assert_template_result('1', '{% case a.size %}{% when 1 %}1{% when 2 %}2{% endcase %}', 'a' => [1])
|
123
|
-
assert_template_result('2', '{% case a.size %}{% when 1 %}1{% when 2 %}2{% endcase %}', 'a' => [1, 1])
|
124
|
-
assert_template_result('', '{% case a.size %}{% when 1 %}1{% when 2 %}2{% endcase %}', 'a' => [1, 1, 1])
|
125
|
-
assert_template_result('', '{% case a.size %}{% when 1 %}1{% when 2 %}2{% endcase %}', 'a' => [1, 1, 1, 1])
|
126
|
-
assert_template_result('', '{% case a.size %}{% when 1 %}1{% when 2 %}2{% endcase %}', 'a' => [1, 1, 1, 1, 1])
|
127
|
-
end
|
128
|
-
|
129
|
-
def test_case_on_size_with_else
|
130
|
-
assert_template_result('else',
|
131
|
-
'{% case a.size %}{% when 1 %}1{% when 2 %}2{% else %}else{% endcase %}',
|
132
|
-
'a' => [])
|
133
|
-
|
134
|
-
assert_template_result('1',
|
135
|
-
'{% case a.size %}{% when 1 %}1{% when 2 %}2{% else %}else{% endcase %}',
|
136
|
-
'a' => [1])
|
137
|
-
|
138
|
-
assert_template_result('2',
|
139
|
-
'{% case a.size %}{% when 1 %}1{% when 2 %}2{% else %}else{% endcase %}',
|
140
|
-
'a' => [1, 1])
|
141
|
-
|
142
|
-
assert_template_result('else',
|
143
|
-
'{% case a.size %}{% when 1 %}1{% when 2 %}2{% else %}else{% endcase %}',
|
144
|
-
'a' => [1, 1, 1])
|
145
|
-
|
146
|
-
assert_template_result('else',
|
147
|
-
'{% case a.size %}{% when 1 %}1{% when 2 %}2{% else %}else{% endcase %}',
|
148
|
-
'a' => [1, 1, 1, 1])
|
149
|
-
|
150
|
-
assert_template_result('else',
|
151
|
-
'{% case a.size %}{% when 1 %}1{% when 2 %}2{% else %}else{% endcase %}',
|
152
|
-
'a' => [1, 1, 1, 1, 1])
|
153
|
-
end
|
154
|
-
|
155
|
-
def test_case_on_length_with_else
|
156
|
-
assert_template_result('else',
|
157
|
-
'{% case a.empty? %}{% when true %}true{% when false %}false{% else %}else{% endcase %}',
|
158
|
-
{})
|
159
|
-
|
160
|
-
assert_template_result('false',
|
161
|
-
'{% case false %}{% when true %}true{% when false %}false{% else %}else{% endcase %}',
|
162
|
-
{})
|
163
|
-
|
164
|
-
assert_template_result('true',
|
165
|
-
'{% case true %}{% when true %}true{% when false %}false{% else %}else{% endcase %}',
|
166
|
-
{})
|
167
|
-
|
168
|
-
assert_template_result('else',
|
169
|
-
'{% case NULL %}{% when true %}true{% when false %}false{% else %}else{% endcase %}',
|
170
|
-
{})
|
171
|
-
end
|
172
|
-
|
173
|
-
def test_assign_from_case
|
174
|
-
# Example from the shopify forums
|
175
|
-
code = "{% case collection.handle %}{% when 'menswear-jackets' %}{% assign ptitle = 'menswear' %}{% when 'menswear-t-shirts' %}{% assign ptitle = 'menswear' %}{% else %}{% assign ptitle = 'womenswear' %}{% endcase %}{{ ptitle }}"
|
176
|
-
template = Liquid::Template.parse(code)
|
177
|
-
assert_equal "menswear", template.render!("collection" => { 'handle' => 'menswear-jackets' })
|
178
|
-
assert_equal "menswear", template.render!("collection" => { 'handle' => 'menswear-t-shirts' })
|
179
|
-
assert_equal "womenswear", template.render!("collection" => { 'handle' => 'x' })
|
180
|
-
assert_equal "womenswear", template.render!("collection" => { 'handle' => 'y' })
|
181
|
-
assert_equal "womenswear", template.render!("collection" => { 'handle' => 'z' })
|
182
|
-
end
|
183
|
-
|
184
|
-
def test_case_when_or
|
185
|
-
code = '{% case condition %}{% when 1 or 2 or 3 %} its 1 or 2 or 3 {% when 4 %} its 4 {% endcase %}'
|
186
|
-
assert_template_result(' its 1 or 2 or 3 ', code, { 'condition' => 1 })
|
187
|
-
assert_template_result(' its 1 or 2 or 3 ', code, { 'condition' => 2 })
|
188
|
-
assert_template_result(' its 1 or 2 or 3 ', code, { 'condition' => 3 })
|
189
|
-
assert_template_result(' its 4 ', code, { 'condition' => 4 })
|
190
|
-
assert_template_result('', code, { 'condition' => 5 })
|
191
|
-
|
192
|
-
code = '{% case condition %}{% when 1 or "string" or null %} its 1 or 2 or 3 {% when 4 %} its 4 {% endcase %}'
|
193
|
-
assert_template_result(' its 1 or 2 or 3 ', code, { 'condition' => 1 })
|
194
|
-
assert_template_result(' its 1 or 2 or 3 ', code, { 'condition' => 'string' })
|
195
|
-
assert_template_result(' its 1 or 2 or 3 ', code, { 'condition' => nil })
|
196
|
-
assert_template_result('', code, { 'condition' => 'something else' })
|
197
|
-
end
|
198
|
-
|
199
|
-
def test_case_when_comma
|
200
|
-
code = '{% case condition %}{% when 1, 2, 3 %} its 1 or 2 or 3 {% when 4 %} its 4 {% endcase %}'
|
201
|
-
assert_template_result(' its 1 or 2 or 3 ', code, { 'condition' => 1 })
|
202
|
-
assert_template_result(' its 1 or 2 or 3 ', code, { 'condition' => 2 })
|
203
|
-
assert_template_result(' its 1 or 2 or 3 ', code, { 'condition' => 3 })
|
204
|
-
assert_template_result(' its 4 ', code, { 'condition' => 4 })
|
205
|
-
assert_template_result('', code, { 'condition' => 5 })
|
206
|
-
|
207
|
-
code = '{% case condition %}{% when 1, "string", null %} its 1 or 2 or 3 {% when 4 %} its 4 {% endcase %}'
|
208
|
-
assert_template_result(' its 1 or 2 or 3 ', code, { 'condition' => 1 })
|
209
|
-
assert_template_result(' its 1 or 2 or 3 ', code, { 'condition' => 'string' })
|
210
|
-
assert_template_result(' its 1 or 2 or 3 ', code, { 'condition' => nil })
|
211
|
-
assert_template_result('', code, { 'condition' => 'something else' })
|
212
|
-
end
|
213
|
-
|
214
|
-
def test_assign
|
215
|
-
assert_template_result 'variable', '{% assign a = "variable"%}{{a}}'
|
216
|
-
end
|
217
|
-
|
218
|
-
def test_assign_unassigned
|
219
|
-
assigns = { 'var' => 'content' }
|
220
|
-
assert_template_result('var2: var2:content', 'var2:{{var2}} {%assign var2 = var%} var2:{{var2}}', assigns)
|
221
|
-
end
|
222
|
-
|
223
|
-
def test_assign_an_empty_string
|
224
|
-
assert_template_result '', '{% assign a = ""%}{{a}}'
|
225
|
-
end
|
226
|
-
|
227
|
-
def test_assign_is_global
|
228
|
-
assert_template_result 'variable', '{%for i in (1..2) %}{% assign a = "variable"%}{% endfor %}{{a}}'
|
229
|
-
end
|
230
|
-
|
231
|
-
def test_case_detects_bad_syntax
|
232
|
-
assert_raises(SyntaxError) do
|
233
|
-
assert_template_result('', '{% case false %}{% when %}true{% endcase %}', {})
|
234
|
-
end
|
235
|
-
|
236
|
-
assert_raises(SyntaxError) do
|
237
|
-
assert_template_result('', '{% case false %}{% huh %}true{% endcase %}', {})
|
238
|
-
end
|
239
|
-
end
|
240
|
-
|
241
|
-
def test_cycle
|
242
|
-
assert_template_result('one', '{%cycle "one", "two"%}')
|
243
|
-
assert_template_result('one two', '{%cycle "one", "two"%} {%cycle "one", "two"%}')
|
244
|
-
assert_template_result(' two', '{%cycle "", "two"%} {%cycle "", "two"%}')
|
245
|
-
|
246
|
-
assert_template_result('one two one', '{%cycle "one", "two"%} {%cycle "one", "two"%} {%cycle "one", "two"%}')
|
247
|
-
|
248
|
-
assert_template_result('text-align: left text-align: right',
|
249
|
-
'{%cycle "text-align: left", "text-align: right" %} {%cycle "text-align: left", "text-align: right"%}')
|
250
|
-
end
|
251
|
-
|
252
|
-
def test_multiple_cycles
|
253
|
-
assert_template_result('1 2 1 1 2 3 1',
|
254
|
-
'{%cycle 1,2%} {%cycle 1,2%} {%cycle 1,2%} {%cycle 1,2,3%} {%cycle 1,2,3%} {%cycle 1,2,3%} {%cycle 1,2,3%}')
|
255
|
-
end
|
256
|
-
|
257
|
-
def test_multiple_named_cycles
|
258
|
-
assert_template_result('one one two two one one',
|
259
|
-
'{%cycle 1: "one", "two" %} {%cycle 2: "one", "two" %} {%cycle 1: "one", "two" %} {%cycle 2: "one", "two" %} {%cycle 1: "one", "two" %} {%cycle 2: "one", "two" %}')
|
260
|
-
end
|
261
|
-
|
262
|
-
def test_multiple_named_cycles_with_names_from_context
|
263
|
-
assigns = { "var1" => 1, "var2" => 2 }
|
264
|
-
assert_template_result('one one two two one one',
|
265
|
-
'{%cycle var1: "one", "two" %} {%cycle var2: "one", "two" %} {%cycle var1: "one", "two" %} {%cycle var2: "one", "two" %} {%cycle var1: "one", "two" %} {%cycle var2: "one", "two" %}', assigns)
|
266
|
-
end
|
267
|
-
|
268
|
-
def test_size_of_array
|
269
|
-
assigns = { "array" => [1, 2, 3, 4] }
|
270
|
-
assert_template_result('array has 4 elements', "array has {{ array.size }} elements", assigns)
|
271
|
-
end
|
272
|
-
|
273
|
-
def test_size_of_hash
|
274
|
-
assigns = { "hash" => { a: 1, b: 2, c: 3, d: 4 } }
|
275
|
-
assert_template_result('hash has 4 elements', "hash has {{ hash.size }} elements", assigns)
|
276
|
-
end
|
277
|
-
|
278
|
-
def test_illegal_symbols
|
279
|
-
assert_template_result('', '{% if true == empty %}?{% endif %}', {})
|
280
|
-
assert_template_result('', '{% if true == null %}?{% endif %}', {})
|
281
|
-
assert_template_result('', '{% if empty == true %}?{% endif %}', {})
|
282
|
-
assert_template_result('', '{% if null == true %}?{% endif %}', {})
|
283
|
-
end
|
284
|
-
|
285
|
-
def test_ifchanged
|
286
|
-
assigns = { 'array' => [ 1, 1, 2, 2, 3, 3] }
|
287
|
-
assert_template_result('123', '{%for item in array%}{%ifchanged%}{{item}}{% endifchanged %}{%endfor%}', assigns)
|
288
|
-
|
289
|
-
assigns = { 'array' => [ 1, 1, 1, 1] }
|
290
|
-
assert_template_result('1', '{%for item in array%}{%ifchanged%}{{item}}{% endifchanged %}{%endfor%}', assigns)
|
291
|
-
end
|
292
|
-
|
293
|
-
def test_multiline_tag
|
294
|
-
assert_template_result '0 1 2 3', "0{%\nfor i in (1..3)\n%} {{\ni\n}}{%\nendfor\n%}"
|
295
|
-
end
|
296
|
-
end # StandardTagTest
|