liquid 5.1.0 → 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 +35 -0
- data/README.md +4 -4
- data/lib/liquid/block_body.rb +6 -6
- data/lib/liquid/condition.rb +7 -1
- data/lib/liquid/context.rb +6 -2
- data/lib/liquid/expression.rb +11 -10
- data/lib/liquid/forloop_drop.rb +44 -1
- data/lib/liquid/locales/en.yml +6 -5
- data/lib/liquid/partial_cache.rb +3 -3
- data/lib/liquid/registers.rb +51 -0
- data/lib/liquid/standardfilters.rb +463 -75
- data/lib/liquid/strainer_factory.rb +15 -10
- data/lib/liquid/strainer_template.rb +9 -0
- data/lib/liquid/tablerowloop_drop.rb +58 -1
- data/lib/liquid/tags/assign.rb +12 -8
- data/lib/liquid/tags/break.rb +8 -0
- data/lib/liquid/tags/capture.rb +13 -10
- data/lib/liquid/tags/case.rb +21 -0
- data/lib/liquid/tags/comment.rb +13 -0
- data/lib/liquid/tags/continue.rb +8 -9
- data/lib/liquid/tags/cycle.rb +12 -11
- data/lib/liquid/tags/decrement.rb +16 -17
- data/lib/liquid/tags/echo.rb +16 -9
- data/lib/liquid/tags/for.rb +22 -43
- data/lib/liquid/tags/if.rb +11 -9
- data/lib/liquid/tags/include.rb +15 -13
- data/lib/liquid/tags/increment.rb +16 -14
- data/lib/liquid/tags/inline_comment.rb +43 -0
- data/lib/liquid/tags/raw.rb +11 -0
- data/lib/liquid/tags/render.rb +29 -4
- data/lib/liquid/tags/table_row.rb +22 -0
- data/lib/liquid/tags/unless.rb +15 -4
- data/lib/liquid/template.rb +2 -3
- data/lib/liquid/variable.rb +4 -4
- data/lib/liquid/variable_lookup.rb +10 -7
- data/lib/liquid/version.rb +1 -1
- data/lib/liquid.rb +4 -4
- metadata +7 -121
- data/lib/liquid/register.rb +0 -6
- data/lib/liquid/static_registers.rb +0 -44
- data/test/fixtures/en_locale.yml +0 -9
- data/test/integration/assign_test.rb +0 -117
- data/test/integration/blank_test.rb +0 -109
- data/test/integration/block_test.rb +0 -58
- data/test/integration/capture_test.rb +0 -58
- data/test/integration/context_test.rb +0 -636
- data/test/integration/document_test.rb +0 -21
- data/test/integration/drop_test.rb +0 -257
- data/test/integration/error_handling_test.rb +0 -272
- data/test/integration/expression_test.rb +0 -46
- data/test/integration/filter_test.rb +0 -189
- data/test/integration/hash_ordering_test.rb +0 -25
- data/test/integration/output_test.rb +0 -125
- data/test/integration/parsing_quirks_test.rb +0 -134
- data/test/integration/profiler_test.rb +0 -213
- data/test/integration/security_test.rb +0 -89
- data/test/integration/standard_filter_test.rb +0 -880
- data/test/integration/tag/disableable_test.rb +0 -59
- data/test/integration/tag_test.rb +0 -45
- data/test/integration/tags/break_tag_test.rb +0 -17
- data/test/integration/tags/continue_tag_test.rb +0 -17
- data/test/integration/tags/echo_test.rb +0 -13
- data/test/integration/tags/for_tag_test.rb +0 -466
- data/test/integration/tags/if_else_tag_test.rb +0 -190
- data/test/integration/tags/include_tag_test.rb +0 -269
- data/test/integration/tags/increment_tag_test.rb +0 -25
- data/test/integration/tags/liquid_tag_test.rb +0 -116
- data/test/integration/tags/raw_tag_test.rb +0 -34
- data/test/integration/tags/render_tag_test.rb +0 -213
- data/test/integration/tags/standard_tag_test.rb +0 -303
- data/test/integration/tags/statements_test.rb +0 -113
- data/test/integration/tags/table_row_test.rb +0 -66
- data/test/integration/tags/unless_else_tag_test.rb +0 -28
- data/test/integration/template_test.rb +0 -340
- data/test/integration/trim_mode_test.rb +0 -563
- data/test/integration/variable_test.rb +0 -138
- data/test/test_helper.rb +0 -207
- data/test/unit/block_unit_test.rb +0 -53
- data/test/unit/condition_unit_test.rb +0 -168
- data/test/unit/file_system_unit_test.rb +0 -37
- data/test/unit/i18n_unit_test.rb +0 -39
- data/test/unit/lexer_unit_test.rb +0 -53
- data/test/unit/parse_tree_visitor_test.rb +0 -261
- data/test/unit/parser_unit_test.rb +0 -84
- data/test/unit/partial_cache_unit_test.rb +0 -128
- data/test/unit/regexp_unit_test.rb +0 -46
- data/test/unit/static_registers_unit_test.rb +0 -156
- data/test/unit/strainer_factory_unit_test.rb +0 -100
- data/test/unit/strainer_template_unit_test.rb +0 -82
- data/test/unit/tag_unit_test.rb +0 -23
- data/test/unit/tags/case_tag_unit_test.rb +0 -12
- data/test/unit/tags/for_tag_unit_test.rb +0 -15
- data/test/unit/tags/if_tag_unit_test.rb +0 -10
- data/test/unit/template_factory_unit_test.rb +0 -12
- data/test/unit/template_unit_test.rb +0 -87
- data/test/unit/tokenizer_unit_test.rb +0 -62
- data/test/unit/variable_unit_test.rb +0 -164
@@ -1,59 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'test_helper'
|
4
|
-
|
5
|
-
class TagDisableableTest < Minitest::Test
|
6
|
-
include Liquid
|
7
|
-
|
8
|
-
module RenderTagName
|
9
|
-
def render(_context)
|
10
|
-
tag_name
|
11
|
-
end
|
12
|
-
end
|
13
|
-
|
14
|
-
class Custom < Tag
|
15
|
-
prepend Liquid::Tag::Disableable
|
16
|
-
include RenderTagName
|
17
|
-
end
|
18
|
-
|
19
|
-
class Custom2 < Tag
|
20
|
-
prepend Liquid::Tag::Disableable
|
21
|
-
include RenderTagName
|
22
|
-
end
|
23
|
-
|
24
|
-
class DisableCustom < Block
|
25
|
-
disable_tags "custom"
|
26
|
-
end
|
27
|
-
|
28
|
-
class DisableBoth < Block
|
29
|
-
disable_tags "custom", "custom2"
|
30
|
-
end
|
31
|
-
|
32
|
-
def test_block_tag_disabling_nested_tag
|
33
|
-
with_disableable_tags do
|
34
|
-
with_custom_tag('disable', DisableCustom) do
|
35
|
-
output = Template.parse('{% disable %}{% custom %};{% custom2 %}{% enddisable %}').render
|
36
|
-
assert_equal('Liquid error: custom usage is not allowed in this context;custom2', output)
|
37
|
-
end
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
def test_block_tag_disabling_multiple_nested_tags
|
42
|
-
with_disableable_tags do
|
43
|
-
with_custom_tag('disable', DisableBoth) do
|
44
|
-
output = Template.parse('{% disable %}{% custom %};{% custom2 %}{% enddisable %}').render
|
45
|
-
assert_equal('Liquid error: custom usage is not allowed in this context;Liquid error: custom2 usage is not allowed in this context', output)
|
46
|
-
end
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
private
|
51
|
-
|
52
|
-
def with_disableable_tags
|
53
|
-
with_custom_tag('custom', Custom) do
|
54
|
-
with_custom_tag('custom2', Custom2) do
|
55
|
-
yield
|
56
|
-
end
|
57
|
-
end
|
58
|
-
end
|
59
|
-
end
|
@@ -1,45 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'test_helper'
|
4
|
-
|
5
|
-
class TagTest < Minitest::Test
|
6
|
-
include Liquid
|
7
|
-
|
8
|
-
def test_custom_tags_have_a_default_render_to_output_buffer_method_for_backwards_compatibility
|
9
|
-
klass1 = Class.new(Tag) do
|
10
|
-
def render(*)
|
11
|
-
'hello'
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
15
|
-
with_custom_tag('blabla', klass1) do
|
16
|
-
template = Liquid::Template.parse("{% blabla %}")
|
17
|
-
|
18
|
-
assert_equal('hello', template.render)
|
19
|
-
|
20
|
-
buf = +''
|
21
|
-
output = template.render({}, output: buf)
|
22
|
-
assert_equal('hello', output)
|
23
|
-
assert_equal('hello', buf)
|
24
|
-
assert_equal(buf.object_id, output.object_id)
|
25
|
-
end
|
26
|
-
|
27
|
-
klass2 = Class.new(klass1) do
|
28
|
-
def render(*)
|
29
|
-
'foo' + super + 'bar'
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
with_custom_tag('blabla', klass2) do
|
34
|
-
template = Liquid::Template.parse("{% blabla %}")
|
35
|
-
|
36
|
-
assert_equal('foohellobar', template.render)
|
37
|
-
|
38
|
-
buf = +''
|
39
|
-
output = template.render({}, output: buf)
|
40
|
-
assert_equal('foohellobar', output)
|
41
|
-
assert_equal('foohellobar', buf)
|
42
|
-
assert_equal(buf.object_id, output.object_id)
|
43
|
-
end
|
44
|
-
end
|
45
|
-
end
|
@@ -1,17 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'test_helper'
|
4
|
-
|
5
|
-
class BreakTagTest < Minitest::Test
|
6
|
-
include Liquid
|
7
|
-
|
8
|
-
# tests that no weird errors are raised if break is called outside of a
|
9
|
-
# block
|
10
|
-
def test_break_with_no_block
|
11
|
-
assigns = { 'i' => 1 }
|
12
|
-
markup = '{% break %}'
|
13
|
-
expected = ''
|
14
|
-
|
15
|
-
assert_template_result(expected, markup, assigns)
|
16
|
-
end
|
17
|
-
end
|
@@ -1,17 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'test_helper'
|
4
|
-
|
5
|
-
class ContinueTagTest < Minitest::Test
|
6
|
-
include Liquid
|
7
|
-
|
8
|
-
# tests that no weird errors are raised if continue is called outside of a
|
9
|
-
# block
|
10
|
-
def test_continue_with_no_block
|
11
|
-
assigns = {}
|
12
|
-
markup = '{% continue %}'
|
13
|
-
expected = ''
|
14
|
-
|
15
|
-
assert_template_result(expected, markup, assigns)
|
16
|
-
end
|
17
|
-
end
|
@@ -1,13 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'test_helper'
|
4
|
-
|
5
|
-
class EchoTest < Minitest::Test
|
6
|
-
include Liquid
|
7
|
-
|
8
|
-
def test_echo_outputs_its_input
|
9
|
-
assert_template_result('BAR', <<~LIQUID, 'variable-name' => 'bar')
|
10
|
-
{%- echo variable-name | upcase -%}
|
11
|
-
LIQUID
|
12
|
-
end
|
13
|
-
end
|
@@ -1,466 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'test_helper'
|
4
|
-
|
5
|
-
class ThingWithValue < Liquid::Drop
|
6
|
-
def value
|
7
|
-
3
|
8
|
-
end
|
9
|
-
end
|
10
|
-
|
11
|
-
class ForTagTest < Minitest::Test
|
12
|
-
include Liquid
|
13
|
-
|
14
|
-
def test_for
|
15
|
-
assert_template_result(' yo yo yo yo ', '{%for item in array%} yo {%endfor%}', 'array' => [1, 2, 3, 4])
|
16
|
-
assert_template_result('yoyo', '{%for item in array%}yo{%endfor%}', 'array' => [1, 2])
|
17
|
-
assert_template_result(' yo ', '{%for item in array%} yo {%endfor%}', 'array' => [1])
|
18
|
-
assert_template_result('', '{%for item in array%}{%endfor%}', 'array' => [1, 2])
|
19
|
-
expected = <<HERE
|
20
|
-
|
21
|
-
yo
|
22
|
-
|
23
|
-
yo
|
24
|
-
|
25
|
-
yo
|
26
|
-
|
27
|
-
HERE
|
28
|
-
template = <<~HERE
|
29
|
-
{%for item in array%}
|
30
|
-
yo
|
31
|
-
{%endfor%}
|
32
|
-
HERE
|
33
|
-
assert_template_result(expected, template, 'array' => [1, 2, 3])
|
34
|
-
end
|
35
|
-
|
36
|
-
def test_for_reversed
|
37
|
-
assigns = { 'array' => [1, 2, 3] }
|
38
|
-
assert_template_result('321', '{%for item in array reversed %}{{item}}{%endfor%}', assigns)
|
39
|
-
end
|
40
|
-
|
41
|
-
def test_for_with_range
|
42
|
-
assert_template_result(' 1 2 3 ', '{%for item in (1..3) %} {{item}} {%endfor%}')
|
43
|
-
|
44
|
-
assert_raises(Liquid::ArgumentError) do
|
45
|
-
Template.parse('{% for i in (a..2) %}{% endfor %}').render!("a" => [1, 2])
|
46
|
-
end
|
47
|
-
|
48
|
-
assert_template_result(' 0 1 2 3 ', '{% for item in (a..3) %} {{item}} {% endfor %}', "a" => "invalid integer")
|
49
|
-
end
|
50
|
-
|
51
|
-
def test_for_with_variable_range
|
52
|
-
assert_template_result(' 1 2 3 ', '{%for item in (1..foobar) %} {{item}} {%endfor%}', "foobar" => 3)
|
53
|
-
end
|
54
|
-
|
55
|
-
def test_for_with_hash_value_range
|
56
|
-
foobar = { "value" => 3 }
|
57
|
-
assert_template_result(' 1 2 3 ', '{%for item in (1..foobar.value) %} {{item}} {%endfor%}', "foobar" => foobar)
|
58
|
-
end
|
59
|
-
|
60
|
-
def test_for_with_drop_value_range
|
61
|
-
foobar = ThingWithValue.new
|
62
|
-
assert_template_result(' 1 2 3 ', '{%for item in (1..foobar.value) %} {{item}} {%endfor%}', "foobar" => foobar)
|
63
|
-
end
|
64
|
-
|
65
|
-
def test_for_with_variable
|
66
|
-
assert_template_result(' 1 2 3 ', '{%for item in array%} {{item}} {%endfor%}', 'array' => [1, 2, 3])
|
67
|
-
assert_template_result('123', '{%for item in array%}{{item}}{%endfor%}', 'array' => [1, 2, 3])
|
68
|
-
assert_template_result('123', '{% for item in array %}{{item}}{% endfor %}', 'array' => [1, 2, 3])
|
69
|
-
assert_template_result('abcd', '{%for item in array%}{{item}}{%endfor%}', 'array' => ['a', 'b', 'c', 'd'])
|
70
|
-
assert_template_result('a b c', '{%for item in array%}{{item}}{%endfor%}', 'array' => ['a', ' ', 'b', ' ', 'c'])
|
71
|
-
assert_template_result('abc', '{%for item in array%}{{item}}{%endfor%}', 'array' => ['a', '', 'b', '', 'c'])
|
72
|
-
end
|
73
|
-
|
74
|
-
def test_for_helpers
|
75
|
-
assigns = { 'array' => [1, 2, 3] }
|
76
|
-
assert_template_result(' 1/3 2/3 3/3 ',
|
77
|
-
'{%for item in array%} {{forloop.index}}/{{forloop.length}} {%endfor%}',
|
78
|
-
assigns)
|
79
|
-
assert_template_result(' 1 2 3 ', '{%for item in array%} {{forloop.index}} {%endfor%}', assigns)
|
80
|
-
assert_template_result(' 0 1 2 ', '{%for item in array%} {{forloop.index0}} {%endfor%}', assigns)
|
81
|
-
assert_template_result(' 2 1 0 ', '{%for item in array%} {{forloop.rindex0}} {%endfor%}', assigns)
|
82
|
-
assert_template_result(' 3 2 1 ', '{%for item in array%} {{forloop.rindex}} {%endfor%}', assigns)
|
83
|
-
assert_template_result(' true false false ', '{%for item in array%} {{forloop.first}} {%endfor%}', assigns)
|
84
|
-
assert_template_result(' false false true ', '{%for item in array%} {{forloop.last}} {%endfor%}', assigns)
|
85
|
-
end
|
86
|
-
|
87
|
-
def test_for_and_if
|
88
|
-
assigns = { 'array' => [1, 2, 3] }
|
89
|
-
assert_template_result('+--',
|
90
|
-
'{%for item in array%}{% if forloop.first %}+{% else %}-{% endif %}{%endfor%}',
|
91
|
-
assigns)
|
92
|
-
end
|
93
|
-
|
94
|
-
def test_for_else
|
95
|
-
assert_template_result('+++', '{%for item in array%}+{%else%}-{%endfor%}', 'array' => [1, 2, 3])
|
96
|
-
assert_template_result('-', '{%for item in array%}+{%else%}-{%endfor%}', 'array' => [])
|
97
|
-
assert_template_result('-', '{%for item in array%}+{%else%}-{%endfor%}', 'array' => nil)
|
98
|
-
end
|
99
|
-
|
100
|
-
def test_limiting
|
101
|
-
assigns = { 'array' => [1, 2, 3, 4, 5, 6, 7, 8, 9, 0] }
|
102
|
-
assert_template_result('12', '{%for i in array limit:2 %}{{ i }}{%endfor%}', assigns)
|
103
|
-
assert_template_result('1234', '{%for i in array limit:4 %}{{ i }}{%endfor%}', assigns)
|
104
|
-
assert_template_result('3456', '{%for i in array limit:4 offset:2 %}{{ i }}{%endfor%}', assigns)
|
105
|
-
assert_template_result('3456', '{%for i in array limit: 4 offset: 2 %}{{ i }}{%endfor%}', assigns)
|
106
|
-
end
|
107
|
-
|
108
|
-
def test_limiting_with_invalid_limit
|
109
|
-
assigns = { 'array' => [1, 2, 3, 4, 5, 6, 7, 8, 9, 0] }
|
110
|
-
template = <<-MKUP
|
111
|
-
{% for i in array limit: true offset: 1 %}
|
112
|
-
{{ i }}
|
113
|
-
{% endfor %}
|
114
|
-
MKUP
|
115
|
-
|
116
|
-
exception = assert_raises(Liquid::ArgumentError) do
|
117
|
-
Template.parse(template).render!(assigns)
|
118
|
-
end
|
119
|
-
assert_equal("Liquid error: invalid integer", exception.message)
|
120
|
-
end
|
121
|
-
|
122
|
-
def test_limiting_with_invalid_offset
|
123
|
-
assigns = { 'array' => [1, 2, 3, 4, 5, 6, 7, 8, 9, 0] }
|
124
|
-
template = <<-MKUP
|
125
|
-
{% for i in array limit: 1 offset: true %}
|
126
|
-
{{ i }}
|
127
|
-
{% endfor %}
|
128
|
-
MKUP
|
129
|
-
|
130
|
-
exception = assert_raises(Liquid::ArgumentError) do
|
131
|
-
Template.parse(template).render!(assigns)
|
132
|
-
end
|
133
|
-
assert_equal("Liquid error: invalid integer", exception.message)
|
134
|
-
end
|
135
|
-
|
136
|
-
def test_dynamic_variable_limiting
|
137
|
-
assigns = { 'array' => [1, 2, 3, 4, 5, 6, 7, 8, 9, 0] }
|
138
|
-
assigns['limit'] = 2
|
139
|
-
assigns['offset'] = 2
|
140
|
-
|
141
|
-
assert_template_result('34', '{%for i in array limit: limit offset: offset %}{{ i }}{%endfor%}', assigns)
|
142
|
-
end
|
143
|
-
|
144
|
-
def test_nested_for
|
145
|
-
assigns = { 'array' => [[1, 2], [3, 4], [5, 6]] }
|
146
|
-
assert_template_result('123456', '{%for item in array%}{%for i in item%}{{ i }}{%endfor%}{%endfor%}', assigns)
|
147
|
-
end
|
148
|
-
|
149
|
-
def test_offset_only
|
150
|
-
assigns = { 'array' => [1, 2, 3, 4, 5, 6, 7, 8, 9, 0] }
|
151
|
-
assert_template_result('890', '{%for i in array offset:7 %}{{ i }}{%endfor%}', assigns)
|
152
|
-
end
|
153
|
-
|
154
|
-
def test_pause_resume
|
155
|
-
assigns = { 'array' => { 'items' => [1, 2, 3, 4, 5, 6, 7, 8, 9, 0] } }
|
156
|
-
markup = <<-MKUP
|
157
|
-
{%for i in array.items limit: 3 %}{{i}}{%endfor%}
|
158
|
-
next
|
159
|
-
{%for i in array.items offset:continue limit: 3 %}{{i}}{%endfor%}
|
160
|
-
next
|
161
|
-
{%for i in array.items offset:continue limit: 3 %}{{i}}{%endfor%}
|
162
|
-
MKUP
|
163
|
-
expected = <<-XPCTD
|
164
|
-
123
|
165
|
-
next
|
166
|
-
456
|
167
|
-
next
|
168
|
-
789
|
169
|
-
XPCTD
|
170
|
-
assert_template_result(expected, markup, assigns)
|
171
|
-
end
|
172
|
-
|
173
|
-
def test_pause_resume_limit
|
174
|
-
assigns = { 'array' => { 'items' => [1, 2, 3, 4, 5, 6, 7, 8, 9, 0] } }
|
175
|
-
markup = <<-MKUP
|
176
|
-
{%for i in array.items limit:3 %}{{i}}{%endfor%}
|
177
|
-
next
|
178
|
-
{%for i in array.items offset:continue limit:3 %}{{i}}{%endfor%}
|
179
|
-
next
|
180
|
-
{%for i in array.items offset:continue limit:1 %}{{i}}{%endfor%}
|
181
|
-
MKUP
|
182
|
-
expected = <<-XPCTD
|
183
|
-
123
|
184
|
-
next
|
185
|
-
456
|
186
|
-
next
|
187
|
-
7
|
188
|
-
XPCTD
|
189
|
-
assert_template_result(expected, markup, assigns)
|
190
|
-
end
|
191
|
-
|
192
|
-
def test_pause_resume_big_limit
|
193
|
-
assigns = { 'array' => { 'items' => [1, 2, 3, 4, 5, 6, 7, 8, 9, 0] } }
|
194
|
-
markup = <<-MKUP
|
195
|
-
{%for i in array.items limit:3 %}{{i}}{%endfor%}
|
196
|
-
next
|
197
|
-
{%for i in array.items offset:continue limit:3 %}{{i}}{%endfor%}
|
198
|
-
next
|
199
|
-
{%for i in array.items offset:continue limit:1000 %}{{i}}{%endfor%}
|
200
|
-
MKUP
|
201
|
-
expected = <<-XPCTD
|
202
|
-
123
|
203
|
-
next
|
204
|
-
456
|
205
|
-
next
|
206
|
-
7890
|
207
|
-
XPCTD
|
208
|
-
assert_template_result(expected, markup, assigns)
|
209
|
-
end
|
210
|
-
|
211
|
-
def test_pause_resume_big_offset
|
212
|
-
assigns = { 'array' => { 'items' => [1, 2, 3, 4, 5, 6, 7, 8, 9, 0] } }
|
213
|
-
markup = '{%for i in array.items limit:3 %}{{i}}{%endfor%}
|
214
|
-
next
|
215
|
-
{%for i in array.items offset:continue limit:3 %}{{i}}{%endfor%}
|
216
|
-
next
|
217
|
-
{%for i in array.items offset:continue limit:3 offset:1000 %}{{i}}{%endfor%}'
|
218
|
-
expected = '123
|
219
|
-
next
|
220
|
-
456
|
221
|
-
next
|
222
|
-
'
|
223
|
-
assert_template_result(expected, markup, assigns)
|
224
|
-
end
|
225
|
-
|
226
|
-
def test_for_with_break
|
227
|
-
assigns = { 'array' => { 'items' => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] } }
|
228
|
-
|
229
|
-
markup = '{% for i in array.items %}{% break %}{% endfor %}'
|
230
|
-
expected = ""
|
231
|
-
assert_template_result(expected, markup, assigns)
|
232
|
-
|
233
|
-
markup = '{% for i in array.items %}{{ i }}{% break %}{% endfor %}'
|
234
|
-
expected = "1"
|
235
|
-
assert_template_result(expected, markup, assigns)
|
236
|
-
|
237
|
-
markup = '{% for i in array.items %}{% break %}{{ i }}{% endfor %}'
|
238
|
-
expected = ""
|
239
|
-
assert_template_result(expected, markup, assigns)
|
240
|
-
|
241
|
-
markup = '{% for i in array.items %}{{ i }}{% if i > 3 %}{% break %}{% endif %}{% endfor %}'
|
242
|
-
expected = "1234"
|
243
|
-
assert_template_result(expected, markup, assigns)
|
244
|
-
|
245
|
-
# tests to ensure it only breaks out of the local for loop
|
246
|
-
# and not all of them.
|
247
|
-
assigns = { 'array' => [[1, 2], [3, 4], [5, 6]] }
|
248
|
-
markup = '{% for item in array %}' \
|
249
|
-
'{% for i in item %}' \
|
250
|
-
'{% if i == 1 %}' \
|
251
|
-
'{% break %}' \
|
252
|
-
'{% endif %}' \
|
253
|
-
'{{ i }}' \
|
254
|
-
'{% endfor %}' \
|
255
|
-
'{% endfor %}'
|
256
|
-
expected = '3456'
|
257
|
-
assert_template_result(expected, markup, assigns)
|
258
|
-
|
259
|
-
# test break does nothing when unreached
|
260
|
-
assigns = { 'array' => { 'items' => [1, 2, 3, 4, 5] } }
|
261
|
-
markup = '{% for i in array.items %}{% if i == 9999 %}{% break %}{% endif %}{{ i }}{% endfor %}'
|
262
|
-
expected = '12345'
|
263
|
-
assert_template_result(expected, markup, assigns)
|
264
|
-
end
|
265
|
-
|
266
|
-
def test_for_with_continue
|
267
|
-
assigns = { 'array' => { 'items' => [1, 2, 3, 4, 5] } }
|
268
|
-
|
269
|
-
markup = '{% for i in array.items %}{% continue %}{% endfor %}'
|
270
|
-
expected = ""
|
271
|
-
assert_template_result(expected, markup, assigns)
|
272
|
-
|
273
|
-
markup = '{% for i in array.items %}{{ i }}{% continue %}{% endfor %}'
|
274
|
-
expected = "12345"
|
275
|
-
assert_template_result(expected, markup, assigns)
|
276
|
-
|
277
|
-
markup = '{% for i in array.items %}{% continue %}{{ i }}{% endfor %}'
|
278
|
-
expected = ""
|
279
|
-
assert_template_result(expected, markup, assigns)
|
280
|
-
|
281
|
-
markup = '{% for i in array.items %}{% if i > 3 %}{% continue %}{% endif %}{{ i }}{% endfor %}'
|
282
|
-
expected = "123"
|
283
|
-
assert_template_result(expected, markup, assigns)
|
284
|
-
|
285
|
-
markup = '{% for i in array.items %}{% if i == 3 %}{% continue %}{% else %}{{ i }}{% endif %}{% endfor %}'
|
286
|
-
expected = "1245"
|
287
|
-
assert_template_result(expected, markup, assigns)
|
288
|
-
|
289
|
-
# tests to ensure it only continues the local for loop and not all of them.
|
290
|
-
assigns = { 'array' => [[1, 2], [3, 4], [5, 6]] }
|
291
|
-
markup = '{% for item in array %}' \
|
292
|
-
'{% for i in item %}' \
|
293
|
-
'{% if i == 1 %}' \
|
294
|
-
'{% continue %}' \
|
295
|
-
'{% endif %}' \
|
296
|
-
'{{ i }}' \
|
297
|
-
'{% endfor %}' \
|
298
|
-
'{% endfor %}'
|
299
|
-
expected = '23456'
|
300
|
-
assert_template_result(expected, markup, assigns)
|
301
|
-
|
302
|
-
# test continue does nothing when unreached
|
303
|
-
assigns = { 'array' => { 'items' => [1, 2, 3, 4, 5] } }
|
304
|
-
markup = '{% for i in array.items %}{% if i == 9999 %}{% continue %}{% endif %}{{ i }}{% endfor %}'
|
305
|
-
expected = '12345'
|
306
|
-
assert_template_result(expected, markup, assigns)
|
307
|
-
end
|
308
|
-
|
309
|
-
def test_for_tag_string
|
310
|
-
# ruby 1.8.7 "String".each => Enumerator with single "String" element.
|
311
|
-
# ruby 1.9.3 no longer supports .each on String though we mimic
|
312
|
-
# the functionality for backwards compatibility
|
313
|
-
|
314
|
-
assert_template_result('test string',
|
315
|
-
'{%for val in string%}{{val}}{%endfor%}',
|
316
|
-
'string' => "test string")
|
317
|
-
|
318
|
-
assert_template_result('test string',
|
319
|
-
'{%for val in string limit:1%}{{val}}{%endfor%}',
|
320
|
-
'string' => "test string")
|
321
|
-
|
322
|
-
assert_template_result('val-string-1-1-0-1-0-true-true-test string',
|
323
|
-
'{%for val in string%}' \
|
324
|
-
'{{forloop.name}}-' \
|
325
|
-
'{{forloop.index}}-' \
|
326
|
-
'{{forloop.length}}-' \
|
327
|
-
'{{forloop.index0}}-' \
|
328
|
-
'{{forloop.rindex}}-' \
|
329
|
-
'{{forloop.rindex0}}-' \
|
330
|
-
'{{forloop.first}}-' \
|
331
|
-
'{{forloop.last}}-' \
|
332
|
-
'{{val}}{%endfor%}',
|
333
|
-
'string' => "test string")
|
334
|
-
end
|
335
|
-
|
336
|
-
def test_for_parentloop_references_parent_loop
|
337
|
-
assert_template_result('1.1 1.2 1.3 2.1 2.2 2.3 ',
|
338
|
-
'{% for inner in outer %}{% for k in inner %}' \
|
339
|
-
'{{ forloop.parentloop.index }}.{{ forloop.index }} ' \
|
340
|
-
'{% endfor %}{% endfor %}',
|
341
|
-
'outer' => [[1, 1, 1], [1, 1, 1]])
|
342
|
-
end
|
343
|
-
|
344
|
-
def test_for_parentloop_nil_when_not_present
|
345
|
-
assert_template_result('.1 .2 ',
|
346
|
-
'{% for inner in outer %}' \
|
347
|
-
'{{ forloop.parentloop.index }}.{{ forloop.index }} ' \
|
348
|
-
'{% endfor %}',
|
349
|
-
'outer' => [[1, 1, 1], [1, 1, 1]])
|
350
|
-
end
|
351
|
-
|
352
|
-
def test_inner_for_over_empty_input
|
353
|
-
assert_template_result('oo', '{% for a in (1..2) %}o{% for b in empty %}{% endfor %}{% endfor %}')
|
354
|
-
end
|
355
|
-
|
356
|
-
def test_blank_string_not_iterable
|
357
|
-
assert_template_result('', "{% for char in characters %}I WILL NOT BE OUTPUT{% endfor %}", 'characters' => '')
|
358
|
-
end
|
359
|
-
|
360
|
-
def test_bad_variable_naming_in_for_loop
|
361
|
-
assert_raises(Liquid::SyntaxError) do
|
362
|
-
Liquid::Template.parse('{% for a/b in x %}{% endfor %}')
|
363
|
-
end
|
364
|
-
end
|
365
|
-
|
366
|
-
def test_spacing_with_variable_naming_in_for_loop
|
367
|
-
expected = '12345'
|
368
|
-
template = '{% for item in items %}{{item}}{% endfor %}'
|
369
|
-
assigns = { 'items' => [1, 2, 3, 4, 5] }
|
370
|
-
assert_template_result(expected, template, assigns)
|
371
|
-
end
|
372
|
-
|
373
|
-
class LoaderDrop < Liquid::Drop
|
374
|
-
attr_accessor :each_called, :load_slice_called
|
375
|
-
|
376
|
-
def initialize(data)
|
377
|
-
@data = data
|
378
|
-
end
|
379
|
-
|
380
|
-
def each
|
381
|
-
@each_called = true
|
382
|
-
@data.each { |el| yield el }
|
383
|
-
end
|
384
|
-
|
385
|
-
def load_slice(from, to)
|
386
|
-
@load_slice_called = true
|
387
|
-
@data[(from..to - 1)]
|
388
|
-
end
|
389
|
-
end
|
390
|
-
|
391
|
-
def test_iterate_with_each_when_no_limit_applied
|
392
|
-
loader = LoaderDrop.new([1, 2, 3, 4, 5])
|
393
|
-
assigns = { 'items' => loader }
|
394
|
-
expected = '12345'
|
395
|
-
template = '{% for item in items %}{{item}}{% endfor %}'
|
396
|
-
assert_template_result(expected, template, assigns)
|
397
|
-
assert(loader.each_called)
|
398
|
-
assert(!loader.load_slice_called)
|
399
|
-
end
|
400
|
-
|
401
|
-
def test_iterate_with_load_slice_when_limit_applied
|
402
|
-
loader = LoaderDrop.new([1, 2, 3, 4, 5])
|
403
|
-
assigns = { 'items' => loader }
|
404
|
-
expected = '1'
|
405
|
-
template = '{% for item in items limit:1 %}{{item}}{% endfor %}'
|
406
|
-
assert_template_result(expected, template, assigns)
|
407
|
-
assert(!loader.each_called)
|
408
|
-
assert(loader.load_slice_called)
|
409
|
-
end
|
410
|
-
|
411
|
-
def test_iterate_with_load_slice_when_limit_and_offset_applied
|
412
|
-
loader = LoaderDrop.new([1, 2, 3, 4, 5])
|
413
|
-
assigns = { 'items' => loader }
|
414
|
-
expected = '34'
|
415
|
-
template = '{% for item in items offset:2 limit:2 %}{{item}}{% endfor %}'
|
416
|
-
assert_template_result(expected, template, assigns)
|
417
|
-
assert(!loader.each_called)
|
418
|
-
assert(loader.load_slice_called)
|
419
|
-
end
|
420
|
-
|
421
|
-
def test_iterate_with_load_slice_returns_same_results_as_without
|
422
|
-
loader = LoaderDrop.new([1, 2, 3, 4, 5])
|
423
|
-
loader_assigns = { 'items' => loader }
|
424
|
-
array_assigns = { 'items' => [1, 2, 3, 4, 5] }
|
425
|
-
expected = '34'
|
426
|
-
template = '{% for item in items offset:2 limit:2 %}{{item}}{% endfor %}'
|
427
|
-
assert_template_result(expected, template, loader_assigns)
|
428
|
-
assert_template_result(expected, template, array_assigns)
|
429
|
-
end
|
430
|
-
|
431
|
-
def test_for_cleans_up_registers
|
432
|
-
context = Context.new(ErrorDrop.new)
|
433
|
-
|
434
|
-
assert_raises(StandardError) do
|
435
|
-
Liquid::Template.parse('{% for i in (1..2) %}{{ standard_error }}{% endfor %}').render!(context)
|
436
|
-
end
|
437
|
-
|
438
|
-
assert(context.registers[:for_stack].empty?)
|
439
|
-
end
|
440
|
-
|
441
|
-
def test_instrument_for_offset_continue
|
442
|
-
assert_usage_increment('for_offset_continue') do
|
443
|
-
Template.parse('{% for item in items offset:continue %}{{item}}{% endfor %}')
|
444
|
-
end
|
445
|
-
|
446
|
-
assert_usage_increment('for_offset_continue', times: 0) do
|
447
|
-
Template.parse('{% for item in items offset:2 %}{{item}}{% endfor %}')
|
448
|
-
end
|
449
|
-
end
|
450
|
-
|
451
|
-
def test_instrument_forloop_drop_name
|
452
|
-
assigns = { 'items' => [1, 2, 3, 4, 5] }
|
453
|
-
|
454
|
-
assert_usage_increment('forloop_drop_name', times: 5) do
|
455
|
-
Template.parse('{% for item in items %}{{forloop.name}}{% endfor %}').render!(assigns)
|
456
|
-
end
|
457
|
-
|
458
|
-
assert_usage_increment('forloop_drop_name', times: 0) do
|
459
|
-
Template.parse('{% for item in items %}{{forloop.index}}{% endfor %}').render!(assigns)
|
460
|
-
end
|
461
|
-
|
462
|
-
assert_usage_increment('forloop_drop_name', times: 0) do
|
463
|
-
Template.parse('{% for item in items %}{{item}}{% endfor %}').render!(assigns)
|
464
|
-
end
|
465
|
-
end
|
466
|
-
end
|