liquid 4.0.1 → 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 (112) hide show
  1. checksums.yaml +4 -4
  2. data/History.md +142 -0
  3. data/README.md +10 -4
  4. data/lib/liquid/block.rb +31 -14
  5. data/lib/liquid/block_body.rb +169 -56
  6. data/lib/liquid/condition.rb +59 -23
  7. data/lib/liquid/context.rb +111 -52
  8. data/lib/liquid/document.rb +47 -9
  9. data/lib/liquid/drop.rb +4 -2
  10. data/lib/liquid/errors.rb +20 -18
  11. data/lib/liquid/expression.rb +29 -33
  12. data/lib/liquid/extensions.rb +2 -0
  13. data/lib/liquid/file_system.rb +6 -4
  14. data/lib/liquid/forloop_drop.rb +54 -4
  15. data/lib/liquid/i18n.rb +5 -3
  16. data/lib/liquid/interrupts.rb +3 -1
  17. data/lib/liquid/lexer.rb +31 -24
  18. data/lib/liquid/locales/en.yml +8 -5
  19. data/lib/liquid/parse_context.rb +20 -4
  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 +17 -3
  23. data/lib/liquid/partial_cache.rb +24 -0
  24. data/lib/liquid/profiler/hooks.rb +26 -14
  25. data/lib/liquid/profiler.rb +67 -86
  26. data/lib/liquid/range_lookup.rb +13 -3
  27. data/lib/liquid/registers.rb +51 -0
  28. data/lib/liquid/resource_limits.rb +47 -8
  29. data/lib/liquid/standardfilters.rb +616 -129
  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 +64 -5
  33. data/lib/liquid/tag/disableable.rb +22 -0
  34. data/lib/liquid/tag/disabler.rb +21 -0
  35. data/lib/liquid/tag.rb +28 -6
  36. data/lib/liquid/tags/assign.rb +44 -18
  37. data/lib/liquid/tags/break.rb +16 -3
  38. data/lib/liquid/tags/capture.rb +24 -18
  39. data/lib/liquid/tags/case.rb +69 -27
  40. data/lib/liquid/tags/comment.rb +18 -3
  41. data/lib/liquid/tags/continue.rb +16 -12
  42. data/lib/liquid/tags/cycle.rb +45 -25
  43. data/lib/liquid/tags/decrement.rb +22 -20
  44. data/lib/liquid/tags/echo.rb +41 -0
  45. data/lib/liquid/tags/for.rb +97 -89
  46. data/lib/liquid/tags/if.rb +61 -35
  47. data/lib/liquid/tags/ifchanged.rb +11 -10
  48. data/lib/liquid/tags/include.rb +56 -56
  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 +25 -11
  52. data/lib/liquid/tags/render.rb +109 -0
  53. data/lib/liquid/tags/table_row.rb +53 -19
  54. data/lib/liquid/tags/unless.rb +38 -19
  55. data/lib/liquid/template.rb +52 -72
  56. data/lib/liquid/template_factory.rb +9 -0
  57. data/lib/liquid/tokenizer.rb +18 -10
  58. data/lib/liquid/usage.rb +8 -0
  59. data/lib/liquid/utils.rb +13 -3
  60. data/lib/liquid/variable.rb +52 -41
  61. data/lib/liquid/variable_lookup.rb +24 -10
  62. data/lib/liquid/version.rb +3 -1
  63. data/lib/liquid.rb +19 -6
  64. metadata +21 -104
  65. data/lib/liquid/strainer.rb +0 -66
  66. data/test/fixtures/en_locale.yml +0 -9
  67. data/test/integration/assign_test.rb +0 -48
  68. data/test/integration/blank_test.rb +0 -106
  69. data/test/integration/block_test.rb +0 -12
  70. data/test/integration/capture_test.rb +0 -50
  71. data/test/integration/context_test.rb +0 -32
  72. data/test/integration/document_test.rb +0 -19
  73. data/test/integration/drop_test.rb +0 -273
  74. data/test/integration/error_handling_test.rb +0 -260
  75. data/test/integration/filter_test.rb +0 -178
  76. data/test/integration/hash_ordering_test.rb +0 -23
  77. data/test/integration/output_test.rb +0 -123
  78. data/test/integration/parsing_quirks_test.rb +0 -122
  79. data/test/integration/render_profiling_test.rb +0 -154
  80. data/test/integration/security_test.rb +0 -80
  81. data/test/integration/standard_filter_test.rb +0 -626
  82. data/test/integration/tags/break_tag_test.rb +0 -15
  83. data/test/integration/tags/continue_tag_test.rb +0 -15
  84. data/test/integration/tags/for_tag_test.rb +0 -410
  85. data/test/integration/tags/if_else_tag_test.rb +0 -188
  86. data/test/integration/tags/include_tag_test.rb +0 -245
  87. data/test/integration/tags/increment_tag_test.rb +0 -23
  88. data/test/integration/tags/raw_tag_test.rb +0 -31
  89. data/test/integration/tags/standard_tag_test.rb +0 -296
  90. data/test/integration/tags/statements_test.rb +0 -111
  91. data/test/integration/tags/table_row_test.rb +0 -64
  92. data/test/integration/tags/unless_else_tag_test.rb +0 -26
  93. data/test/integration/template_test.rb +0 -332
  94. data/test/integration/trim_mode_test.rb +0 -529
  95. data/test/integration/variable_test.rb +0 -96
  96. data/test/test_helper.rb +0 -116
  97. data/test/unit/block_unit_test.rb +0 -58
  98. data/test/unit/condition_unit_test.rb +0 -166
  99. data/test/unit/context_unit_test.rb +0 -489
  100. data/test/unit/file_system_unit_test.rb +0 -35
  101. data/test/unit/i18n_unit_test.rb +0 -37
  102. data/test/unit/lexer_unit_test.rb +0 -51
  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 -164
  106. data/test/unit/tag_unit_test.rb +0 -21
  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 -78
  111. data/test/unit/tokenizer_unit_test.rb +0 -55
  112. data/test/unit/variable_unit_test.rb +0 -162
@@ -1,626 +0,0 @@
1
- # encoding: utf-8
2
-
3
- require 'test_helper'
4
-
5
- class Filters
6
- include Liquid::StandardFilters
7
- end
8
-
9
- class TestThing
10
- attr_reader :foo
11
-
12
- def initialize
13
- @foo = 0
14
- end
15
-
16
- def to_s
17
- "woot: #{@foo}"
18
- end
19
-
20
- def [](whatever)
21
- to_s
22
- end
23
-
24
- def to_liquid
25
- @foo += 1
26
- self
27
- end
28
- end
29
-
30
- class TestDrop < Liquid::Drop
31
- def test
32
- "testfoo"
33
- end
34
- end
35
-
36
- class TestEnumerable < Liquid::Drop
37
- include Enumerable
38
-
39
- def each(&block)
40
- [ { "foo" => 1, "bar" => 2 }, { "foo" => 2, "bar" => 1 }, { "foo" => 3, "bar" => 3 } ].each(&block)
41
- end
42
- end
43
-
44
- class NumberLikeThing < Liquid::Drop
45
- def initialize(amount)
46
- @amount = amount
47
- end
48
-
49
- def to_number
50
- @amount
51
- end
52
- end
53
-
54
- class StandardFiltersTest < Minitest::Test
55
- include Liquid
56
-
57
- def setup
58
- @filters = Filters.new
59
- end
60
-
61
- def test_size
62
- assert_equal 3, @filters.size([1, 2, 3])
63
- assert_equal 0, @filters.size([])
64
- assert_equal 0, @filters.size(nil)
65
- end
66
-
67
- def test_downcase
68
- assert_equal 'testing', @filters.downcase("Testing")
69
- assert_equal '', @filters.downcase(nil)
70
- end
71
-
72
- def test_upcase
73
- assert_equal 'TESTING', @filters.upcase("Testing")
74
- assert_equal '', @filters.upcase(nil)
75
- end
76
-
77
- def test_slice
78
- assert_equal 'oob', @filters.slice('foobar', 1, 3)
79
- assert_equal 'oobar', @filters.slice('foobar', 1, 1000)
80
- assert_equal '', @filters.slice('foobar', 1, 0)
81
- assert_equal 'o', @filters.slice('foobar', 1, 1)
82
- assert_equal 'bar', @filters.slice('foobar', 3, 3)
83
- assert_equal 'ar', @filters.slice('foobar', -2, 2)
84
- assert_equal 'ar', @filters.slice('foobar', -2, 1000)
85
- assert_equal 'r', @filters.slice('foobar', -1)
86
- assert_equal '', @filters.slice(nil, 0)
87
- assert_equal '', @filters.slice('foobar', 100, 10)
88
- assert_equal '', @filters.slice('foobar', -100, 10)
89
- assert_equal 'oob', @filters.slice('foobar', '1', '3')
90
- assert_raises(Liquid::ArgumentError) do
91
- @filters.slice('foobar', nil)
92
- end
93
- assert_raises(Liquid::ArgumentError) do
94
- @filters.slice('foobar', 0, "")
95
- end
96
- end
97
-
98
- def test_slice_on_arrays
99
- input = 'foobar'.split(//)
100
- assert_equal %w(o o b), @filters.slice(input, 1, 3)
101
- assert_equal %w(o o b a r), @filters.slice(input, 1, 1000)
102
- assert_equal %w(), @filters.slice(input, 1, 0)
103
- assert_equal %w(o), @filters.slice(input, 1, 1)
104
- assert_equal %w(b a r), @filters.slice(input, 3, 3)
105
- assert_equal %w(a r), @filters.slice(input, -2, 2)
106
- assert_equal %w(a r), @filters.slice(input, -2, 1000)
107
- assert_equal %w(r), @filters.slice(input, -1)
108
- assert_equal %w(), @filters.slice(input, 100, 10)
109
- assert_equal %w(), @filters.slice(input, -100, 10)
110
- end
111
-
112
- def test_truncate
113
- assert_equal '1234...', @filters.truncate('1234567890', 7)
114
- assert_equal '1234567890', @filters.truncate('1234567890', 20)
115
- assert_equal '...', @filters.truncate('1234567890', 0)
116
- assert_equal '1234567890', @filters.truncate('1234567890')
117
- assert_equal "测试...", @filters.truncate("测试测试测试测试", 5)
118
- assert_equal '12341', @filters.truncate("1234567890", 5, 1)
119
- end
120
-
121
- def test_split
122
- assert_equal ['12', '34'], @filters.split('12~34', '~')
123
- assert_equal ['A? ', ' ,Z'], @filters.split('A? ~ ~ ~ ,Z', '~ ~ ~')
124
- assert_equal ['A?Z'], @filters.split('A?Z', '~')
125
- assert_equal [], @filters.split(nil, ' ')
126
- assert_equal ['A', 'Z'], @filters.split('A1Z', 1)
127
- end
128
-
129
- def test_escape
130
- assert_equal '&lt;strong&gt;', @filters.escape('<strong>')
131
- assert_equal '1', @filters.escape(1)
132
- assert_equal '2001-02-03', @filters.escape(Date.new(2001, 2, 3))
133
- assert_nil @filters.escape(nil)
134
- end
135
-
136
- def test_h
137
- assert_equal '&lt;strong&gt;', @filters.h('<strong>')
138
- assert_equal '1', @filters.h(1)
139
- assert_equal '2001-02-03', @filters.h(Date.new(2001, 2, 3))
140
- assert_nil @filters.h(nil)
141
- end
142
-
143
- def test_escape_once
144
- assert_equal '&lt;strong&gt;Hulk&lt;/strong&gt;', @filters.escape_once('&lt;strong&gt;Hulk</strong>')
145
- end
146
-
147
- def test_url_encode
148
- assert_equal 'foo%2B1%40example.com', @filters.url_encode('foo+1@example.com')
149
- assert_equal '1', @filters.url_encode(1)
150
- assert_equal '2001-02-03', @filters.url_encode(Date.new(2001, 2, 3))
151
- assert_nil @filters.url_encode(nil)
152
- end
153
-
154
- def test_url_decode
155
- assert_equal 'foo bar', @filters.url_decode('foo+bar')
156
- assert_equal 'foo bar', @filters.url_decode('foo%20bar')
157
- assert_equal 'foo+1@example.com', @filters.url_decode('foo%2B1%40example.com')
158
- assert_equal '1', @filters.url_decode(1)
159
- assert_equal '2001-02-03', @filters.url_decode(Date.new(2001, 2, 3))
160
- assert_nil @filters.url_decode(nil)
161
- end
162
-
163
- def test_truncatewords
164
- assert_equal 'one two three', @filters.truncatewords('one two three', 4)
165
- assert_equal 'one two...', @filters.truncatewords('one two three', 2)
166
- assert_equal 'one two three', @filters.truncatewords('one two three')
167
- assert_equal 'Two small (13&#8221; x 5.5&#8221; x 10&#8221; high) baskets fit inside one large basket (13&#8221;...', @filters.truncatewords('Two small (13&#8221; x 5.5&#8221; x 10&#8221; high) baskets fit inside one large basket (13&#8221; x 16&#8221; x 10.5&#8221; high) with cover.', 15)
168
- assert_equal "测试测试测试测试", @filters.truncatewords('测试测试测试测试', 5)
169
- assert_equal 'one two1', @filters.truncatewords("one two three", 2, 1)
170
- end
171
-
172
- def test_strip_html
173
- assert_equal 'test', @filters.strip_html("<div>test</div>")
174
- assert_equal 'test', @filters.strip_html("<div id='test'>test</div>")
175
- assert_equal '', @filters.strip_html("<script type='text/javascript'>document.write('some stuff');</script>")
176
- assert_equal '', @filters.strip_html("<style type='text/css'>foo bar</style>")
177
- assert_equal 'test', @filters.strip_html("<div\nclass='multiline'>test</div>")
178
- assert_equal 'test', @filters.strip_html("<!-- foo bar \n test -->test")
179
- assert_equal '', @filters.strip_html(nil)
180
- end
181
-
182
- def test_join
183
- assert_equal '1 2 3 4', @filters.join([1, 2, 3, 4])
184
- assert_equal '1 - 2 - 3 - 4', @filters.join([1, 2, 3, 4], ' - ')
185
- assert_equal '1121314', @filters.join([1, 2, 3, 4], 1)
186
- end
187
-
188
- def test_sort
189
- assert_equal [1, 2, 3, 4], @filters.sort([4, 3, 2, 1])
190
- assert_equal [{ "a" => 1 }, { "a" => 2 }, { "a" => 3 }, { "a" => 4 }], @filters.sort([{ "a" => 4 }, { "a" => 3 }, { "a" => 1 }, { "a" => 2 }], "a")
191
- end
192
-
193
- def test_sort_with_nils
194
- assert_equal [1, 2, 3, 4, nil], @filters.sort([nil, 4, 3, 2, 1])
195
- assert_equal [{ "a" => 1 }, { "a" => 2 }, { "a" => 3 }, { "a" => 4 }, {}], @filters.sort([{ "a" => 4 }, { "a" => 3 }, {}, { "a" => 1 }, { "a" => 2 }], "a")
196
- end
197
-
198
- def test_sort_when_property_is_sometimes_missing_puts_nils_last
199
- input = [
200
- { "price" => 4, "handle" => "alpha" },
201
- { "handle" => "beta" },
202
- { "price" => 1, "handle" => "gamma" },
203
- { "handle" => "delta" },
204
- { "price" => 2, "handle" => "epsilon" }
205
- ]
206
- expectation = [
207
- { "price" => 1, "handle" => "gamma" },
208
- { "price" => 2, "handle" => "epsilon" },
209
- { "price" => 4, "handle" => "alpha" },
210
- { "handle" => "delta" },
211
- { "handle" => "beta" }
212
- ]
213
- assert_equal expectation, @filters.sort(input, "price")
214
- end
215
-
216
- def test_sort_natural
217
- assert_equal ["a", "B", "c", "D"], @filters.sort_natural(["c", "D", "a", "B"])
218
- assert_equal [{ "a" => "a" }, { "a" => "B" }, { "a" => "c" }, { "a" => "D" }], @filters.sort_natural([{ "a" => "D" }, { "a" => "c" }, { "a" => "a" }, { "a" => "B" }], "a")
219
- end
220
-
221
- def test_sort_natural_with_nils
222
- assert_equal ["a", "B", "c", "D", nil], @filters.sort_natural([nil, "c", "D", "a", "B"])
223
- assert_equal [{ "a" => "a" }, { "a" => "B" }, { "a" => "c" }, { "a" => "D" }, {}], @filters.sort_natural([{ "a" => "D" }, { "a" => "c" }, {}, { "a" => "a" }, { "a" => "B" }], "a")
224
- end
225
-
226
- def test_sort_natural_when_property_is_sometimes_missing_puts_nils_last
227
- input = [
228
- { "price" => "4", "handle" => "alpha" },
229
- { "handle" => "beta" },
230
- { "price" => "1", "handle" => "gamma" },
231
- { "handle" => "delta" },
232
- { "price" => 2, "handle" => "epsilon" }
233
- ]
234
- expectation = [
235
- { "price" => "1", "handle" => "gamma" },
236
- { "price" => 2, "handle" => "epsilon" },
237
- { "price" => "4", "handle" => "alpha" },
238
- { "handle" => "delta" },
239
- { "handle" => "beta" }
240
- ]
241
- assert_equal expectation, @filters.sort_natural(input, "price")
242
- end
243
-
244
- def test_sort_natural_case_check
245
- input = [
246
- { "key" => "X" },
247
- { "key" => "Y" },
248
- { "key" => "Z" },
249
- { "fake" => "t" },
250
- { "key" => "a" },
251
- { "key" => "b" },
252
- { "key" => "c" }
253
- ]
254
- expectation = [
255
- { "key" => "a" },
256
- { "key" => "b" },
257
- { "key" => "c" },
258
- { "key" => "X" },
259
- { "key" => "Y" },
260
- { "key" => "Z" },
261
- { "fake" => "t" }
262
- ]
263
- assert_equal expectation, @filters.sort_natural(input, "key")
264
- assert_equal ["a", "b", "c", "X", "Y", "Z"], @filters.sort_natural(["X", "Y", "Z", "a", "b", "c"])
265
- end
266
-
267
- def test_sort_empty_array
268
- assert_equal [], @filters.sort([], "a")
269
- end
270
-
271
- def test_sort_natural_empty_array
272
- assert_equal [], @filters.sort_natural([], "a")
273
- end
274
-
275
- def test_legacy_sort_hash
276
- assert_equal [{ a: 1, b: 2 }], @filters.sort({ a: 1, b: 2 })
277
- end
278
-
279
- def test_numerical_vs_lexicographical_sort
280
- assert_equal [2, 10], @filters.sort([10, 2])
281
- assert_equal [{ "a" => 2 }, { "a" => 10 }], @filters.sort([{ "a" => 10 }, { "a" => 2 }], "a")
282
- assert_equal ["10", "2"], @filters.sort(["10", "2"])
283
- assert_equal [{ "a" => "10" }, { "a" => "2" }], @filters.sort([{ "a" => "10" }, { "a" => "2" }], "a")
284
- end
285
-
286
- def test_uniq
287
- assert_equal ["foo"], @filters.uniq("foo")
288
- assert_equal [1, 3, 2, 4], @filters.uniq([1, 1, 3, 2, 3, 1, 4, 3, 2, 1])
289
- assert_equal [{ "a" => 1 }, { "a" => 3 }, { "a" => 2 }], @filters.uniq([{ "a" => 1 }, { "a" => 3 }, { "a" => 1 }, { "a" => 2 }], "a")
290
- testdrop = TestDrop.new
291
- assert_equal [testdrop], @filters.uniq([testdrop, TestDrop.new], 'test')
292
- end
293
-
294
- def test_uniq_empty_array
295
- assert_equal [], @filters.uniq([], "a")
296
- end
297
-
298
- def test_compact_empty_array
299
- assert_equal [], @filters.compact([], "a")
300
- end
301
-
302
- def test_reverse
303
- assert_equal [4, 3, 2, 1], @filters.reverse([1, 2, 3, 4])
304
- end
305
-
306
- def test_legacy_reverse_hash
307
- assert_equal [{ a: 1, b: 2 }], @filters.reverse(a: 1, b: 2)
308
- end
309
-
310
- def test_map
311
- assert_equal [1, 2, 3, 4], @filters.map([{ "a" => 1 }, { "a" => 2 }, { "a" => 3 }, { "a" => 4 }], 'a')
312
- assert_template_result 'abc', "{{ ary | map:'foo' | map:'bar' }}",
313
- 'ary' => [{ 'foo' => { 'bar' => 'a' } }, { 'foo' => { 'bar' => 'b' } }, { 'foo' => { 'bar' => 'c' } }]
314
- end
315
-
316
- def test_map_doesnt_call_arbitrary_stuff
317
- assert_template_result "", '{{ "foo" | map: "__id__" }}'
318
- assert_template_result "", '{{ "foo" | map: "inspect" }}'
319
- end
320
-
321
- def test_map_calls_to_liquid
322
- t = TestThing.new
323
- assert_template_result "woot: 1", '{{ foo | map: "whatever" }}', "foo" => [t]
324
- end
325
-
326
- def test_map_on_hashes
327
- assert_template_result "4217", '{{ thing | map: "foo" | map: "bar" }}',
328
- "thing" => { "foo" => [ { "bar" => 42 }, { "bar" => 17 } ] }
329
- end
330
-
331
- def test_legacy_map_on_hashes_with_dynamic_key
332
- template = "{% assign key = 'foo' %}{{ thing | map: key | map: 'bar' }}"
333
- hash = { "foo" => { "bar" => 42 } }
334
- assert_template_result "42", template, "thing" => hash
335
- end
336
-
337
- def test_sort_calls_to_liquid
338
- t = TestThing.new
339
- Liquid::Template.parse('{{ foo | sort: "whatever" }}').render("foo" => [t])
340
- assert t.foo > 0
341
- end
342
-
343
- def test_map_over_proc
344
- drop = TestDrop.new
345
- p = proc{ drop }
346
- templ = '{{ procs | map: "test" }}'
347
- assert_template_result "testfoo", templ, "procs" => [p]
348
- end
349
-
350
- def test_map_over_drops_returning_procs
351
- drops = [
352
- {
353
- "proc" => ->{ "foo" },
354
- },
355
- {
356
- "proc" => ->{ "bar" },
357
- },
358
- ]
359
- templ = '{{ drops | map: "proc" }}'
360
- assert_template_result "foobar", templ, "drops" => drops
361
- end
362
-
363
- def test_map_works_on_enumerables
364
- assert_template_result "123", '{{ foo | map: "foo" }}', "foo" => TestEnumerable.new
365
- end
366
-
367
- def test_sort_works_on_enumerables
368
- assert_template_result "213", '{{ foo | sort: "bar" | map: "foo" }}', "foo" => TestEnumerable.new
369
- end
370
-
371
- def test_first_and_last_call_to_liquid
372
- assert_template_result 'foobar', '{{ foo | first }}', 'foo' => [ThingWithToLiquid.new]
373
- assert_template_result 'foobar', '{{ foo | last }}', 'foo' => [ThingWithToLiquid.new]
374
- end
375
-
376
- def test_truncate_calls_to_liquid
377
- assert_template_result "wo...", '{{ foo | truncate: 5 }}', "foo" => TestThing.new
378
- end
379
-
380
- def test_date
381
- assert_equal 'May', @filters.date(Time.parse("2006-05-05 10:00:00"), "%B")
382
- assert_equal 'June', @filters.date(Time.parse("2006-06-05 10:00:00"), "%B")
383
- assert_equal 'July', @filters.date(Time.parse("2006-07-05 10:00:00"), "%B")
384
-
385
- assert_equal 'May', @filters.date("2006-05-05 10:00:00", "%B")
386
- assert_equal 'June', @filters.date("2006-06-05 10:00:00", "%B")
387
- assert_equal 'July', @filters.date("2006-07-05 10:00:00", "%B")
388
-
389
- assert_equal '2006-07-05 10:00:00', @filters.date("2006-07-05 10:00:00", "")
390
- assert_equal '2006-07-05 10:00:00', @filters.date("2006-07-05 10:00:00", "")
391
- assert_equal '2006-07-05 10:00:00', @filters.date("2006-07-05 10:00:00", "")
392
- assert_equal '2006-07-05 10:00:00', @filters.date("2006-07-05 10:00:00", nil)
393
-
394
- assert_equal '07/05/2006', @filters.date("2006-07-05 10:00:00", "%m/%d/%Y")
395
-
396
- assert_equal "07/16/2004", @filters.date("Fri Jul 16 01:00:00 2004", "%m/%d/%Y")
397
- assert_equal "#{Date.today.year}", @filters.date('now', '%Y')
398
- assert_equal "#{Date.today.year}", @filters.date('today', '%Y')
399
- assert_equal "#{Date.today.year}", @filters.date('Today', '%Y')
400
-
401
- assert_nil @filters.date(nil, "%B")
402
-
403
- assert_equal '', @filters.date('', "%B")
404
-
405
- with_timezone("UTC") do
406
- assert_equal "07/05/2006", @filters.date(1152098955, "%m/%d/%Y")
407
- assert_equal "07/05/2006", @filters.date("1152098955", "%m/%d/%Y")
408
- end
409
- end
410
-
411
- def test_first_last
412
- assert_equal 1, @filters.first([1, 2, 3])
413
- assert_equal 3, @filters.last([1, 2, 3])
414
- assert_nil @filters.first([])
415
- assert_nil @filters.last([])
416
- end
417
-
418
- def test_replace
419
- assert_equal '2 2 2 2', @filters.replace('1 1 1 1', '1', 2)
420
- assert_equal '2 2 2 2', @filters.replace('1 1 1 1', 1, 2)
421
- assert_equal '2 1 1 1', @filters.replace_first('1 1 1 1', '1', 2)
422
- assert_equal '2 1 1 1', @filters.replace_first('1 1 1 1', 1, 2)
423
- assert_template_result '2 1 1 1', "{{ '1 1 1 1' | replace_first: '1', 2 }}"
424
- end
425
-
426
- def test_remove
427
- assert_equal ' ', @filters.remove("a a a a", 'a')
428
- assert_equal ' ', @filters.remove("1 1 1 1", 1)
429
- assert_equal 'a a a', @filters.remove_first("a a a a", 'a ')
430
- assert_equal ' 1 1 1', @filters.remove_first("1 1 1 1", 1)
431
- assert_template_result 'a a a', "{{ 'a a a a' | remove_first: 'a ' }}"
432
- end
433
-
434
- def test_pipes_in_string_arguments
435
- assert_template_result 'foobar', "{{ 'foo|bar' | remove: '|' }}"
436
- end
437
-
438
- def test_strip
439
- assert_template_result 'ab c', "{{ source | strip }}", 'source' => " ab c "
440
- assert_template_result 'ab c', "{{ source | strip }}", 'source' => " \tab c \n \t"
441
- end
442
-
443
- def test_lstrip
444
- assert_template_result 'ab c ', "{{ source | lstrip }}", 'source' => " ab c "
445
- assert_template_result "ab c \n \t", "{{ source | lstrip }}", 'source' => " \tab c \n \t"
446
- end
447
-
448
- def test_rstrip
449
- assert_template_result " ab c", "{{ source | rstrip }}", 'source' => " ab c "
450
- assert_template_result " \tab c", "{{ source | rstrip }}", 'source' => " \tab c \n \t"
451
- end
452
-
453
- def test_strip_newlines
454
- assert_template_result 'abc', "{{ source | strip_newlines }}", 'source' => "a\nb\nc"
455
- assert_template_result 'abc', "{{ source | strip_newlines }}", 'source' => "a\r\nb\nc"
456
- end
457
-
458
- def test_newlines_to_br
459
- assert_template_result "a<br />\nb<br />\nc", "{{ source | newline_to_br }}", 'source' => "a\nb\nc"
460
- end
461
-
462
- def test_plus
463
- assert_template_result "2", "{{ 1 | plus:1 }}"
464
- assert_template_result "2.0", "{{ '1' | plus:'1.0' }}"
465
-
466
- assert_template_result "5", "{{ price | plus:'2' }}", 'price' => NumberLikeThing.new(3)
467
- end
468
-
469
- def test_minus
470
- assert_template_result "4", "{{ input | minus:operand }}", 'input' => 5, 'operand' => 1
471
- assert_template_result "2.3", "{{ '4.3' | minus:'2' }}"
472
-
473
- assert_template_result "5", "{{ price | minus:'2' }}", 'price' => NumberLikeThing.new(7)
474
- end
475
-
476
- def test_abs
477
- assert_template_result "17", "{{ 17 | abs }}"
478
- assert_template_result "17", "{{ -17 | abs }}"
479
- assert_template_result "17", "{{ '17' | abs }}"
480
- assert_template_result "17", "{{ '-17' | abs }}"
481
- assert_template_result "0", "{{ 0 | abs }}"
482
- assert_template_result "0", "{{ '0' | abs }}"
483
- assert_template_result "17.42", "{{ 17.42 | abs }}"
484
- assert_template_result "17.42", "{{ -17.42 | abs }}"
485
- assert_template_result "17.42", "{{ '17.42' | abs }}"
486
- assert_template_result "17.42", "{{ '-17.42' | abs }}"
487
- end
488
-
489
- def test_times
490
- assert_template_result "12", "{{ 3 | times:4 }}"
491
- assert_template_result "0", "{{ 'foo' | times:4 }}"
492
- assert_template_result "6", "{{ '2.1' | times:3 | replace: '.','-' | plus:0}}"
493
- assert_template_result "7.25", "{{ 0.0725 | times:100 }}"
494
- assert_template_result "-7.25", '{{ "-0.0725" | times:100 }}'
495
- assert_template_result "7.25", '{{ "-0.0725" | times: -100 }}'
496
- assert_template_result "4", "{{ price | times:2 }}", 'price' => NumberLikeThing.new(2)
497
- end
498
-
499
- def test_divided_by
500
- assert_template_result "4", "{{ 12 | divided_by:3 }}"
501
- assert_template_result "4", "{{ 14 | divided_by:3 }}"
502
-
503
- assert_template_result "5", "{{ 15 | divided_by:3 }}"
504
- assert_equal "Liquid error: divided by 0", Template.parse("{{ 5 | divided_by:0 }}").render
505
-
506
- assert_template_result "0.5", "{{ 2.0 | divided_by:4 }}"
507
- assert_raises(Liquid::ZeroDivisionError) do
508
- assert_template_result "4", "{{ 1 | modulo: 0 }}"
509
- end
510
-
511
- assert_template_result "5", "{{ price | divided_by:2 }}", 'price' => NumberLikeThing.new(10)
512
- end
513
-
514
- def test_modulo
515
- assert_template_result "1", "{{ 3 | modulo:2 }}"
516
- assert_raises(Liquid::ZeroDivisionError) do
517
- assert_template_result "4", "{{ 1 | modulo: 0 }}"
518
- end
519
-
520
- assert_template_result "1", "{{ price | modulo:2 }}", 'price' => NumberLikeThing.new(3)
521
- end
522
-
523
- def test_round
524
- assert_template_result "5", "{{ input | round }}", 'input' => 4.6
525
- assert_template_result "4", "{{ '4.3' | round }}"
526
- assert_template_result "4.56", "{{ input | round: 2 }}", 'input' => 4.5612
527
- assert_raises(Liquid::FloatDomainError) do
528
- assert_template_result "4", "{{ 1.0 | divided_by: 0.0 | round }}"
529
- end
530
-
531
- assert_template_result "5", "{{ price | round }}", 'price' => NumberLikeThing.new(4.6)
532
- assert_template_result "4", "{{ price | round }}", 'price' => NumberLikeThing.new(4.3)
533
- end
534
-
535
- def test_ceil
536
- assert_template_result "5", "{{ input | ceil }}", 'input' => 4.6
537
- assert_template_result "5", "{{ '4.3' | ceil }}"
538
- assert_raises(Liquid::FloatDomainError) do
539
- assert_template_result "4", "{{ 1.0 | divided_by: 0.0 | ceil }}"
540
- end
541
-
542
- assert_template_result "5", "{{ price | ceil }}", 'price' => NumberLikeThing.new(4.6)
543
- end
544
-
545
- def test_floor
546
- assert_template_result "4", "{{ input | floor }}", 'input' => 4.6
547
- assert_template_result "4", "{{ '4.3' | floor }}"
548
- assert_raises(Liquid::FloatDomainError) do
549
- assert_template_result "4", "{{ 1.0 | divided_by: 0.0 | floor }}"
550
- end
551
-
552
- assert_template_result "5", "{{ price | floor }}", 'price' => NumberLikeThing.new(5.4)
553
- end
554
-
555
- def test_at_most
556
- assert_template_result "4", "{{ 5 | at_most:4 }}"
557
- assert_template_result "5", "{{ 5 | at_most:5 }}"
558
- assert_template_result "5", "{{ 5 | at_most:6 }}"
559
-
560
- assert_template_result "4.5", "{{ 4.5 | at_most:5 }}"
561
- assert_template_result "5", "{{ width | at_most:5 }}", 'width' => NumberLikeThing.new(6)
562
- assert_template_result "4", "{{ width | at_most:5 }}", 'width' => NumberLikeThing.new(4)
563
- assert_template_result "4", "{{ 5 | at_most: width }}", 'width' => NumberLikeThing.new(4)
564
- end
565
-
566
- def test_at_least
567
- assert_template_result "5", "{{ 5 | at_least:4 }}"
568
- assert_template_result "5", "{{ 5 | at_least:5 }}"
569
- assert_template_result "6", "{{ 5 | at_least:6 }}"
570
-
571
- assert_template_result "5", "{{ 4.5 | at_least:5 }}"
572
- assert_template_result "6", "{{ width | at_least:5 }}", 'width' => NumberLikeThing.new(6)
573
- assert_template_result "5", "{{ width | at_least:5 }}", 'width' => NumberLikeThing.new(4)
574
- assert_template_result "6", "{{ 5 | at_least: width }}", 'width' => NumberLikeThing.new(6)
575
- end
576
-
577
- def test_append
578
- assigns = { 'a' => 'bc', 'b' => 'd' }
579
- assert_template_result('bcd', "{{ a | append: 'd'}}", assigns)
580
- assert_template_result('bcd', "{{ a | append: b}}", assigns)
581
- end
582
-
583
- def test_concat
584
- assert_equal [1, 2, 3, 4], @filters.concat([1, 2], [3, 4])
585
- assert_equal [1, 2, 'a'], @filters.concat([1, 2], ['a'])
586
- assert_equal [1, 2, 10], @filters.concat([1, 2], [10])
587
-
588
- assert_raises(Liquid::ArgumentError, "concat filter requires an array argument") do
589
- @filters.concat([1, 2], 10)
590
- end
591
- end
592
-
593
- def test_prepend
594
- assigns = { 'a' => 'bc', 'b' => 'a' }
595
- assert_template_result('abc', "{{ a | prepend: 'a'}}", assigns)
596
- assert_template_result('abc', "{{ a | prepend: b}}", assigns)
597
- end
598
-
599
- def test_default
600
- assert_equal "foo", @filters.default("foo", "bar")
601
- assert_equal "bar", @filters.default(nil, "bar")
602
- assert_equal "bar", @filters.default("", "bar")
603
- assert_equal "bar", @filters.default(false, "bar")
604
- assert_equal "bar", @filters.default([], "bar")
605
- assert_equal "bar", @filters.default({}, "bar")
606
- end
607
-
608
- def test_cannot_access_private_methods
609
- assert_template_result('a', "{{ 'a' | to_number }}")
610
- end
611
-
612
- def test_date_raises_nothing
613
- assert_template_result('', "{{ '' | date: '%D' }}")
614
- assert_template_result('abc', "{{ 'abc' | date: '%D' }}")
615
- end
616
-
617
- private
618
-
619
- def with_timezone(tz)
620
- old_tz = ENV['TZ']
621
- ENV['TZ'] = tz
622
- yield
623
- ensure
624
- ENV['TZ'] = old_tz
625
- end
626
- end # StandardFiltersTest
@@ -1,15 +0,0 @@
1
- require 'test_helper'
2
-
3
- class BreakTagTest < Minitest::Test
4
- include Liquid
5
-
6
- # tests that no weird errors are raised if break is called outside of a
7
- # block
8
- def test_break_with_no_block
9
- assigns = { 'i' => 1 }
10
- markup = '{% break %}'
11
- expected = ''
12
-
13
- assert_template_result(expected, markup, assigns)
14
- end
15
- end
@@ -1,15 +0,0 @@
1
- require 'test_helper'
2
-
3
- class ContinueTagTest < Minitest::Test
4
- include Liquid
5
-
6
- # tests that no weird errors are raised if continue is called outside of a
7
- # block
8
- def test_continue_with_no_block
9
- assigns = {}
10
- markup = '{% continue %}'
11
- expected = ''
12
-
13
- assert_template_result(expected, markup, assigns)
14
- end
15
- end