liquid 3.0.6 → 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.
Files changed (113) hide show
  1. checksums.yaml +5 -5
  2. data/History.md +243 -58
  3. data/README.md +43 -4
  4. data/lib/liquid/block.rb +57 -123
  5. data/lib/liquid/block_body.rb +217 -85
  6. data/lib/liquid/condition.rb +92 -45
  7. data/lib/liquid/context.rb +154 -89
  8. data/lib/liquid/document.rb +57 -9
  9. data/lib/liquid/drop.rb +20 -17
  10. data/lib/liquid/errors.rb +27 -29
  11. data/lib/liquid/expression.rb +32 -20
  12. data/lib/liquid/extensions.rb +21 -7
  13. data/lib/liquid/file_system.rb +17 -15
  14. data/lib/liquid/forloop_drop.rb +92 -0
  15. data/lib/liquid/i18n.rb +10 -8
  16. data/lib/liquid/interrupts.rb +4 -3
  17. data/lib/liquid/lexer.rb +37 -26
  18. data/lib/liquid/locales/en.yml +13 -6
  19. data/lib/liquid/parse_context.rb +54 -0
  20. data/lib/liquid/parse_tree_visitor.rb +42 -0
  21. data/lib/liquid/parser.rb +30 -18
  22. data/lib/liquid/parser_switching.rb +20 -6
  23. data/lib/liquid/partial_cache.rb +24 -0
  24. data/lib/liquid/profiler/hooks.rb +26 -14
  25. data/lib/liquid/profiler.rb +72 -92
  26. data/lib/liquid/range_lookup.rb +28 -3
  27. data/lib/liquid/registers.rb +51 -0
  28. data/lib/liquid/resource_limits.rb +62 -0
  29. data/lib/liquid/standardfilters.rb +715 -132
  30. data/lib/liquid/strainer_factory.rb +41 -0
  31. data/lib/liquid/strainer_template.rb +62 -0
  32. data/lib/liquid/tablerowloop_drop.rb +121 -0
  33. data/lib/liquid/tag/disableable.rb +22 -0
  34. data/lib/liquid/tag/disabler.rb +21 -0
  35. data/lib/liquid/tag.rb +35 -12
  36. data/lib/liquid/tags/assign.rb +57 -18
  37. data/lib/liquid/tags/break.rb +15 -5
  38. data/lib/liquid/tags/capture.rb +24 -18
  39. data/lib/liquid/tags/case.rb +79 -30
  40. data/lib/liquid/tags/comment.rb +19 -4
  41. data/lib/liquid/tags/continue.rb +16 -12
  42. data/lib/liquid/tags/cycle.rb +47 -27
  43. data/lib/liquid/tags/decrement.rb +23 -24
  44. data/lib/liquid/tags/echo.rb +41 -0
  45. data/lib/liquid/tags/for.rb +155 -124
  46. data/lib/liquid/tags/if.rb +97 -63
  47. data/lib/liquid/tags/ifchanged.rb +11 -12
  48. data/lib/liquid/tags/include.rb +82 -73
  49. data/lib/liquid/tags/increment.rb +23 -17
  50. data/lib/liquid/tags/inline_comment.rb +43 -0
  51. data/lib/liquid/tags/raw.rb +50 -8
  52. data/lib/liquid/tags/render.rb +109 -0
  53. data/lib/liquid/tags/table_row.rb +57 -41
  54. data/lib/liquid/tags/unless.rb +38 -20
  55. data/lib/liquid/template.rb +71 -103
  56. data/lib/liquid/template_factory.rb +9 -0
  57. data/lib/liquid/tokenizer.rb +39 -0
  58. data/lib/liquid/usage.rb +8 -0
  59. data/lib/liquid/utils.rb +63 -9
  60. data/lib/liquid/variable.rb +74 -56
  61. data/lib/liquid/variable_lookup.rb +31 -15
  62. data/lib/liquid/version.rb +3 -1
  63. data/lib/liquid.rb +27 -12
  64. metadata +30 -106
  65. data/lib/liquid/module_ex.rb +0 -62
  66. data/lib/liquid/strainer.rb +0 -59
  67. data/lib/liquid/token.rb +0 -18
  68. data/test/fixtures/en_locale.yml +0 -9
  69. data/test/integration/assign_test.rb +0 -48
  70. data/test/integration/blank_test.rb +0 -106
  71. data/test/integration/capture_test.rb +0 -50
  72. data/test/integration/context_test.rb +0 -32
  73. data/test/integration/drop_test.rb +0 -271
  74. data/test/integration/error_handling_test.rb +0 -207
  75. data/test/integration/filter_test.rb +0 -138
  76. data/test/integration/hash_ordering_test.rb +0 -23
  77. data/test/integration/output_test.rb +0 -124
  78. data/test/integration/parsing_quirks_test.rb +0 -116
  79. data/test/integration/render_profiling_test.rb +0 -154
  80. data/test/integration/security_test.rb +0 -64
  81. data/test/integration/standard_filter_test.rb +0 -396
  82. data/test/integration/tags/break_tag_test.rb +0 -16
  83. data/test/integration/tags/continue_tag_test.rb +0 -16
  84. data/test/integration/tags/for_tag_test.rb +0 -375
  85. data/test/integration/tags/if_else_tag_test.rb +0 -190
  86. data/test/integration/tags/include_tag_test.rb +0 -234
  87. data/test/integration/tags/increment_tag_test.rb +0 -24
  88. data/test/integration/tags/raw_tag_test.rb +0 -25
  89. data/test/integration/tags/standard_tag_test.rb +0 -297
  90. data/test/integration/tags/statements_test.rb +0 -113
  91. data/test/integration/tags/table_row_test.rb +0 -63
  92. data/test/integration/tags/unless_else_tag_test.rb +0 -26
  93. data/test/integration/template_test.rb +0 -182
  94. data/test/integration/variable_test.rb +0 -82
  95. data/test/test_helper.rb +0 -89
  96. data/test/unit/block_unit_test.rb +0 -55
  97. data/test/unit/condition_unit_test.rb +0 -149
  98. data/test/unit/context_unit_test.rb +0 -492
  99. data/test/unit/file_system_unit_test.rb +0 -35
  100. data/test/unit/i18n_unit_test.rb +0 -37
  101. data/test/unit/lexer_unit_test.rb +0 -48
  102. data/test/unit/module_ex_unit_test.rb +0 -87
  103. data/test/unit/parser_unit_test.rb +0 -82
  104. data/test/unit/regexp_unit_test.rb +0 -44
  105. data/test/unit/strainer_unit_test.rb +0 -69
  106. data/test/unit/tag_unit_test.rb +0 -16
  107. data/test/unit/tags/case_tag_unit_test.rb +0 -10
  108. data/test/unit/tags/for_tag_unit_test.rb +0 -13
  109. data/test/unit/tags/if_tag_unit_test.rb +0 -8
  110. data/test/unit/template_unit_test.rb +0 -69
  111. data/test/unit/tokenizer_unit_test.rb +0 -38
  112. data/test/unit/variable_unit_test.rb +0 -145
  113. /data/{MIT-LICENSE → LICENSE} +0 -0
@@ -1,375 +0,0 @@
1
- require 'test_helper'
2
-
3
- class ThingWithValue < Liquid::Drop
4
- def value
5
- 3
6
- end
7
- end
8
-
9
- class ForTagTest < Minitest::Test
10
- include Liquid
11
-
12
- def test_for
13
- assert_template_result(' yo yo yo yo ','{%for item in array%} yo {%endfor%}','array' => [1,2,3,4])
14
- assert_template_result('yoyo','{%for item in array%}yo{%endfor%}','array' => [1,2])
15
- assert_template_result(' yo ','{%for item in array%} yo {%endfor%}','array' => [1])
16
- assert_template_result('','{%for item in array%}{%endfor%}','array' => [1,2])
17
- expected = <<HERE
18
-
19
- yo
20
-
21
- yo
22
-
23
- yo
24
-
25
- HERE
26
- template = <<HERE
27
- {%for item in array%}
28
- yo
29
- {%endfor%}
30
- HERE
31
- assert_template_result(expected,template,'array' => [1,2,3])
32
- end
33
-
34
- def test_for_reversed
35
- assigns = {'array' => [ 1, 2, 3] }
36
- assert_template_result('321','{%for item in array reversed %}{{item}}{%endfor%}',assigns)
37
- end
38
-
39
- def test_for_with_range
40
- assert_template_result(' 1 2 3 ','{%for item in (1..3) %} {{item}} {%endfor%}')
41
- end
42
-
43
- def test_for_with_variable_range
44
- assert_template_result(' 1 2 3 ','{%for item in (1..foobar) %} {{item}} {%endfor%}', "foobar" => 3)
45
- end
46
-
47
- def test_for_with_hash_value_range
48
- foobar = { "value" => 3 }
49
- assert_template_result(' 1 2 3 ','{%for item in (1..foobar.value) %} {{item}} {%endfor%}', "foobar" => foobar)
50
- end
51
-
52
- def test_for_with_drop_value_range
53
- foobar = ThingWithValue.new
54
- assert_template_result(' 1 2 3 ','{%for item in (1..foobar.value) %} {{item}} {%endfor%}', "foobar" => foobar)
55
- end
56
-
57
- def test_for_with_variable
58
- assert_template_result(' 1 2 3 ','{%for item in array%} {{item}} {%endfor%}','array' => [1,2,3])
59
- assert_template_result('123','{%for item in array%}{{item}}{%endfor%}','array' => [1,2,3])
60
- assert_template_result('123','{% for item in array %}{{item}}{% endfor %}','array' => [1,2,3])
61
- assert_template_result('abcd','{%for item in array%}{{item}}{%endfor%}','array' => ['a','b','c','d'])
62
- assert_template_result('a b c','{%for item in array%}{{item}}{%endfor%}','array' => ['a',' ','b',' ','c'])
63
- assert_template_result('abc','{%for item in array%}{{item}}{%endfor%}','array' => ['a','','b','','c'])
64
- end
65
-
66
- def test_for_helpers
67
- assigns = {'array' => [1,2,3] }
68
- assert_template_result(' 1/3 2/3 3/3 ',
69
- '{%for item in array%} {{forloop.index}}/{{forloop.length}} {%endfor%}',
70
- assigns)
71
- assert_template_result(' 1 2 3 ', '{%for item in array%} {{forloop.index}} {%endfor%}', assigns)
72
- assert_template_result(' 0 1 2 ', '{%for item in array%} {{forloop.index0}} {%endfor%}', assigns)
73
- assert_template_result(' 2 1 0 ', '{%for item in array%} {{forloop.rindex0}} {%endfor%}', assigns)
74
- assert_template_result(' 3 2 1 ', '{%for item in array%} {{forloop.rindex}} {%endfor%}', assigns)
75
- assert_template_result(' true false false ', '{%for item in array%} {{forloop.first}} {%endfor%}', assigns)
76
- assert_template_result(' false false true ', '{%for item in array%} {{forloop.last}} {%endfor%}', assigns)
77
- end
78
-
79
- def test_for_and_if
80
- assigns = {'array' => [1,2,3] }
81
- assert_template_result('+--',
82
- '{%for item in array%}{% if forloop.first %}+{% else %}-{% endif %}{%endfor%}',
83
- assigns)
84
- end
85
-
86
- def test_for_else
87
- assert_template_result('+++', '{%for item in array%}+{%else%}-{%endfor%}', 'array'=>[1,2,3])
88
- assert_template_result('-', '{%for item in array%}+{%else%}-{%endfor%}', 'array'=>[])
89
- assert_template_result('-', '{%for item in array%}+{%else%}-{%endfor%}', 'array'=>nil)
90
- end
91
-
92
- def test_limiting
93
- assigns = {'array' => [1,2,3,4,5,6,7,8,9,0]}
94
- assert_template_result('12', '{%for i in array limit:2 %}{{ i }}{%endfor%}', assigns)
95
- assert_template_result('1234', '{%for i in array limit:4 %}{{ i }}{%endfor%}', assigns)
96
- assert_template_result('3456', '{%for i in array limit:4 offset:2 %}{{ i }}{%endfor%}', assigns)
97
- assert_template_result('3456', '{%for i in array limit: 4 offset: 2 %}{{ i }}{%endfor%}', assigns)
98
- end
99
-
100
- def test_dynamic_variable_limiting
101
- assigns = {'array' => [1,2,3,4,5,6,7,8,9,0]}
102
- assigns['limit'] = 2
103
- assigns['offset'] = 2
104
-
105
- assert_template_result('34', '{%for i in array limit: limit offset: offset %}{{ i }}{%endfor%}', assigns)
106
- end
107
-
108
- def test_nested_for
109
- assigns = {'array' => [[1,2],[3,4],[5,6]] }
110
- assert_template_result('123456', '{%for item in array%}{%for i in item%}{{ i }}{%endfor%}{%endfor%}', assigns)
111
- end
112
-
113
- def test_offset_only
114
- assigns = {'array' => [1,2,3,4,5,6,7,8,9,0]}
115
- assert_template_result('890', '{%for i in array offset:7 %}{{ i }}{%endfor%}', assigns)
116
- end
117
-
118
- def test_pause_resume
119
- assigns = {'array' => {'items' => [1,2,3,4,5,6,7,8,9,0]}}
120
- markup = <<-MKUP
121
- {%for i in array.items limit: 3 %}{{i}}{%endfor%}
122
- next
123
- {%for i in array.items offset:continue limit: 3 %}{{i}}{%endfor%}
124
- next
125
- {%for i in array.items offset:continue limit: 3 %}{{i}}{%endfor%}
126
- MKUP
127
- expected = <<-XPCTD
128
- 123
129
- next
130
- 456
131
- next
132
- 789
133
- XPCTD
134
- assert_template_result(expected,markup,assigns)
135
- end
136
-
137
- def test_pause_resume_limit
138
- assigns = {'array' => {'items' => [1,2,3,4,5,6,7,8,9,0]}}
139
- markup = <<-MKUP
140
- {%for i in array.items limit:3 %}{{i}}{%endfor%}
141
- next
142
- {%for i in array.items offset:continue limit:3 %}{{i}}{%endfor%}
143
- next
144
- {%for i in array.items offset:continue limit:1 %}{{i}}{%endfor%}
145
- MKUP
146
- expected = <<-XPCTD
147
- 123
148
- next
149
- 456
150
- next
151
- 7
152
- XPCTD
153
- assert_template_result(expected,markup,assigns)
154
- end
155
-
156
- def test_pause_resume_BIG_limit
157
- assigns = {'array' => {'items' => [1,2,3,4,5,6,7,8,9,0]}}
158
- markup = <<-MKUP
159
- {%for i in array.items limit:3 %}{{i}}{%endfor%}
160
- next
161
- {%for i in array.items offset:continue limit:3 %}{{i}}{%endfor%}
162
- next
163
- {%for i in array.items offset:continue limit:1000 %}{{i}}{%endfor%}
164
- MKUP
165
- expected = <<-XPCTD
166
- 123
167
- next
168
- 456
169
- next
170
- 7890
171
- XPCTD
172
- assert_template_result(expected,markup,assigns)
173
- end
174
-
175
-
176
- def test_pause_resume_BIG_offset
177
- assigns = {'array' => {'items' => [1,2,3,4,5,6,7,8,9,0]}}
178
- markup = %q({%for i in array.items limit:3 %}{{i}}{%endfor%}
179
- next
180
- {%for i in array.items offset:continue limit:3 %}{{i}}{%endfor%}
181
- next
182
- {%for i in array.items offset:continue limit:3 offset:1000 %}{{i}}{%endfor%})
183
- expected = %q(123
184
- next
185
- 456
186
- next
187
- )
188
- assert_template_result(expected,markup,assigns)
189
- end
190
-
191
- def test_for_with_break
192
- assigns = {'array' => {'items' => [1,2,3,4,5,6,7,8,9,10]}}
193
-
194
- markup = '{% for i in array.items %}{% break %}{% endfor %}'
195
- expected = ""
196
- assert_template_result(expected,markup,assigns)
197
-
198
- markup = '{% for i in array.items %}{{ i }}{% break %}{% endfor %}'
199
- expected = "1"
200
- assert_template_result(expected,markup,assigns)
201
-
202
- markup = '{% for i in array.items %}{% break %}{{ i }}{% endfor %}'
203
- expected = ""
204
- assert_template_result(expected,markup,assigns)
205
-
206
- markup = '{% for i in array.items %}{{ i }}{% if i > 3 %}{% break %}{% endif %}{% endfor %}'
207
- expected = "1234"
208
- assert_template_result(expected,markup,assigns)
209
-
210
- # tests to ensure it only breaks out of the local for loop
211
- # and not all of them.
212
- assigns = {'array' => [[1,2],[3,4],[5,6]] }
213
- markup = '{% for item in array %}' +
214
- '{% for i in item %}' +
215
- '{% if i == 1 %}' +
216
- '{% break %}' +
217
- '{% endif %}' +
218
- '{{ i }}' +
219
- '{% endfor %}' +
220
- '{% endfor %}'
221
- expected = '3456'
222
- assert_template_result(expected, markup, assigns)
223
-
224
- # test break does nothing when unreached
225
- assigns = {'array' => {'items' => [1,2,3,4,5]}}
226
- markup = '{% for i in array.items %}{% if i == 9999 %}{% break %}{% endif %}{{ i }}{% endfor %}'
227
- expected = '12345'
228
- assert_template_result(expected, markup, assigns)
229
- end
230
-
231
- def test_for_with_continue
232
- assigns = {'array' => {'items' => [1,2,3,4,5]}}
233
-
234
- markup = '{% for i in array.items %}{% continue %}{% endfor %}'
235
- expected = ""
236
- assert_template_result(expected,markup,assigns)
237
-
238
- markup = '{% for i in array.items %}{{ i }}{% continue %}{% endfor %}'
239
- expected = "12345"
240
- assert_template_result(expected,markup,assigns)
241
-
242
- markup = '{% for i in array.items %}{% continue %}{{ i }}{% endfor %}'
243
- expected = ""
244
- assert_template_result(expected,markup,assigns)
245
-
246
- markup = '{% for i in array.items %}{% if i > 3 %}{% continue %}{% endif %}{{ i }}{% endfor %}'
247
- expected = "123"
248
- assert_template_result(expected,markup,assigns)
249
-
250
- markup = '{% for i in array.items %}{% if i == 3 %}{% continue %}{% else %}{{ i }}{% endif %}{% endfor %}'
251
- expected = "1245"
252
- assert_template_result(expected,markup,assigns)
253
-
254
- # tests to ensure it only continues the local for loop and not all of them.
255
- assigns = {'array' => [[1,2],[3,4],[5,6]] }
256
- markup = '{% for item in array %}' +
257
- '{% for i in item %}' +
258
- '{% if i == 1 %}' +
259
- '{% continue %}' +
260
- '{% endif %}' +
261
- '{{ i }}' +
262
- '{% endfor %}' +
263
- '{% endfor %}'
264
- expected = '23456'
265
- assert_template_result(expected, markup, assigns)
266
-
267
- # test continue does nothing when unreached
268
- assigns = {'array' => {'items' => [1,2,3,4,5]}}
269
- markup = '{% for i in array.items %}{% if i == 9999 %}{% continue %}{% endif %}{{ i }}{% endfor %}'
270
- expected = '12345'
271
- assert_template_result(expected, markup, assigns)
272
- end
273
-
274
- def test_for_tag_string
275
- # ruby 1.8.7 "String".each => Enumerator with single "String" element.
276
- # ruby 1.9.3 no longer supports .each on String though we mimic
277
- # the functionality for backwards compatibility
278
-
279
- assert_template_result('test string',
280
- '{%for val in string%}{{val}}{%endfor%}',
281
- 'string' => "test string")
282
-
283
- assert_template_result('test string',
284
- '{%for val in string limit:1%}{{val}}{%endfor%}',
285
- 'string' => "test string")
286
-
287
- assert_template_result('val-string-1-1-0-1-0-true-true-test string',
288
- '{%for val in string%}' +
289
- '{{forloop.name}}-' +
290
- '{{forloop.index}}-' +
291
- '{{forloop.length}}-' +
292
- '{{forloop.index0}}-' +
293
- '{{forloop.rindex}}-' +
294
- '{{forloop.rindex0}}-' +
295
- '{{forloop.first}}-' +
296
- '{{forloop.last}}-' +
297
- '{{val}}{%endfor%}',
298
- 'string' => "test string")
299
- end
300
-
301
- def test_blank_string_not_iterable
302
- assert_template_result('', "{% for char in characters %}I WILL NOT BE OUTPUT{% endfor %}", 'characters' => '')
303
- end
304
-
305
- def test_bad_variable_naming_in_for_loop
306
- assert_raises(Liquid::SyntaxError) do
307
- Liquid::Template.parse('{% for a/b in x %}{% endfor %}')
308
- end
309
- end
310
-
311
- def test_spacing_with_variable_naming_in_for_loop
312
- expected = '12345'
313
- template = '{% for item in items %}{{item}}{% endfor %}'
314
- assigns = {'items' => [1,2,3,4,5]}
315
- assert_template_result(expected, template, assigns)
316
- end
317
-
318
- class LoaderDrop < Liquid::Drop
319
- attr_accessor :each_called, :load_slice_called
320
-
321
- def initialize(data)
322
- @data = data
323
- end
324
-
325
- def each
326
- @each_called = true
327
- @data.each { |el| yield el }
328
- end
329
-
330
- def load_slice(from, to)
331
- @load_slice_called = true
332
- @data[(from..to-1)]
333
- end
334
- end
335
-
336
- def test_iterate_with_each_when_no_limit_applied
337
- loader = LoaderDrop.new([1,2,3,4,5])
338
- assigns = {'items' => loader}
339
- expected = '12345'
340
- template = '{% for item in items %}{{item}}{% endfor %}'
341
- assert_template_result(expected, template, assigns)
342
- assert loader.each_called
343
- assert !loader.load_slice_called
344
- end
345
-
346
- def test_iterate_with_load_slice_when_limit_applied
347
- loader = LoaderDrop.new([1,2,3,4,5])
348
- assigns = {'items' => loader}
349
- expected = '1'
350
- template = '{% for item in items limit:1 %}{{item}}{% endfor %}'
351
- assert_template_result(expected, template, assigns)
352
- assert !loader.each_called
353
- assert loader.load_slice_called
354
- end
355
-
356
- def test_iterate_with_load_slice_when_limit_and_offset_applied
357
- loader = LoaderDrop.new([1,2,3,4,5])
358
- assigns = {'items' => loader}
359
- expected = '34'
360
- template = '{% for item in items offset:2 limit:2 %}{{item}}{% endfor %}'
361
- assert_template_result(expected, template, assigns)
362
- assert !loader.each_called
363
- assert loader.load_slice_called
364
- end
365
-
366
- def test_iterate_with_load_slice_returns_same_results_as_without
367
- loader = LoaderDrop.new([1,2,3,4,5])
368
- loader_assigns = {'items' => loader}
369
- array_assigns = {'items' => [1,2,3,4,5]}
370
- expected = '34'
371
- template = '{% for item in items offset:2 limit:2 %}{{item}}{% endfor %}'
372
- assert_template_result(expected, template, loader_assigns)
373
- assert_template_result(expected, template, array_assigns)
374
- end
375
- end
@@ -1,190 +0,0 @@
1
- require 'test_helper'
2
-
3
- class IfElseTagTest < Minitest::Test
4
- include Liquid
5
-
6
- def test_if
7
- assert_template_result(' ',' {% if false %} this text should not go into the output {% endif %} ')
8
- assert_template_result(' this text should go into the output ',
9
- ' {% if true %} this text should go into the output {% endif %} ')
10
- assert_template_result(' you rock ?','{% if false %} you suck {% endif %} {% if true %} you rock {% endif %}?')
11
- end
12
-
13
- def test_literal_comparisons
14
- assert_template_result(' NO ','{% assign v = false %}{% if v %} YES {% else %} NO {% endif %}')
15
- assert_template_result(' YES ','{% assign v = nil %}{% if v == nil %} YES {% else %} NO {% endif %}')
16
- end
17
-
18
- def test_if_else
19
- assert_template_result(' YES ','{% if false %} NO {% else %} YES {% endif %}')
20
- assert_template_result(' YES ','{% if true %} YES {% else %} NO {% endif %}')
21
- assert_template_result(' YES ','{% if "foo" %} YES {% else %} NO {% endif %}')
22
- end
23
-
24
- def test_if_boolean
25
- assert_template_result(' YES ','{% if var %} YES {% endif %}', 'var' => true)
26
- end
27
-
28
- def test_if_or
29
- assert_template_result(' YES ','{% if a or b %} YES {% endif %}', 'a' => true, 'b' => true)
30
- assert_template_result(' YES ','{% if a or b %} YES {% endif %}', 'a' => true, 'b' => false)
31
- assert_template_result(' YES ','{% if a or b %} YES {% endif %}', 'a' => false, 'b' => true)
32
- assert_template_result('', '{% if a or b %} YES {% endif %}', 'a' => false, 'b' => false)
33
-
34
- assert_template_result(' YES ','{% if a or b or c %} YES {% endif %}', 'a' => false, 'b' => false, 'c' => true)
35
- assert_template_result('', '{% if a or b or c %} YES {% endif %}', 'a' => false, 'b' => false, 'c' => false)
36
- end
37
-
38
- def test_if_or_with_operators
39
- assert_template_result(' YES ','{% if a == true or b == true %} YES {% endif %}', 'a' => true, 'b' => true)
40
- assert_template_result(' YES ','{% if a == true or b == false %} YES {% endif %}', 'a' => true, 'b' => true)
41
- assert_template_result('','{% if a == false or b == false %} YES {% endif %}', 'a' => true, 'b' => true)
42
- end
43
-
44
- def test_comparison_of_strings_containing_and_or_or
45
- 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}
47
- assert_template_result(' YES ',"{% if #{awful_markup} %} YES {% endif %}", assigns)
48
- end
49
-
50
- def test_comparison_of_expressions_starting_with_and_or_or
51
- assigns = {'order' => {'items_count' => 0}, 'android' => {'name' => 'Roy'}}
52
- assert_template_result( "YES",
53
- "{% if android.name == 'Roy' %}YES{% endif %}",
54
- assigns)
55
- assert_template_result( "YES",
56
- "{% if order.items_count == 0 %}YES{% endif %}",
57
- assigns)
58
- end
59
-
60
- def test_if_and
61
- assert_template_result(' YES ','{% if true and true %} YES {% endif %}')
62
- assert_template_result('','{% if false and true %} YES {% endif %}')
63
- assert_template_result('','{% if false and true %} YES {% endif %}')
64
- end
65
-
66
-
67
- def test_hash_miss_generates_false
68
- assert_template_result('','{% if foo.bar %} NO {% endif %}', 'foo' => {})
69
- end
70
-
71
- def test_if_from_variable
72
- assert_template_result('','{% if var %} NO {% endif %}', 'var' => false)
73
- assert_template_result('','{% if var %} NO {% endif %}', 'var' => nil)
74
- assert_template_result('','{% if foo.bar %} NO {% endif %}', 'foo' => {'bar' => false})
75
- assert_template_result('','{% if foo.bar %} NO {% endif %}', 'foo' => {})
76
- assert_template_result('','{% if foo.bar %} NO {% endif %}', 'foo' => nil)
77
- assert_template_result('','{% if foo.bar %} NO {% endif %}', 'foo' => true)
78
-
79
- assert_template_result(' YES ','{% if var %} YES {% endif %}', 'var' => "text")
80
- assert_template_result(' YES ','{% if var %} YES {% endif %}', 'var' => true)
81
- assert_template_result(' YES ','{% if var %} YES {% endif %}', 'var' => 1)
82
- assert_template_result(' YES ','{% if var %} YES {% endif %}', 'var' => {})
83
- assert_template_result(' YES ','{% if var %} YES {% endif %}', 'var' => [])
84
- assert_template_result(' YES ','{% if "foo" %} YES {% endif %}')
85
- assert_template_result(' YES ','{% if foo.bar %} YES {% endif %}', 'foo' => {'bar' => true})
86
- assert_template_result(' YES ','{% if foo.bar %} YES {% endif %}', 'foo' => {'bar' => "text"})
87
- assert_template_result(' YES ','{% if foo.bar %} YES {% endif %}', 'foo' => {'bar' => 1 })
88
- assert_template_result(' YES ','{% if foo.bar %} YES {% endif %}', 'foo' => {'bar' => {} })
89
- assert_template_result(' YES ','{% if foo.bar %} YES {% endif %}', 'foo' => {'bar' => [] })
90
-
91
- assert_template_result(' YES ','{% if var %} NO {% else %} YES {% endif %}', 'var' => false)
92
- assert_template_result(' YES ','{% if var %} NO {% else %} YES {% endif %}', 'var' => nil)
93
- assert_template_result(' YES ','{% if var %} YES {% else %} NO {% endif %}', 'var' => true)
94
- assert_template_result(' YES ','{% if "foo" %} YES {% else %} NO {% endif %}', 'var' => "text")
95
-
96
- assert_template_result(' YES ','{% if foo.bar %} NO {% else %} YES {% endif %}', 'foo' => {'bar' => false})
97
- assert_template_result(' YES ','{% if foo.bar %} YES {% else %} NO {% endif %}', 'foo' => {'bar' => true})
98
- assert_template_result(' YES ','{% if foo.bar %} YES {% else %} NO {% endif %}', 'foo' => {'bar' => "text"})
99
- assert_template_result(' YES ','{% if foo.bar %} NO {% else %} YES {% endif %}', 'foo' => {'notbar' => true})
100
- assert_template_result(' YES ','{% if foo.bar %} NO {% else %} YES {% endif %}', 'foo' => {})
101
- assert_template_result(' YES ','{% if foo.bar %} NO {% else %} YES {% endif %}', 'notfoo' => {'bar' => true})
102
- end
103
-
104
- def test_nested_if
105
- assert_template_result('', '{% if false %}{% if false %} NO {% endif %}{% endif %}')
106
- assert_template_result('', '{% if false %}{% if true %} NO {% endif %}{% endif %}')
107
- assert_template_result('', '{% if true %}{% if false %} NO {% endif %}{% endif %}')
108
- assert_template_result(' YES ', '{% if true %}{% if true %} YES {% endif %}{% endif %}')
109
-
110
- assert_template_result(' YES ', '{% if true %}{% if true %} YES {% else %} NO {% endif %}{% else %} NO {% endif %}')
111
- assert_template_result(' YES ', '{% if true %}{% if false %} NO {% else %} YES {% endif %}{% else %} NO {% endif %}')
112
- assert_template_result(' YES ', '{% if false %}{% if true %} NO {% else %} NONO {% endif %}{% else %} YES {% endif %}')
113
-
114
- end
115
-
116
- def test_comparisons_on_null
117
- assert_template_result('','{% if null < 10 %} NO {% endif %}')
118
- assert_template_result('','{% if null <= 10 %} NO {% endif %}')
119
- assert_template_result('','{% if null >= 10 %} NO {% endif %}')
120
- assert_template_result('','{% if null > 10 %} NO {% endif %}')
121
-
122
- assert_template_result('','{% if 10 < null %} NO {% endif %}')
123
- assert_template_result('','{% if 10 <= null %} NO {% endif %}')
124
- assert_template_result('','{% if 10 >= null %} NO {% endif %}')
125
- assert_template_result('','{% if 10 > null %} NO {% endif %}')
126
- end
127
-
128
- def test_else_if
129
- assert_template_result('0','{% if 0 == 0 %}0{% elsif 1 == 1%}1{% else %}2{% endif %}')
130
- assert_template_result('1','{% if 0 != 0 %}0{% elsif 1 == 1%}1{% else %}2{% endif %}')
131
- assert_template_result('2','{% if 0 != 0 %}0{% elsif 1 != 1%}1{% else %}2{% endif %}')
132
-
133
- assert_template_result('elsif','{% if false %}if{% elsif true %}elsif{% endif %}')
134
- end
135
-
136
- def test_syntax_error_no_variable
137
- assert_raises(SyntaxError){ assert_template_result('', '{% if jerry == 1 %}')}
138
- end
139
-
140
- def test_syntax_error_no_expression
141
- assert_raises(SyntaxError) { assert_template_result('', '{% if %}') }
142
- end
143
-
144
- def test_if_with_custom_condition
145
- original_op = Condition.operators['contains']
146
- Condition.operators['contains'] = :[]
147
-
148
- assert_template_result('yes', %({% if 'bob' contains 'o' %}yes{% endif %}))
149
- assert_template_result('no', %({% if 'bob' contains 'f' %}yes{% else %}no{% endif %}))
150
- ensure
151
- Condition.operators['contains'] = original_op
152
- end
153
-
154
- def test_operators_are_ignored_unless_isolated
155
- original_op = Condition.operators['contains']
156
- Condition.operators['contains'] = :[]
157
-
158
- assert_template_result('yes',
159
- %({% if 'gnomeslab-and-or-liquid' contains 'gnomeslab-and-or-liquid' %}yes{% endif %}))
160
- ensure
161
- Condition.operators['contains'] = original_op
162
- end
163
-
164
- def test_operators_are_whitelisted
165
- assert_raises(SyntaxError) do
166
- assert_template_result('', %({% if 1 or throw or or 1 %}yes{% endif %}))
167
- end
168
- end
169
-
170
- def test_multiple_conditions
171
- tpl = "{% if a or b and c %}true{% else %}false{% endif %}"
172
-
173
- tests = {
174
- [true, true, true] => true,
175
- [true, true, false] => true,
176
- [true, false, true] => true,
177
- [true, false, false] => true,
178
- [false, true, true] => true,
179
- [false, true, false] => false,
180
- [false, false, true] => false,
181
- [false, false, false] => false,
182
- }
183
-
184
- tests.each do |vals, expected|
185
- a, b, c = vals
186
- assigns = { 'a' => a, 'b' => b, 'c' => c }
187
- assert_template_result expected.to_s, tpl, assigns, assigns.to_s
188
- end
189
- end
190
- end