liquid 4.0.3 → 5.1.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 +54 -0
- data/README.md +6 -0
- data/lib/liquid/block.rb +31 -14
- data/lib/liquid/block_body.rb +166 -54
- data/lib/liquid/condition.rb +41 -20
- data/lib/liquid/context.rb +107 -52
- data/lib/liquid/document.rb +47 -9
- data/lib/liquid/drop.rb +4 -2
- data/lib/liquid/errors.rb +20 -18
- data/lib/liquid/expression.rb +29 -34
- data/lib/liquid/extensions.rb +2 -0
- data/lib/liquid/file_system.rb +6 -4
- data/lib/liquid/forloop_drop.rb +11 -4
- data/lib/liquid/i18n.rb +5 -3
- data/lib/liquid/interrupts.rb +3 -1
- data/lib/liquid/lexer.rb +30 -23
- data/lib/liquid/locales/en.yml +3 -1
- data/lib/liquid/parse_context.rb +20 -4
- data/lib/liquid/parse_tree_visitor.rb +2 -2
- data/lib/liquid/parser.rb +30 -18
- data/lib/liquid/parser_switching.rb +17 -3
- data/lib/liquid/partial_cache.rb +24 -0
- data/lib/liquid/profiler/hooks.rb +26 -14
- data/lib/liquid/profiler.rb +67 -86
- data/lib/liquid/range_lookup.rb +13 -3
- data/lib/liquid/register.rb +6 -0
- data/lib/liquid/resource_limits.rb +47 -8
- data/lib/liquid/standardfilters.rb +95 -46
- data/lib/liquid/static_registers.rb +44 -0
- data/lib/liquid/strainer_factory.rb +36 -0
- data/lib/liquid/strainer_template.rb +53 -0
- data/lib/liquid/tablerowloop_drop.rb +6 -4
- data/lib/liquid/tag/disableable.rb +22 -0
- data/lib/liquid/tag/disabler.rb +21 -0
- data/lib/liquid/tag.rb +28 -6
- data/lib/liquid/tags/assign.rb +24 -10
- data/lib/liquid/tags/break.rb +8 -3
- data/lib/liquid/tags/capture.rb +11 -8
- data/lib/liquid/tags/case.rb +40 -27
- data/lib/liquid/tags/comment.rb +5 -3
- data/lib/liquid/tags/continue.rb +8 -3
- data/lib/liquid/tags/cycle.rb +25 -14
- data/lib/liquid/tags/decrement.rb +6 -3
- data/lib/liquid/tags/echo.rb +34 -0
- data/lib/liquid/tags/for.rb +68 -44
- data/lib/liquid/tags/if.rb +39 -23
- data/lib/liquid/tags/ifchanged.rb +11 -10
- data/lib/liquid/tags/include.rb +34 -47
- data/lib/liquid/tags/increment.rb +7 -3
- data/lib/liquid/tags/raw.rb +14 -11
- data/lib/liquid/tags/render.rb +84 -0
- data/lib/liquid/tags/table_row.rb +23 -19
- data/lib/liquid/tags/unless.rb +23 -15
- data/lib/liquid/template.rb +53 -72
- data/lib/liquid/template_factory.rb +9 -0
- data/lib/liquid/tokenizer.rb +18 -10
- data/lib/liquid/usage.rb +8 -0
- data/lib/liquid/utils.rb +13 -3
- data/lib/liquid/variable.rb +46 -41
- data/lib/liquid/variable_lookup.rb +11 -6
- data/lib/liquid/version.rb +2 -1
- data/lib/liquid.rb +17 -5
- data/test/integration/assign_test.rb +74 -5
- data/test/integration/blank_test.rb +11 -8
- data/test/integration/block_test.rb +47 -1
- data/test/integration/capture_test.rb +18 -10
- data/test/integration/context_test.rb +609 -5
- data/test/integration/document_test.rb +4 -2
- data/test/integration/drop_test.rb +67 -83
- data/test/integration/error_handling_test.rb +73 -61
- data/test/integration/expression_test.rb +46 -0
- data/test/integration/filter_test.rb +53 -42
- data/test/integration/hash_ordering_test.rb +5 -3
- data/test/integration/output_test.rb +26 -24
- data/test/integration/parsing_quirks_test.rb +19 -7
- data/test/integration/{render_profiling_test.rb → profiler_test.rb} +84 -25
- data/test/integration/security_test.rb +30 -21
- data/test/integration/standard_filter_test.rb +385 -281
- data/test/integration/tag/disableable_test.rb +59 -0
- data/test/integration/tag_test.rb +45 -0
- data/test/integration/tags/break_tag_test.rb +4 -2
- data/test/integration/tags/continue_tag_test.rb +4 -2
- data/test/integration/tags/echo_test.rb +13 -0
- data/test/integration/tags/for_tag_test.rb +107 -51
- data/test/integration/tags/if_else_tag_test.rb +5 -3
- data/test/integration/tags/include_tag_test.rb +70 -54
- data/test/integration/tags/increment_tag_test.rb +4 -2
- data/test/integration/tags/liquid_tag_test.rb +116 -0
- data/test/integration/tags/raw_tag_test.rb +14 -11
- data/test/integration/tags/render_tag_test.rb +213 -0
- data/test/integration/tags/standard_tag_test.rb +38 -31
- data/test/integration/tags/statements_test.rb +23 -21
- data/test/integration/tags/table_row_test.rb +2 -0
- data/test/integration/tags/unless_else_tag_test.rb +4 -2
- data/test/integration/template_test.rb +132 -124
- data/test/integration/trim_mode_test.rb +78 -44
- data/test/integration/variable_test.rb +74 -32
- data/test/test_helper.rb +113 -22
- data/test/unit/block_unit_test.rb +19 -24
- data/test/unit/condition_unit_test.rb +79 -77
- data/test/unit/file_system_unit_test.rb +6 -4
- data/test/unit/i18n_unit_test.rb +7 -5
- data/test/unit/lexer_unit_test.rb +11 -9
- data/test/{integration → unit}/parse_tree_visitor_test.rb +16 -2
- data/test/unit/parser_unit_test.rb +37 -35
- data/test/unit/partial_cache_unit_test.rb +128 -0
- data/test/unit/regexp_unit_test.rb +17 -15
- data/test/unit/static_registers_unit_test.rb +156 -0
- data/test/unit/strainer_factory_unit_test.rb +100 -0
- data/test/unit/strainer_template_unit_test.rb +82 -0
- data/test/unit/tag_unit_test.rb +5 -3
- data/test/unit/tags/case_tag_unit_test.rb +3 -1
- data/test/unit/tags/for_tag_unit_test.rb +4 -2
- data/test/unit/tags/if_tag_unit_test.rb +3 -1
- data/test/unit/template_factory_unit_test.rb +12 -0
- data/test/unit/template_unit_test.rb +19 -10
- data/test/unit/tokenizer_unit_test.rb +26 -19
- data/test/unit/variable_unit_test.rb +51 -49
- metadata +76 -50
- data/lib/liquid/strainer.rb +0 -66
- data/lib/liquid/truffle.rb +0 -5
- data/test/truffle/truffle_test.rb +0 -9
- data/test/unit/context_unit_test.rb +0 -489
- data/test/unit/strainer_unit_test.rb +0 -164
@@ -1,4 +1,5 @@
|
|
1
1
|
# encoding: utf-8
|
2
|
+
# frozen_string_literal: true
|
2
3
|
|
3
4
|
require 'test_helper'
|
4
5
|
|
@@ -17,7 +18,7 @@ class TestThing
|
|
17
18
|
"woot: #{@foo}"
|
18
19
|
end
|
19
20
|
|
20
|
-
def [](
|
21
|
+
def [](_whatever)
|
21
22
|
to_s
|
22
23
|
end
|
23
24
|
|
@@ -37,7 +38,7 @@ class TestEnumerable < Liquid::Drop
|
|
37
38
|
include Enumerable
|
38
39
|
|
39
40
|
def each(&block)
|
40
|
-
[
|
41
|
+
[{ "foo" => 1, "bar" => 2 }, { "foo" => 2, "bar" => 1 }, { "foo" => 3, "bar" => 3 }].each(&block)
|
41
42
|
end
|
42
43
|
end
|
43
44
|
|
@@ -59,34 +60,34 @@ class StandardFiltersTest < Minitest::Test
|
|
59
60
|
end
|
60
61
|
|
61
62
|
def test_size
|
62
|
-
assert_equal
|
63
|
-
assert_equal
|
64
|
-
assert_equal
|
63
|
+
assert_equal(3, @filters.size([1, 2, 3]))
|
64
|
+
assert_equal(0, @filters.size([]))
|
65
|
+
assert_equal(0, @filters.size(nil))
|
65
66
|
end
|
66
67
|
|
67
68
|
def test_downcase
|
68
|
-
assert_equal
|
69
|
-
assert_equal
|
69
|
+
assert_equal('testing', @filters.downcase("Testing"))
|
70
|
+
assert_equal('', @filters.downcase(nil))
|
70
71
|
end
|
71
72
|
|
72
73
|
def test_upcase
|
73
|
-
assert_equal
|
74
|
-
assert_equal
|
74
|
+
assert_equal('TESTING', @filters.upcase("Testing"))
|
75
|
+
assert_equal('', @filters.upcase(nil))
|
75
76
|
end
|
76
77
|
|
77
78
|
def test_slice
|
78
|
-
assert_equal
|
79
|
-
assert_equal
|
80
|
-
assert_equal
|
81
|
-
assert_equal
|
82
|
-
assert_equal
|
83
|
-
assert_equal
|
84
|
-
assert_equal
|
85
|
-
assert_equal
|
86
|
-
assert_equal
|
87
|
-
assert_equal
|
88
|
-
assert_equal
|
89
|
-
assert_equal
|
79
|
+
assert_equal('oob', @filters.slice('foobar', 1, 3))
|
80
|
+
assert_equal('oobar', @filters.slice('foobar', 1, 1000))
|
81
|
+
assert_equal('', @filters.slice('foobar', 1, 0))
|
82
|
+
assert_equal('o', @filters.slice('foobar', 1, 1))
|
83
|
+
assert_equal('bar', @filters.slice('foobar', 3, 3))
|
84
|
+
assert_equal('ar', @filters.slice('foobar', -2, 2))
|
85
|
+
assert_equal('ar', @filters.slice('foobar', -2, 1000))
|
86
|
+
assert_equal('r', @filters.slice('foobar', -1))
|
87
|
+
assert_equal('', @filters.slice(nil, 0))
|
88
|
+
assert_equal('', @filters.slice('foobar', 100, 10))
|
89
|
+
assert_equal('', @filters.slice('foobar', -100, 10))
|
90
|
+
assert_equal('oob', @filters.slice('foobar', '1', '3'))
|
90
91
|
assert_raises(Liquid::ArgumentError) do
|
91
92
|
@filters.slice('foobar', nil)
|
92
93
|
end
|
@@ -97,155 +98,199 @@ class StandardFiltersTest < Minitest::Test
|
|
97
98
|
|
98
99
|
def test_slice_on_arrays
|
99
100
|
input = 'foobar'.split(//)
|
100
|
-
assert_equal
|
101
|
-
assert_equal
|
102
|
-
assert_equal
|
103
|
-
assert_equal
|
104
|
-
assert_equal
|
105
|
-
assert_equal
|
106
|
-
assert_equal
|
107
|
-
assert_equal
|
108
|
-
assert_equal
|
109
|
-
assert_equal
|
101
|
+
assert_equal(%w(o o b), @filters.slice(input, 1, 3))
|
102
|
+
assert_equal(%w(o o b a r), @filters.slice(input, 1, 1000))
|
103
|
+
assert_equal(%w(), @filters.slice(input, 1, 0))
|
104
|
+
assert_equal(%w(o), @filters.slice(input, 1, 1))
|
105
|
+
assert_equal(%w(b a r), @filters.slice(input, 3, 3))
|
106
|
+
assert_equal(%w(a r), @filters.slice(input, -2, 2))
|
107
|
+
assert_equal(%w(a r), @filters.slice(input, -2, 1000))
|
108
|
+
assert_equal(%w(r), @filters.slice(input, -1))
|
109
|
+
assert_equal(%w(), @filters.slice(input, 100, 10))
|
110
|
+
assert_equal(%w(), @filters.slice(input, -100, 10))
|
110
111
|
end
|
111
112
|
|
112
113
|
def test_truncate
|
113
|
-
assert_equal
|
114
|
-
assert_equal
|
115
|
-
assert_equal
|
116
|
-
assert_equal
|
117
|
-
assert_equal
|
118
|
-
assert_equal
|
114
|
+
assert_equal('1234...', @filters.truncate('1234567890', 7))
|
115
|
+
assert_equal('1234567890', @filters.truncate('1234567890', 20))
|
116
|
+
assert_equal('...', @filters.truncate('1234567890', 0))
|
117
|
+
assert_equal('1234567890', @filters.truncate('1234567890'))
|
118
|
+
assert_equal("测试...", @filters.truncate("测试测试测试测试", 5))
|
119
|
+
assert_equal('12341', @filters.truncate("1234567890", 5, 1))
|
119
120
|
end
|
120
121
|
|
121
122
|
def test_split
|
122
|
-
assert_equal
|
123
|
-
assert_equal
|
124
|
-
assert_equal
|
125
|
-
assert_equal
|
126
|
-
assert_equal
|
123
|
+
assert_equal(['12', '34'], @filters.split('12~34', '~'))
|
124
|
+
assert_equal(['A? ', ' ,Z'], @filters.split('A? ~ ~ ~ ,Z', '~ ~ ~'))
|
125
|
+
assert_equal(['A?Z'], @filters.split('A?Z', '~'))
|
126
|
+
assert_equal([], @filters.split(nil, ' '))
|
127
|
+
assert_equal(['A', 'Z'], @filters.split('A1Z', 1))
|
127
128
|
end
|
128
129
|
|
129
130
|
def test_escape
|
130
|
-
assert_equal
|
131
|
-
assert_equal
|
132
|
-
assert_equal
|
133
|
-
assert_nil
|
131
|
+
assert_equal('<strong>', @filters.escape('<strong>'))
|
132
|
+
assert_equal('1', @filters.escape(1))
|
133
|
+
assert_equal('2001-02-03', @filters.escape(Date.new(2001, 2, 3)))
|
134
|
+
assert_nil(@filters.escape(nil))
|
134
135
|
end
|
135
136
|
|
136
137
|
def test_h
|
137
|
-
assert_equal
|
138
|
-
assert_equal
|
139
|
-
assert_equal
|
140
|
-
assert_nil
|
138
|
+
assert_equal('<strong>', @filters.h('<strong>'))
|
139
|
+
assert_equal('1', @filters.h(1))
|
140
|
+
assert_equal('2001-02-03', @filters.h(Date.new(2001, 2, 3)))
|
141
|
+
assert_nil(@filters.h(nil))
|
141
142
|
end
|
142
143
|
|
143
144
|
def test_escape_once
|
144
|
-
assert_equal
|
145
|
+
assert_equal('<strong>Hulk</strong>', @filters.escape_once('<strong>Hulk</strong>'))
|
146
|
+
end
|
147
|
+
|
148
|
+
def test_base64_encode
|
149
|
+
assert_equal('b25lIHR3byB0aHJlZQ==', @filters.base64_encode('one two three'))
|
150
|
+
assert_equal('', @filters.base64_encode(nil))
|
151
|
+
end
|
152
|
+
|
153
|
+
def test_base64_decode
|
154
|
+
assert_equal('one two three', @filters.base64_decode('b25lIHR3byB0aHJlZQ=='))
|
155
|
+
|
156
|
+
exception = assert_raises(Liquid::ArgumentError) do
|
157
|
+
@filters.base64_decode("invalidbase64")
|
158
|
+
end
|
159
|
+
|
160
|
+
assert_equal('Liquid error: invalid base64 provided to base64_decode', exception.message)
|
161
|
+
end
|
162
|
+
|
163
|
+
def test_base64_url_safe_encode
|
164
|
+
assert_equal(
|
165
|
+
'YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXogQUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVogMTIzNDU2Nzg5MCAhQCMkJV4mKigpLT1fKy8_Ljo7W117fVx8',
|
166
|
+
@filters.base64_url_safe_encode('abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ 1234567890 !@#$%^&*()-=_+/?.:;[]{}\|')
|
167
|
+
)
|
168
|
+
assert_equal('', @filters.base64_url_safe_encode(nil))
|
169
|
+
end
|
170
|
+
|
171
|
+
def test_base64_url_safe_decode
|
172
|
+
assert_equal(
|
173
|
+
'abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ 1234567890 !@#$%^&*()-=_+/?.:;[]{}\|',
|
174
|
+
@filters.base64_url_safe_decode('YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXogQUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVogMTIzNDU2Nzg5MCAhQCMkJV4mKigpLT1fKy8_Ljo7W117fVx8')
|
175
|
+
)
|
176
|
+
exception = assert_raises(Liquid::ArgumentError) do
|
177
|
+
@filters.base64_url_safe_decode("invalidbase64")
|
178
|
+
end
|
179
|
+
assert_equal('Liquid error: invalid base64 provided to base64_url_safe_decode', exception.message)
|
145
180
|
end
|
146
181
|
|
147
182
|
def test_url_encode
|
148
|
-
assert_equal
|
149
|
-
assert_equal
|
150
|
-
assert_equal
|
151
|
-
assert_nil
|
183
|
+
assert_equal('foo%2B1%40example.com', @filters.url_encode('foo+1@example.com'))
|
184
|
+
assert_equal('1', @filters.url_encode(1))
|
185
|
+
assert_equal('2001-02-03', @filters.url_encode(Date.new(2001, 2, 3)))
|
186
|
+
assert_nil(@filters.url_encode(nil))
|
152
187
|
end
|
153
188
|
|
154
189
|
def test_url_decode
|
155
|
-
assert_equal
|
156
|
-
assert_equal
|
157
|
-
assert_equal
|
158
|
-
assert_equal
|
159
|
-
assert_equal
|
160
|
-
assert_nil
|
161
|
-
exception = assert_raises
|
190
|
+
assert_equal('foo bar', @filters.url_decode('foo+bar'))
|
191
|
+
assert_equal('foo bar', @filters.url_decode('foo%20bar'))
|
192
|
+
assert_equal('foo+1@example.com', @filters.url_decode('foo%2B1%40example.com'))
|
193
|
+
assert_equal('1', @filters.url_decode(1))
|
194
|
+
assert_equal('2001-02-03', @filters.url_decode(Date.new(2001, 2, 3)))
|
195
|
+
assert_nil(@filters.url_decode(nil))
|
196
|
+
exception = assert_raises(Liquid::ArgumentError) do
|
162
197
|
@filters.url_decode('%ff')
|
163
198
|
end
|
164
|
-
assert_equal
|
199
|
+
assert_equal('Liquid error: invalid byte sequence in UTF-8', exception.message)
|
165
200
|
end
|
166
201
|
|
167
202
|
def test_truncatewords
|
168
|
-
assert_equal
|
169
|
-
assert_equal
|
170
|
-
assert_equal
|
171
|
-
assert_equal
|
172
|
-
|
173
|
-
|
203
|
+
assert_equal('one two three', @filters.truncatewords('one two three', 4))
|
204
|
+
assert_equal('one two...', @filters.truncatewords('one two three', 2))
|
205
|
+
assert_equal('one two three', @filters.truncatewords('one two three'))
|
206
|
+
assert_equal(
|
207
|
+
'Two small (13” x 5.5” x 10” high) baskets fit inside one large basket (13”...',
|
208
|
+
@filters.truncatewords('Two small (13” x 5.5” x 10” high) baskets fit inside one large basket (13” x 16” x 10.5” high) with cover.', 15)
|
209
|
+
)
|
210
|
+
assert_equal("测试测试测试测试", @filters.truncatewords('测试测试测试测试', 5))
|
211
|
+
assert_equal('one two1', @filters.truncatewords("one two three", 2, 1))
|
212
|
+
assert_equal('one two three...', @filters.truncatewords("one two\tthree\nfour", 3))
|
213
|
+
assert_equal('one two...', @filters.truncatewords("one two three four", 2))
|
214
|
+
assert_equal('one...', @filters.truncatewords("one two three four", 0))
|
215
|
+
exception = assert_raises(Liquid::ArgumentError) do
|
216
|
+
@filters.truncatewords("one two three four", 1 << 31)
|
217
|
+
end
|
218
|
+
assert_equal("Liquid error: integer #{1 << 31} too big for truncatewords", exception.message)
|
174
219
|
end
|
175
220
|
|
176
221
|
def test_strip_html
|
177
|
-
assert_equal
|
178
|
-
assert_equal
|
179
|
-
assert_equal
|
180
|
-
assert_equal
|
181
|
-
assert_equal
|
182
|
-
assert_equal
|
183
|
-
assert_equal
|
222
|
+
assert_equal('test', @filters.strip_html("<div>test</div>"))
|
223
|
+
assert_equal('test', @filters.strip_html("<div id='test'>test</div>"))
|
224
|
+
assert_equal('', @filters.strip_html("<script type='text/javascript'>document.write('some stuff');</script>"))
|
225
|
+
assert_equal('', @filters.strip_html("<style type='text/css'>foo bar</style>"))
|
226
|
+
assert_equal('test', @filters.strip_html("<div\nclass='multiline'>test</div>"))
|
227
|
+
assert_equal('test', @filters.strip_html("<!-- foo bar \n test -->test"))
|
228
|
+
assert_equal('', @filters.strip_html(nil))
|
184
229
|
|
185
230
|
# Quirk of the existing implementation
|
186
|
-
assert_equal
|
231
|
+
assert_equal('foo;', @filters.strip_html("<<<script </script>script>foo;</script>"))
|
187
232
|
end
|
188
233
|
|
189
234
|
def test_join
|
190
|
-
assert_equal
|
191
|
-
assert_equal
|
192
|
-
assert_equal
|
235
|
+
assert_equal('1 2 3 4', @filters.join([1, 2, 3, 4]))
|
236
|
+
assert_equal('1 - 2 - 3 - 4', @filters.join([1, 2, 3, 4], ' - '))
|
237
|
+
assert_equal('1121314', @filters.join([1, 2, 3, 4], 1))
|
193
238
|
end
|
194
239
|
|
195
240
|
def test_sort
|
196
|
-
assert_equal
|
197
|
-
assert_equal
|
241
|
+
assert_equal([1, 2, 3, 4], @filters.sort([4, 3, 2, 1]))
|
242
|
+
assert_equal([{ "a" => 1 }, { "a" => 2 }, { "a" => 3 }, { "a" => 4 }], @filters.sort([{ "a" => 4 }, { "a" => 3 }, { "a" => 1 }, { "a" => 2 }], "a"))
|
198
243
|
end
|
199
244
|
|
200
245
|
def test_sort_with_nils
|
201
|
-
assert_equal
|
202
|
-
assert_equal
|
246
|
+
assert_equal([1, 2, 3, 4, nil], @filters.sort([nil, 4, 3, 2, 1]))
|
247
|
+
assert_equal([{ "a" => 1 }, { "a" => 2 }, { "a" => 3 }, { "a" => 4 }, {}], @filters.sort([{ "a" => 4 }, { "a" => 3 }, {}, { "a" => 1 }, { "a" => 2 }], "a"))
|
203
248
|
end
|
204
249
|
|
205
250
|
def test_sort_when_property_is_sometimes_missing_puts_nils_last
|
206
|
-
input
|
251
|
+
input = [
|
207
252
|
{ "price" => 4, "handle" => "alpha" },
|
208
253
|
{ "handle" => "beta" },
|
209
254
|
{ "price" => 1, "handle" => "gamma" },
|
210
255
|
{ "handle" => "delta" },
|
211
|
-
{ "price" => 2, "handle" => "epsilon" }
|
256
|
+
{ "price" => 2, "handle" => "epsilon" },
|
212
257
|
]
|
213
258
|
expectation = [
|
214
259
|
{ "price" => 1, "handle" => "gamma" },
|
215
260
|
{ "price" => 2, "handle" => "epsilon" },
|
216
261
|
{ "price" => 4, "handle" => "alpha" },
|
217
262
|
{ "handle" => "delta" },
|
218
|
-
{ "handle" => "beta" }
|
263
|
+
{ "handle" => "beta" },
|
219
264
|
]
|
220
|
-
assert_equal
|
265
|
+
assert_equal(expectation, @filters.sort(input, "price"))
|
221
266
|
end
|
222
267
|
|
223
268
|
def test_sort_natural
|
224
|
-
assert_equal
|
225
|
-
assert_equal
|
269
|
+
assert_equal(["a", "B", "c", "D"], @filters.sort_natural(["c", "D", "a", "B"]))
|
270
|
+
assert_equal([{ "a" => "a" }, { "a" => "B" }, { "a" => "c" }, { "a" => "D" }], @filters.sort_natural([{ "a" => "D" }, { "a" => "c" }, { "a" => "a" }, { "a" => "B" }], "a"))
|
226
271
|
end
|
227
272
|
|
228
273
|
def test_sort_natural_with_nils
|
229
|
-
assert_equal
|
230
|
-
assert_equal
|
274
|
+
assert_equal(["a", "B", "c", "D", nil], @filters.sort_natural([nil, "c", "D", "a", "B"]))
|
275
|
+
assert_equal([{ "a" => "a" }, { "a" => "B" }, { "a" => "c" }, { "a" => "D" }, {}], @filters.sort_natural([{ "a" => "D" }, { "a" => "c" }, {}, { "a" => "a" }, { "a" => "B" }], "a"))
|
231
276
|
end
|
232
277
|
|
233
278
|
def test_sort_natural_when_property_is_sometimes_missing_puts_nils_last
|
234
|
-
input
|
279
|
+
input = [
|
235
280
|
{ "price" => "4", "handle" => "alpha" },
|
236
281
|
{ "handle" => "beta" },
|
237
282
|
{ "price" => "1", "handle" => "gamma" },
|
238
283
|
{ "handle" => "delta" },
|
239
|
-
{ "price" => 2, "handle" => "epsilon" }
|
284
|
+
{ "price" => 2, "handle" => "epsilon" },
|
240
285
|
]
|
241
286
|
expectation = [
|
242
287
|
{ "price" => "1", "handle" => "gamma" },
|
243
288
|
{ "price" => 2, "handle" => "epsilon" },
|
244
289
|
{ "price" => "4", "handle" => "alpha" },
|
245
290
|
{ "handle" => "delta" },
|
246
|
-
{ "handle" => "beta" }
|
291
|
+
{ "handle" => "beta" },
|
247
292
|
]
|
248
|
-
assert_equal
|
293
|
+
assert_equal(expectation, @filters.sort_natural(input, "price"))
|
249
294
|
end
|
250
295
|
|
251
296
|
def test_sort_natural_case_check
|
@@ -256,7 +301,7 @@ class StandardFiltersTest < Minitest::Test
|
|
256
301
|
{ "fake" => "t" },
|
257
302
|
{ "key" => "a" },
|
258
303
|
{ "key" => "b" },
|
259
|
-
{ "key" => "c" }
|
304
|
+
{ "key" => "c" },
|
260
305
|
]
|
261
306
|
expectation = [
|
262
307
|
{ "key" => "a" },
|
@@ -265,168 +310,168 @@ class StandardFiltersTest < Minitest::Test
|
|
265
310
|
{ "key" => "X" },
|
266
311
|
{ "key" => "Y" },
|
267
312
|
{ "key" => "Z" },
|
268
|
-
{ "fake" => "t" }
|
313
|
+
{ "fake" => "t" },
|
269
314
|
]
|
270
|
-
assert_equal
|
271
|
-
assert_equal
|
315
|
+
assert_equal(expectation, @filters.sort_natural(input, "key"))
|
316
|
+
assert_equal(["a", "b", "c", "X", "Y", "Z"], @filters.sort_natural(["X", "Y", "Z", "a", "b", "c"]))
|
272
317
|
end
|
273
318
|
|
274
319
|
def test_sort_empty_array
|
275
|
-
assert_equal
|
320
|
+
assert_equal([], @filters.sort([], "a"))
|
276
321
|
end
|
277
322
|
|
278
323
|
def test_sort_invalid_property
|
279
324
|
foo = [
|
280
325
|
[1],
|
281
326
|
[2],
|
282
|
-
[3]
|
327
|
+
[3],
|
283
328
|
]
|
284
329
|
|
285
|
-
assert_raises
|
330
|
+
assert_raises(Liquid::ArgumentError) do
|
286
331
|
@filters.sort(foo, "bar")
|
287
332
|
end
|
288
333
|
end
|
289
334
|
|
290
335
|
def test_sort_natural_empty_array
|
291
|
-
assert_equal
|
336
|
+
assert_equal([], @filters.sort_natural([], "a"))
|
292
337
|
end
|
293
338
|
|
294
339
|
def test_sort_natural_invalid_property
|
295
340
|
foo = [
|
296
341
|
[1],
|
297
342
|
[2],
|
298
|
-
[3]
|
343
|
+
[3],
|
299
344
|
]
|
300
345
|
|
301
|
-
assert_raises
|
346
|
+
assert_raises(Liquid::ArgumentError) do
|
302
347
|
@filters.sort_natural(foo, "bar")
|
303
348
|
end
|
304
349
|
end
|
305
350
|
|
306
351
|
def test_legacy_sort_hash
|
307
|
-
assert_equal
|
352
|
+
assert_equal([{ a: 1, b: 2 }], @filters.sort(a: 1, b: 2))
|
308
353
|
end
|
309
354
|
|
310
355
|
def test_numerical_vs_lexicographical_sort
|
311
|
-
assert_equal
|
312
|
-
assert_equal
|
313
|
-
assert_equal
|
314
|
-
assert_equal
|
356
|
+
assert_equal([2, 10], @filters.sort([10, 2]))
|
357
|
+
assert_equal([{ "a" => 2 }, { "a" => 10 }], @filters.sort([{ "a" => 10 }, { "a" => 2 }], "a"))
|
358
|
+
assert_equal(["10", "2"], @filters.sort(["10", "2"]))
|
359
|
+
assert_equal([{ "a" => "10" }, { "a" => "2" }], @filters.sort([{ "a" => "10" }, { "a" => "2" }], "a"))
|
315
360
|
end
|
316
361
|
|
317
362
|
def test_uniq
|
318
|
-
assert_equal
|
319
|
-
assert_equal
|
320
|
-
assert_equal
|
363
|
+
assert_equal(["foo"], @filters.uniq("foo"))
|
364
|
+
assert_equal([1, 3, 2, 4], @filters.uniq([1, 1, 3, 2, 3, 1, 4, 3, 2, 1]))
|
365
|
+
assert_equal([{ "a" => 1 }, { "a" => 3 }, { "a" => 2 }], @filters.uniq([{ "a" => 1 }, { "a" => 3 }, { "a" => 1 }, { "a" => 2 }], "a"))
|
321
366
|
testdrop = TestDrop.new
|
322
|
-
assert_equal
|
367
|
+
assert_equal([testdrop], @filters.uniq([testdrop, TestDrop.new], 'test'))
|
323
368
|
end
|
324
369
|
|
325
370
|
def test_uniq_empty_array
|
326
|
-
assert_equal
|
371
|
+
assert_equal([], @filters.uniq([], "a"))
|
327
372
|
end
|
328
373
|
|
329
374
|
def test_uniq_invalid_property
|
330
375
|
foo = [
|
331
376
|
[1],
|
332
377
|
[2],
|
333
|
-
[3]
|
378
|
+
[3],
|
334
379
|
]
|
335
380
|
|
336
|
-
assert_raises
|
381
|
+
assert_raises(Liquid::ArgumentError) do
|
337
382
|
@filters.uniq(foo, "bar")
|
338
383
|
end
|
339
384
|
end
|
340
385
|
|
341
386
|
def test_compact_empty_array
|
342
|
-
assert_equal
|
387
|
+
assert_equal([], @filters.compact([], "a"))
|
343
388
|
end
|
344
389
|
|
345
390
|
def test_compact_invalid_property
|
346
391
|
foo = [
|
347
392
|
[1],
|
348
393
|
[2],
|
349
|
-
[3]
|
394
|
+
[3],
|
350
395
|
]
|
351
396
|
|
352
|
-
assert_raises
|
397
|
+
assert_raises(Liquid::ArgumentError) do
|
353
398
|
@filters.compact(foo, "bar")
|
354
399
|
end
|
355
400
|
end
|
356
401
|
|
357
402
|
def test_reverse
|
358
|
-
assert_equal
|
403
|
+
assert_equal([4, 3, 2, 1], @filters.reverse([1, 2, 3, 4]))
|
359
404
|
end
|
360
405
|
|
361
406
|
def test_legacy_reverse_hash
|
362
|
-
assert_equal
|
407
|
+
assert_equal([{ a: 1, b: 2 }], @filters.reverse(a: 1, b: 2))
|
363
408
|
end
|
364
409
|
|
365
410
|
def test_map
|
366
|
-
assert_equal
|
367
|
-
assert_template_result
|
368
|
-
'ary' => [{ 'foo' => { 'bar' => 'a' } }, { 'foo' => { 'bar' => 'b' } }, { 'foo' => { 'bar' => 'c' } }]
|
411
|
+
assert_equal([1, 2, 3, 4], @filters.map([{ "a" => 1 }, { "a" => 2 }, { "a" => 3 }, { "a" => 4 }], 'a'))
|
412
|
+
assert_template_result('abc', "{{ ary | map:'foo' | map:'bar' }}",
|
413
|
+
'ary' => [{ 'foo' => { 'bar' => 'a' } }, { 'foo' => { 'bar' => 'b' } }, { 'foo' => { 'bar' => 'c' } }])
|
369
414
|
end
|
370
415
|
|
371
416
|
def test_map_doesnt_call_arbitrary_stuff
|
372
|
-
assert_template_result
|
373
|
-
assert_template_result
|
417
|
+
assert_template_result("", '{{ "foo" | map: "__id__" }}')
|
418
|
+
assert_template_result("", '{{ "foo" | map: "inspect" }}')
|
374
419
|
end
|
375
420
|
|
376
421
|
def test_map_calls_to_liquid
|
377
422
|
t = TestThing.new
|
378
|
-
assert_template_result
|
423
|
+
assert_template_result("woot: 1", '{{ foo | map: "whatever" }}', "foo" => [t])
|
379
424
|
end
|
380
425
|
|
381
426
|
def test_map_on_hashes
|
382
|
-
assert_template_result
|
383
|
-
"thing" => { "foo" => [
|
427
|
+
assert_template_result("4217", '{{ thing | map: "foo" | map: "bar" }}',
|
428
|
+
"thing" => { "foo" => [{ "bar" => 42 }, { "bar" => 17 }] })
|
384
429
|
end
|
385
430
|
|
386
431
|
def test_legacy_map_on_hashes_with_dynamic_key
|
387
432
|
template = "{% assign key = 'foo' %}{{ thing | map: key | map: 'bar' }}"
|
388
|
-
hash
|
389
|
-
assert_template_result
|
433
|
+
hash = { "foo" => { "bar" => 42 } }
|
434
|
+
assert_template_result("42", template, "thing" => hash)
|
390
435
|
end
|
391
436
|
|
392
437
|
def test_sort_calls_to_liquid
|
393
438
|
t = TestThing.new
|
394
439
|
Liquid::Template.parse('{{ foo | sort: "whatever" }}').render("foo" => [t])
|
395
|
-
assert
|
440
|
+
assert(t.foo > 0)
|
396
441
|
end
|
397
442
|
|
398
443
|
def test_map_over_proc
|
399
|
-
drop
|
400
|
-
p
|
444
|
+
drop = TestDrop.new
|
445
|
+
p = proc { drop }
|
401
446
|
templ = '{{ procs | map: "test" }}'
|
402
|
-
assert_template_result
|
447
|
+
assert_template_result("testfoo", templ, "procs" => [p])
|
403
448
|
end
|
404
449
|
|
405
450
|
def test_map_over_drops_returning_procs
|
406
451
|
drops = [
|
407
452
|
{
|
408
|
-
"proc" => ->{ "foo" },
|
453
|
+
"proc" => -> { "foo" },
|
409
454
|
},
|
410
455
|
{
|
411
|
-
"proc" => ->{ "bar" },
|
456
|
+
"proc" => -> { "bar" },
|
412
457
|
},
|
413
458
|
]
|
414
459
|
templ = '{{ drops | map: "proc" }}'
|
415
|
-
assert_template_result
|
460
|
+
assert_template_result("foobar", templ, "drops" => drops)
|
416
461
|
end
|
417
462
|
|
418
463
|
def test_map_works_on_enumerables
|
419
|
-
assert_template_result
|
464
|
+
assert_template_result("123", '{{ foo | map: "foo" }}', "foo" => TestEnumerable.new)
|
420
465
|
end
|
421
466
|
|
422
467
|
def test_map_returns_empty_on_2d_input_array
|
423
468
|
foo = [
|
424
469
|
[1],
|
425
470
|
[2],
|
426
|
-
[3]
|
471
|
+
[3],
|
427
472
|
]
|
428
473
|
|
429
|
-
assert_raises
|
474
|
+
assert_raises(Liquid::ArgumentError) do
|
430
475
|
@filters.map(foo, "bar")
|
431
476
|
end
|
432
477
|
end
|
@@ -435,221 +480,222 @@ class StandardFiltersTest < Minitest::Test
|
|
435
480
|
foo = [
|
436
481
|
[1],
|
437
482
|
[2],
|
438
|
-
[3]
|
483
|
+
[3],
|
439
484
|
]
|
440
|
-
assert_raises
|
485
|
+
assert_raises(Liquid::ArgumentError) do
|
441
486
|
@filters.map(foo, nil)
|
442
487
|
end
|
443
488
|
end
|
444
489
|
|
445
490
|
def test_sort_works_on_enumerables
|
446
|
-
assert_template_result
|
491
|
+
assert_template_result("213", '{{ foo | sort: "bar" | map: "foo" }}', "foo" => TestEnumerable.new)
|
447
492
|
end
|
448
493
|
|
449
494
|
def test_first_and_last_call_to_liquid
|
450
|
-
assert_template_result
|
451
|
-
assert_template_result
|
495
|
+
assert_template_result('foobar', '{{ foo | first }}', 'foo' => [ThingWithToLiquid.new])
|
496
|
+
assert_template_result('foobar', '{{ foo | last }}', 'foo' => [ThingWithToLiquid.new])
|
452
497
|
end
|
453
498
|
|
454
499
|
def test_truncate_calls_to_liquid
|
455
|
-
assert_template_result
|
500
|
+
assert_template_result("wo...", '{{ foo | truncate: 5 }}', "foo" => TestThing.new)
|
456
501
|
end
|
457
502
|
|
458
503
|
def test_date
|
459
|
-
assert_equal
|
460
|
-
assert_equal
|
461
|
-
assert_equal
|
504
|
+
assert_equal('May', @filters.date(Time.parse("2006-05-05 10:00:00"), "%B"))
|
505
|
+
assert_equal('June', @filters.date(Time.parse("2006-06-05 10:00:00"), "%B"))
|
506
|
+
assert_equal('July', @filters.date(Time.parse("2006-07-05 10:00:00"), "%B"))
|
462
507
|
|
463
|
-
assert_equal
|
464
|
-
assert_equal
|
465
|
-
assert_equal
|
508
|
+
assert_equal('May', @filters.date("2006-05-05 10:00:00", "%B"))
|
509
|
+
assert_equal('June', @filters.date("2006-06-05 10:00:00", "%B"))
|
510
|
+
assert_equal('July', @filters.date("2006-07-05 10:00:00", "%B"))
|
466
511
|
|
467
|
-
assert_equal
|
468
|
-
assert_equal
|
469
|
-
assert_equal
|
470
|
-
assert_equal
|
512
|
+
assert_equal('2006-07-05 10:00:00', @filters.date("2006-07-05 10:00:00", ""))
|
513
|
+
assert_equal('2006-07-05 10:00:00', @filters.date("2006-07-05 10:00:00", ""))
|
514
|
+
assert_equal('2006-07-05 10:00:00', @filters.date("2006-07-05 10:00:00", ""))
|
515
|
+
assert_equal('2006-07-05 10:00:00', @filters.date("2006-07-05 10:00:00", nil))
|
471
516
|
|
472
|
-
assert_equal
|
517
|
+
assert_equal('07/05/2006', @filters.date("2006-07-05 10:00:00", "%m/%d/%Y"))
|
473
518
|
|
474
|
-
assert_equal
|
475
|
-
assert_equal
|
476
|
-
assert_equal
|
477
|
-
assert_equal
|
519
|
+
assert_equal("07/16/2004", @filters.date("Fri Jul 16 01:00:00 2004", "%m/%d/%Y"))
|
520
|
+
assert_equal(Date.today.year.to_s, @filters.date('now', '%Y'))
|
521
|
+
assert_equal(Date.today.year.to_s, @filters.date('today', '%Y'))
|
522
|
+
assert_equal(Date.today.year.to_s, @filters.date('Today', '%Y'))
|
478
523
|
|
479
|
-
assert_nil
|
524
|
+
assert_nil(@filters.date(nil, "%B"))
|
480
525
|
|
481
|
-
assert_equal
|
526
|
+
assert_equal('', @filters.date('', "%B"))
|
482
527
|
|
483
528
|
with_timezone("UTC") do
|
484
|
-
assert_equal
|
485
|
-
assert_equal
|
529
|
+
assert_equal("07/05/2006", @filters.date(1152098955, "%m/%d/%Y"))
|
530
|
+
assert_equal("07/05/2006", @filters.date("1152098955", "%m/%d/%Y"))
|
486
531
|
end
|
487
532
|
end
|
488
533
|
|
489
534
|
def test_first_last
|
490
|
-
assert_equal
|
491
|
-
assert_equal
|
492
|
-
assert_nil
|
493
|
-
assert_nil
|
535
|
+
assert_equal(1, @filters.first([1, 2, 3]))
|
536
|
+
assert_equal(3, @filters.last([1, 2, 3]))
|
537
|
+
assert_nil(@filters.first([]))
|
538
|
+
assert_nil(@filters.last([]))
|
494
539
|
end
|
495
540
|
|
496
541
|
def test_replace
|
497
|
-
assert_equal
|
498
|
-
assert_equal
|
499
|
-
assert_equal
|
500
|
-
assert_equal
|
501
|
-
assert_template_result
|
542
|
+
assert_equal('2 2 2 2', @filters.replace('1 1 1 1', '1', 2))
|
543
|
+
assert_equal('2 2 2 2', @filters.replace('1 1 1 1', 1, 2))
|
544
|
+
assert_equal('2 1 1 1', @filters.replace_first('1 1 1 1', '1', 2))
|
545
|
+
assert_equal('2 1 1 1', @filters.replace_first('1 1 1 1', 1, 2))
|
546
|
+
assert_template_result('2 1 1 1', "{{ '1 1 1 1' | replace_first: '1', 2 }}")
|
502
547
|
end
|
503
548
|
|
504
549
|
def test_remove
|
505
|
-
assert_equal
|
506
|
-
assert_equal
|
507
|
-
assert_equal
|
508
|
-
assert_equal
|
509
|
-
assert_template_result
|
550
|
+
assert_equal(' ', @filters.remove("a a a a", 'a'))
|
551
|
+
assert_equal(' ', @filters.remove("1 1 1 1", 1))
|
552
|
+
assert_equal('a a a', @filters.remove_first("a a a a", 'a '))
|
553
|
+
assert_equal(' 1 1 1', @filters.remove_first("1 1 1 1", 1))
|
554
|
+
assert_template_result('a a a', "{{ 'a a a a' | remove_first: 'a ' }}")
|
510
555
|
end
|
511
556
|
|
512
557
|
def test_pipes_in_string_arguments
|
513
|
-
assert_template_result
|
558
|
+
assert_template_result('foobar', "{{ 'foo|bar' | remove: '|' }}")
|
514
559
|
end
|
515
560
|
|
516
561
|
def test_strip
|
517
|
-
assert_template_result
|
518
|
-
assert_template_result
|
562
|
+
assert_template_result('ab c', "{{ source | strip }}", 'source' => " ab c ")
|
563
|
+
assert_template_result('ab c', "{{ source | strip }}", 'source' => " \tab c \n \t")
|
519
564
|
end
|
520
565
|
|
521
566
|
def test_lstrip
|
522
|
-
assert_template_result
|
523
|
-
assert_template_result
|
567
|
+
assert_template_result('ab c ', "{{ source | lstrip }}", 'source' => " ab c ")
|
568
|
+
assert_template_result("ab c \n \t", "{{ source | lstrip }}", 'source' => " \tab c \n \t")
|
524
569
|
end
|
525
570
|
|
526
571
|
def test_rstrip
|
527
|
-
assert_template_result
|
528
|
-
assert_template_result
|
572
|
+
assert_template_result(" ab c", "{{ source | rstrip }}", 'source' => " ab c ")
|
573
|
+
assert_template_result(" \tab c", "{{ source | rstrip }}", 'source' => " \tab c \n \t")
|
529
574
|
end
|
530
575
|
|
531
576
|
def test_strip_newlines
|
532
|
-
assert_template_result
|
533
|
-
assert_template_result
|
577
|
+
assert_template_result('abc', "{{ source | strip_newlines }}", 'source' => "a\nb\nc")
|
578
|
+
assert_template_result('abc', "{{ source | strip_newlines }}", 'source' => "a\r\nb\nc")
|
534
579
|
end
|
535
580
|
|
536
581
|
def test_newlines_to_br
|
537
|
-
assert_template_result
|
582
|
+
assert_template_result("a<br />\nb<br />\nc", "{{ source | newline_to_br }}", 'source' => "a\nb\nc")
|
583
|
+
assert_template_result("a<br />\nb<br />\nc", "{{ source | newline_to_br }}", 'source' => "a\r\nb\nc")
|
538
584
|
end
|
539
585
|
|
540
586
|
def test_plus
|
541
|
-
assert_template_result
|
542
|
-
assert_template_result
|
587
|
+
assert_template_result("2", "{{ 1 | plus:1 }}")
|
588
|
+
assert_template_result("2.0", "{{ '1' | plus:'1.0' }}")
|
543
589
|
|
544
|
-
assert_template_result
|
590
|
+
assert_template_result("5", "{{ price | plus:'2' }}", 'price' => NumberLikeThing.new(3))
|
545
591
|
end
|
546
592
|
|
547
593
|
def test_minus
|
548
|
-
assert_template_result
|
549
|
-
assert_template_result
|
594
|
+
assert_template_result("4", "{{ input | minus:operand }}", 'input' => 5, 'operand' => 1)
|
595
|
+
assert_template_result("2.3", "{{ '4.3' | minus:'2' }}")
|
550
596
|
|
551
|
-
assert_template_result
|
597
|
+
assert_template_result("5", "{{ price | minus:'2' }}", 'price' => NumberLikeThing.new(7))
|
552
598
|
end
|
553
599
|
|
554
600
|
def test_abs
|
555
|
-
assert_template_result
|
556
|
-
assert_template_result
|
557
|
-
assert_template_result
|
558
|
-
assert_template_result
|
559
|
-
assert_template_result
|
560
|
-
assert_template_result
|
561
|
-
assert_template_result
|
562
|
-
assert_template_result
|
563
|
-
assert_template_result
|
564
|
-
assert_template_result
|
601
|
+
assert_template_result("17", "{{ 17 | abs }}")
|
602
|
+
assert_template_result("17", "{{ -17 | abs }}")
|
603
|
+
assert_template_result("17", "{{ '17' | abs }}")
|
604
|
+
assert_template_result("17", "{{ '-17' | abs }}")
|
605
|
+
assert_template_result("0", "{{ 0 | abs }}")
|
606
|
+
assert_template_result("0", "{{ '0' | abs }}")
|
607
|
+
assert_template_result("17.42", "{{ 17.42 | abs }}")
|
608
|
+
assert_template_result("17.42", "{{ -17.42 | abs }}")
|
609
|
+
assert_template_result("17.42", "{{ '17.42' | abs }}")
|
610
|
+
assert_template_result("17.42", "{{ '-17.42' | abs }}")
|
565
611
|
end
|
566
612
|
|
567
613
|
def test_times
|
568
|
-
assert_template_result
|
569
|
-
assert_template_result
|
570
|
-
assert_template_result
|
571
|
-
assert_template_result
|
572
|
-
assert_template_result
|
573
|
-
assert_template_result
|
574
|
-
assert_template_result
|
614
|
+
assert_template_result("12", "{{ 3 | times:4 }}")
|
615
|
+
assert_template_result("0", "{{ 'foo' | times:4 }}")
|
616
|
+
assert_template_result("6", "{{ '2.1' | times:3 | replace: '.','-' | plus:0}}")
|
617
|
+
assert_template_result("7.25", "{{ 0.0725 | times:100 }}")
|
618
|
+
assert_template_result("-7.25", '{{ "-0.0725" | times:100 }}')
|
619
|
+
assert_template_result("7.25", '{{ "-0.0725" | times: -100 }}')
|
620
|
+
assert_template_result("4", "{{ price | times:2 }}", 'price' => NumberLikeThing.new(2))
|
575
621
|
end
|
576
622
|
|
577
623
|
def test_divided_by
|
578
|
-
assert_template_result
|
579
|
-
assert_template_result
|
624
|
+
assert_template_result("4", "{{ 12 | divided_by:3 }}")
|
625
|
+
assert_template_result("4", "{{ 14 | divided_by:3 }}")
|
580
626
|
|
581
|
-
assert_template_result
|
582
|
-
assert_equal
|
627
|
+
assert_template_result("5", "{{ 15 | divided_by:3 }}")
|
628
|
+
assert_equal("Liquid error: divided by 0", Template.parse("{{ 5 | divided_by:0 }}").render)
|
583
629
|
|
584
|
-
assert_template_result
|
630
|
+
assert_template_result("0.5", "{{ 2.0 | divided_by:4 }}")
|
585
631
|
assert_raises(Liquid::ZeroDivisionError) do
|
586
|
-
assert_template_result
|
632
|
+
assert_template_result("4", "{{ 1 | modulo: 0 }}")
|
587
633
|
end
|
588
634
|
|
589
|
-
assert_template_result
|
635
|
+
assert_template_result("5", "{{ price | divided_by:2 }}", 'price' => NumberLikeThing.new(10))
|
590
636
|
end
|
591
637
|
|
592
638
|
def test_modulo
|
593
|
-
assert_template_result
|
639
|
+
assert_template_result("1", "{{ 3 | modulo:2 }}")
|
594
640
|
assert_raises(Liquid::ZeroDivisionError) do
|
595
|
-
assert_template_result
|
641
|
+
assert_template_result("4", "{{ 1 | modulo: 0 }}")
|
596
642
|
end
|
597
643
|
|
598
|
-
assert_template_result
|
644
|
+
assert_template_result("1", "{{ price | modulo:2 }}", 'price' => NumberLikeThing.new(3))
|
599
645
|
end
|
600
646
|
|
601
647
|
def test_round
|
602
|
-
assert_template_result
|
603
|
-
assert_template_result
|
604
|
-
assert_template_result
|
648
|
+
assert_template_result("5", "{{ input | round }}", 'input' => 4.6)
|
649
|
+
assert_template_result("4", "{{ '4.3' | round }}")
|
650
|
+
assert_template_result("4.56", "{{ input | round: 2 }}", 'input' => 4.5612)
|
605
651
|
assert_raises(Liquid::FloatDomainError) do
|
606
|
-
assert_template_result
|
652
|
+
assert_template_result("4", "{{ 1.0 | divided_by: 0.0 | round }}")
|
607
653
|
end
|
608
654
|
|
609
|
-
assert_template_result
|
610
|
-
assert_template_result
|
655
|
+
assert_template_result("5", "{{ price | round }}", 'price' => NumberLikeThing.new(4.6))
|
656
|
+
assert_template_result("4", "{{ price | round }}", 'price' => NumberLikeThing.new(4.3))
|
611
657
|
end
|
612
658
|
|
613
659
|
def test_ceil
|
614
|
-
assert_template_result
|
615
|
-
assert_template_result
|
660
|
+
assert_template_result("5", "{{ input | ceil }}", 'input' => 4.6)
|
661
|
+
assert_template_result("5", "{{ '4.3' | ceil }}")
|
616
662
|
assert_raises(Liquid::FloatDomainError) do
|
617
|
-
assert_template_result
|
663
|
+
assert_template_result("4", "{{ 1.0 | divided_by: 0.0 | ceil }}")
|
618
664
|
end
|
619
665
|
|
620
|
-
assert_template_result
|
666
|
+
assert_template_result("5", "{{ price | ceil }}", 'price' => NumberLikeThing.new(4.6))
|
621
667
|
end
|
622
668
|
|
623
669
|
def test_floor
|
624
|
-
assert_template_result
|
625
|
-
assert_template_result
|
670
|
+
assert_template_result("4", "{{ input | floor }}", 'input' => 4.6)
|
671
|
+
assert_template_result("4", "{{ '4.3' | floor }}")
|
626
672
|
assert_raises(Liquid::FloatDomainError) do
|
627
|
-
assert_template_result
|
673
|
+
assert_template_result("4", "{{ 1.0 | divided_by: 0.0 | floor }}")
|
628
674
|
end
|
629
675
|
|
630
|
-
assert_template_result
|
676
|
+
assert_template_result("5", "{{ price | floor }}", 'price' => NumberLikeThing.new(5.4))
|
631
677
|
end
|
632
678
|
|
633
679
|
def test_at_most
|
634
|
-
assert_template_result
|
635
|
-
assert_template_result
|
636
|
-
assert_template_result
|
680
|
+
assert_template_result("4", "{{ 5 | at_most:4 }}")
|
681
|
+
assert_template_result("5", "{{ 5 | at_most:5 }}")
|
682
|
+
assert_template_result("5", "{{ 5 | at_most:6 }}")
|
637
683
|
|
638
|
-
assert_template_result
|
639
|
-
assert_template_result
|
640
|
-
assert_template_result
|
641
|
-
assert_template_result
|
684
|
+
assert_template_result("4.5", "{{ 4.5 | at_most:5 }}")
|
685
|
+
assert_template_result("5", "{{ width | at_most:5 }}", 'width' => NumberLikeThing.new(6))
|
686
|
+
assert_template_result("4", "{{ width | at_most:5 }}", 'width' => NumberLikeThing.new(4))
|
687
|
+
assert_template_result("4", "{{ 5 | at_most: width }}", 'width' => NumberLikeThing.new(4))
|
642
688
|
end
|
643
689
|
|
644
690
|
def test_at_least
|
645
|
-
assert_template_result
|
646
|
-
assert_template_result
|
647
|
-
assert_template_result
|
691
|
+
assert_template_result("5", "{{ 5 | at_least:4 }}")
|
692
|
+
assert_template_result("5", "{{ 5 | at_least:5 }}")
|
693
|
+
assert_template_result("6", "{{ 5 | at_least:6 }}")
|
648
694
|
|
649
|
-
assert_template_result
|
650
|
-
assert_template_result
|
651
|
-
assert_template_result
|
652
|
-
assert_template_result
|
695
|
+
assert_template_result("5", "{{ 4.5 | at_least:5 }}")
|
696
|
+
assert_template_result("6", "{{ width | at_least:5 }}", 'width' => NumberLikeThing.new(6))
|
697
|
+
assert_template_result("5", "{{ width | at_least:5 }}", 'width' => NumberLikeThing.new(4))
|
698
|
+
assert_template_result("6", "{{ 5 | at_least: width }}", 'width' => NumberLikeThing.new(6))
|
653
699
|
end
|
654
700
|
|
655
701
|
def test_append
|
@@ -659,9 +705,9 @@ class StandardFiltersTest < Minitest::Test
|
|
659
705
|
end
|
660
706
|
|
661
707
|
def test_concat
|
662
|
-
assert_equal
|
663
|
-
assert_equal
|
664
|
-
assert_equal
|
708
|
+
assert_equal([1, 2, 3, 4], @filters.concat([1, 2], [3, 4]))
|
709
|
+
assert_equal([1, 2, 'a'], @filters.concat([1, 2], ['a']))
|
710
|
+
assert_equal([1, 2, 10], @filters.concat([1, 2], [10]))
|
665
711
|
|
666
712
|
assert_raises(Liquid::ArgumentError, "concat filter requires an array argument") do
|
667
713
|
@filters.concat([1, 2], 10)
|
@@ -675,12 +721,27 @@ class StandardFiltersTest < Minitest::Test
|
|
675
721
|
end
|
676
722
|
|
677
723
|
def test_default
|
678
|
-
assert_equal
|
679
|
-
assert_equal
|
680
|
-
assert_equal
|
681
|
-
assert_equal
|
682
|
-
assert_equal
|
683
|
-
assert_equal
|
724
|
+
assert_equal("foo", @filters.default("foo", "bar"))
|
725
|
+
assert_equal("bar", @filters.default(nil, "bar"))
|
726
|
+
assert_equal("bar", @filters.default("", "bar"))
|
727
|
+
assert_equal("bar", @filters.default(false, "bar"))
|
728
|
+
assert_equal("bar", @filters.default([], "bar"))
|
729
|
+
assert_equal("bar", @filters.default({}, "bar"))
|
730
|
+
assert_template_result('bar', "{{ false | default: 'bar' }}")
|
731
|
+
assert_template_result('bar', "{{ drop | default: 'bar' }}", 'drop' => BooleanDrop.new(false))
|
732
|
+
assert_template_result('Yay', "{{ drop | default: 'bar' }}", 'drop' => BooleanDrop.new(true))
|
733
|
+
end
|
734
|
+
|
735
|
+
def test_default_handle_false
|
736
|
+
assert_equal("foo", @filters.default("foo", "bar", "allow_false" => true))
|
737
|
+
assert_equal("bar", @filters.default(nil, "bar", "allow_false" => true))
|
738
|
+
assert_equal("bar", @filters.default("", "bar", "allow_false" => true))
|
739
|
+
assert_equal(false, @filters.default(false, "bar", "allow_false" => true))
|
740
|
+
assert_equal("bar", @filters.default([], "bar", "allow_false" => true))
|
741
|
+
assert_equal("bar", @filters.default({}, "bar", "allow_false" => true))
|
742
|
+
assert_template_result('false', "{{ false | default: 'bar', allow_false: true }}")
|
743
|
+
assert_template_result('Nay', "{{ drop | default: 'bar', allow_false: true }}", 'drop' => BooleanDrop.new(false))
|
744
|
+
assert_template_result('Yay', "{{ drop | default: 'bar', allow_false: true }}", 'drop' => BooleanDrop.new(true))
|
684
745
|
end
|
685
746
|
|
686
747
|
def test_cannot_access_private_methods
|
@@ -697,16 +758,16 @@ class StandardFiltersTest < Minitest::Test
|
|
697
758
|
{ "handle" => "alpha", "ok" => true },
|
698
759
|
{ "handle" => "beta", "ok" => false },
|
699
760
|
{ "handle" => "gamma", "ok" => false },
|
700
|
-
{ "handle" => "delta", "ok" => true }
|
761
|
+
{ "handle" => "delta", "ok" => true },
|
701
762
|
]
|
702
763
|
|
703
764
|
expectation = [
|
704
765
|
{ "handle" => "alpha", "ok" => true },
|
705
|
-
{ "handle" => "delta", "ok" => true }
|
766
|
+
{ "handle" => "delta", "ok" => true },
|
706
767
|
]
|
707
768
|
|
708
|
-
assert_equal
|
709
|
-
assert_equal
|
769
|
+
assert_equal(expectation, @filters.where(input, "ok", true))
|
770
|
+
assert_equal(expectation, @filters.where(input, "ok"))
|
710
771
|
end
|
711
772
|
|
712
773
|
def test_where_no_key_set
|
@@ -714,21 +775,21 @@ class StandardFiltersTest < Minitest::Test
|
|
714
775
|
{ "handle" => "alpha", "ok" => true },
|
715
776
|
{ "handle" => "beta" },
|
716
777
|
{ "handle" => "gamma" },
|
717
|
-
{ "handle" => "delta", "ok" => true }
|
778
|
+
{ "handle" => "delta", "ok" => true },
|
718
779
|
]
|
719
780
|
|
720
781
|
expectation = [
|
721
782
|
{ "handle" => "alpha", "ok" => true },
|
722
|
-
{ "handle" => "delta", "ok" => true }
|
783
|
+
{ "handle" => "delta", "ok" => true },
|
723
784
|
]
|
724
785
|
|
725
|
-
assert_equal
|
726
|
-
assert_equal
|
786
|
+
assert_equal(expectation, @filters.where(input, "ok", true))
|
787
|
+
assert_equal(expectation, @filters.where(input, "ok"))
|
727
788
|
end
|
728
789
|
|
729
790
|
def test_where_non_array_map_input
|
730
|
-
assert_equal
|
731
|
-
assert_equal
|
791
|
+
assert_equal([{ "a" => "ok" }], @filters.where({ "a" => "ok" }, "a", "ok"))
|
792
|
+
assert_equal([], @filters.where({ "a" => "not ok" }, "a", "ok"))
|
732
793
|
end
|
733
794
|
|
734
795
|
def test_where_indexable_but_non_map_value
|
@@ -740,17 +801,60 @@ class StandardFiltersTest < Minitest::Test
|
|
740
801
|
input = [
|
741
802
|
{ "message" => "Bonjour!", "language" => "French" },
|
742
803
|
{ "message" => "Hello!", "language" => "English" },
|
743
|
-
{ "message" => "Hallo!", "language" => "German" }
|
804
|
+
{ "message" => "Hallo!", "language" => "German" },
|
744
805
|
]
|
745
806
|
|
746
|
-
assert_equal
|
747
|
-
assert_equal
|
748
|
-
assert_equal
|
807
|
+
assert_equal([{ "message" => "Bonjour!", "language" => "French" }], @filters.where(input, "language", "French"))
|
808
|
+
assert_equal([{ "message" => "Hallo!", "language" => "German" }], @filters.where(input, "language", "German"))
|
809
|
+
assert_equal([{ "message" => "Hello!", "language" => "English" }], @filters.where(input, "language", "English"))
|
749
810
|
end
|
750
811
|
|
751
812
|
def test_where_array_of_only_unindexable_values
|
752
|
-
assert_nil
|
753
|
-
assert_nil
|
813
|
+
assert_nil(@filters.where([nil], "ok", true))
|
814
|
+
assert_nil(@filters.where([nil], "ok"))
|
815
|
+
end
|
816
|
+
|
817
|
+
def test_all_filters_never_raise_non_liquid_exception
|
818
|
+
test_drop = TestDrop.new
|
819
|
+
test_drop.context = Context.new
|
820
|
+
test_enum = TestEnumerable.new
|
821
|
+
test_enum.context = Context.new
|
822
|
+
test_types = [
|
823
|
+
"foo",
|
824
|
+
123,
|
825
|
+
0,
|
826
|
+
0.0,
|
827
|
+
-1234.003030303,
|
828
|
+
-99999999,
|
829
|
+
1234.38383000383830003838300,
|
830
|
+
nil,
|
831
|
+
true,
|
832
|
+
false,
|
833
|
+
TestThing.new,
|
834
|
+
test_drop,
|
835
|
+
test_enum,
|
836
|
+
["foo", "bar"],
|
837
|
+
{ "foo" => "bar" },
|
838
|
+
{ foo: "bar" },
|
839
|
+
[{ "foo" => "bar" }, { "foo" => 123 }, { "foo" => nil }, { "foo" => true }, { "foo" => ["foo", "bar"] }],
|
840
|
+
{ 1 => "bar" },
|
841
|
+
["foo", 123, nil, true, false, Drop, ["foo"], { foo: "bar" }],
|
842
|
+
]
|
843
|
+
test_types.each do |first|
|
844
|
+
test_types.each do |other|
|
845
|
+
(@filters.methods - Object.methods).each do |method|
|
846
|
+
arg_count = @filters.method(method).arity
|
847
|
+
arg_count *= -1 if arg_count < 0
|
848
|
+
inputs = [first]
|
849
|
+
inputs << ([other] * (arg_count - 1)) if arg_count > 1
|
850
|
+
begin
|
851
|
+
@filters.send(method, *inputs)
|
852
|
+
rescue Liquid::ArgumentError, Liquid::ZeroDivisionError
|
853
|
+
nil
|
854
|
+
end
|
855
|
+
end
|
856
|
+
end
|
857
|
+
end
|
754
858
|
end
|
755
859
|
|
756
860
|
def test_where_no_target_value
|
@@ -758,16 +862,16 @@ class StandardFiltersTest < Minitest::Test
|
|
758
862
|
{ "foo" => false },
|
759
863
|
{ "foo" => true },
|
760
864
|
{ "foo" => "for sure" },
|
761
|
-
{ "bar" => true }
|
865
|
+
{ "bar" => true },
|
762
866
|
]
|
763
867
|
|
764
|
-
assert_equal
|
868
|
+
assert_equal([{ "foo" => true }, { "foo" => "for sure" }], @filters.where(input, "foo"))
|
765
869
|
end
|
766
870
|
|
767
871
|
private
|
768
872
|
|
769
873
|
def with_timezone(tz)
|
770
|
-
old_tz
|
874
|
+
old_tz = ENV['TZ']
|
771
875
|
ENV['TZ'] = tz
|
772
876
|
yield
|
773
877
|
ensure
|