liquid 5.3.0 → 5.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (96) hide show
  1. checksums.yaml +4 -4
  2. data/History.md +16 -1
  3. data/README.md +2 -2
  4. data/lib/liquid/block_body.rb +4 -4
  5. data/lib/liquid/context.rb +6 -2
  6. data/lib/liquid/forloop_drop.rb +44 -1
  7. data/lib/liquid/locales/en.yml +6 -5
  8. data/lib/liquid/partial_cache.rb +3 -3
  9. data/lib/liquid/{static_registers.rb → registers.rb} +13 -10
  10. data/lib/liquid/standardfilters.rb +406 -57
  11. data/lib/liquid/strainer_factory.rb +4 -0
  12. data/lib/liquid/strainer_template.rb +4 -0
  13. data/lib/liquid/tablerowloop_drop.rb +58 -1
  14. data/lib/liquid/tags/assign.rb +12 -8
  15. data/lib/liquid/tags/break.rb +8 -0
  16. data/lib/liquid/tags/capture.rb +13 -10
  17. data/lib/liquid/tags/case.rb +21 -0
  18. data/lib/liquid/tags/comment.rb +13 -0
  19. data/lib/liquid/tags/continue.rb +8 -9
  20. data/lib/liquid/tags/cycle.rb +12 -11
  21. data/lib/liquid/tags/decrement.rb +16 -17
  22. data/lib/liquid/tags/echo.rb +16 -9
  23. data/lib/liquid/tags/for.rb +22 -43
  24. data/lib/liquid/tags/if.rb +11 -9
  25. data/lib/liquid/tags/include.rb +15 -13
  26. data/lib/liquid/tags/increment.rb +16 -14
  27. data/lib/liquid/tags/inline_comment.rb +43 -0
  28. data/lib/liquid/tags/raw.rb +11 -0
  29. data/lib/liquid/tags/render.rb +29 -4
  30. data/lib/liquid/tags/table_row.rb +22 -0
  31. data/lib/liquid/tags/unless.rb +15 -4
  32. data/lib/liquid/template.rb +2 -3
  33. data/lib/liquid/variable.rb +4 -4
  34. data/lib/liquid/variable_lookup.rb +10 -7
  35. data/lib/liquid/version.rb +1 -1
  36. data/lib/liquid.rb +2 -2
  37. metadata +7 -123
  38. data/lib/liquid/register.rb +0 -6
  39. data/test/fixtures/en_locale.yml +0 -9
  40. data/test/integration/assign_test.rb +0 -117
  41. data/test/integration/blank_test.rb +0 -109
  42. data/test/integration/block_test.rb +0 -58
  43. data/test/integration/capture_test.rb +0 -58
  44. data/test/integration/context_test.rb +0 -634
  45. data/test/integration/document_test.rb +0 -21
  46. data/test/integration/drop_test.rb +0 -257
  47. data/test/integration/error_handling_test.rb +0 -272
  48. data/test/integration/expression_test.rb +0 -46
  49. data/test/integration/filter_kwarg_test.rb +0 -24
  50. data/test/integration/filter_test.rb +0 -189
  51. data/test/integration/hash_ordering_test.rb +0 -25
  52. data/test/integration/output_test.rb +0 -125
  53. data/test/integration/parsing_quirks_test.rb +0 -134
  54. data/test/integration/profiler_test.rb +0 -240
  55. data/test/integration/security_test.rb +0 -89
  56. data/test/integration/standard_filter_test.rb +0 -925
  57. data/test/integration/tag/disableable_test.rb +0 -59
  58. data/test/integration/tag_test.rb +0 -45
  59. data/test/integration/tags/break_tag_test.rb +0 -17
  60. data/test/integration/tags/continue_tag_test.rb +0 -17
  61. data/test/integration/tags/echo_test.rb +0 -13
  62. data/test/integration/tags/for_tag_test.rb +0 -466
  63. data/test/integration/tags/if_else_tag_test.rb +0 -190
  64. data/test/integration/tags/include_tag_test.rb +0 -269
  65. data/test/integration/tags/increment_tag_test.rb +0 -25
  66. data/test/integration/tags/liquid_tag_test.rb +0 -116
  67. data/test/integration/tags/raw_tag_test.rb +0 -34
  68. data/test/integration/tags/render_tag_test.rb +0 -213
  69. data/test/integration/tags/standard_tag_test.rb +0 -303
  70. data/test/integration/tags/statements_test.rb +0 -113
  71. data/test/integration/tags/table_row_test.rb +0 -66
  72. data/test/integration/tags/unless_else_tag_test.rb +0 -28
  73. data/test/integration/template_test.rb +0 -340
  74. data/test/integration/trim_mode_test.rb +0 -563
  75. data/test/integration/variable_test.rb +0 -138
  76. data/test/test_helper.rb +0 -207
  77. data/test/unit/block_unit_test.rb +0 -53
  78. data/test/unit/condition_unit_test.rb +0 -181
  79. data/test/unit/file_system_unit_test.rb +0 -37
  80. data/test/unit/i18n_unit_test.rb +0 -39
  81. data/test/unit/lexer_unit_test.rb +0 -53
  82. data/test/unit/parse_tree_visitor_test.rb +0 -261
  83. data/test/unit/parser_unit_test.rb +0 -84
  84. data/test/unit/partial_cache_unit_test.rb +0 -128
  85. data/test/unit/regexp_unit_test.rb +0 -46
  86. data/test/unit/static_registers_unit_test.rb +0 -156
  87. data/test/unit/strainer_factory_unit_test.rb +0 -101
  88. data/test/unit/strainer_template_unit_test.rb +0 -82
  89. data/test/unit/tag_unit_test.rb +0 -23
  90. data/test/unit/tags/case_tag_unit_test.rb +0 -12
  91. data/test/unit/tags/for_tag_unit_test.rb +0 -15
  92. data/test/unit/tags/if_tag_unit_test.rb +0 -10
  93. data/test/unit/template_factory_unit_test.rb +0 -12
  94. data/test/unit/template_unit_test.rb +0 -87
  95. data/test/unit/tokenizer_unit_test.rb +0 -62
  96. 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