liquid 3.0.0 → 4.0.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 +130 -62
- data/README.md +31 -0
- data/lib/liquid/block.rb +31 -124
- data/lib/liquid/block_body.rb +75 -59
- data/lib/liquid/condition.rb +23 -22
- data/lib/liquid/context.rb +51 -60
- data/lib/liquid/document.rb +19 -9
- data/lib/liquid/drop.rb +17 -16
- data/lib/liquid/errors.rb +20 -24
- data/lib/liquid/expression.rb +15 -3
- data/lib/liquid/extensions.rb +13 -7
- data/lib/liquid/file_system.rb +11 -11
- data/lib/liquid/forloop_drop.rb +42 -0
- data/lib/liquid/i18n.rb +5 -5
- data/lib/liquid/interrupts.rb +1 -2
- data/lib/liquid/lexer.rb +6 -4
- data/lib/liquid/locales/en.yml +5 -1
- data/lib/liquid/parse_context.rb +37 -0
- data/lib/liquid/parser.rb +1 -1
- data/lib/liquid/parser_switching.rb +4 -4
- data/lib/liquid/profiler/hooks.rb +7 -7
- data/lib/liquid/profiler.rb +18 -19
- data/lib/liquid/range_lookup.rb +16 -1
- data/lib/liquid/resource_limits.rb +23 -0
- data/lib/liquid/standardfilters.rb +121 -61
- data/lib/liquid/strainer.rb +32 -29
- data/lib/liquid/tablerowloop_drop.rb +62 -0
- data/lib/liquid/tag.rb +9 -8
- data/lib/liquid/tags/assign.rb +17 -4
- data/lib/liquid/tags/break.rb +0 -3
- data/lib/liquid/tags/capture.rb +2 -2
- data/lib/liquid/tags/case.rb +19 -12
- data/lib/liquid/tags/comment.rb +2 -2
- data/lib/liquid/tags/cycle.rb +6 -6
- data/lib/liquid/tags/decrement.rb +1 -4
- data/lib/liquid/tags/for.rb +95 -75
- data/lib/liquid/tags/if.rb +48 -43
- data/lib/liquid/tags/ifchanged.rb +0 -2
- data/lib/liquid/tags/include.rb +61 -52
- data/lib/liquid/tags/raw.rb +32 -4
- data/lib/liquid/tags/table_row.rb +12 -31
- data/lib/liquid/tags/unless.rb +4 -5
- data/lib/liquid/template.rb +42 -54
- data/lib/liquid/tokenizer.rb +31 -0
- data/lib/liquid/utils.rb +52 -8
- data/lib/liquid/variable.rb +46 -45
- data/lib/liquid/variable_lookup.rb +9 -5
- data/lib/liquid/version.rb +1 -1
- data/lib/liquid.rb +9 -7
- data/test/integration/assign_test.rb +18 -8
- data/test/integration/blank_test.rb +14 -14
- data/test/integration/capture_test.rb +10 -0
- data/test/integration/context_test.rb +2 -2
- data/test/integration/document_test.rb +19 -0
- data/test/integration/drop_test.rb +42 -40
- data/test/integration/error_handling_test.rb +99 -46
- data/test/integration/filter_test.rb +72 -19
- data/test/integration/hash_ordering_test.rb +9 -9
- data/test/integration/output_test.rb +34 -27
- data/test/integration/parsing_quirks_test.rb +15 -13
- data/test/integration/render_profiling_test.rb +20 -20
- data/test/integration/security_test.rb +9 -7
- data/test/integration/standard_filter_test.rb +198 -42
- data/test/integration/tags/break_tag_test.rb +1 -2
- data/test/integration/tags/continue_tag_test.rb +0 -1
- data/test/integration/tags/for_tag_test.rb +133 -98
- data/test/integration/tags/if_else_tag_test.rb +96 -77
- data/test/integration/tags/include_tag_test.rb +34 -30
- data/test/integration/tags/increment_tag_test.rb +10 -11
- data/test/integration/tags/raw_tag_test.rb +7 -1
- data/test/integration/tags/standard_tag_test.rb +121 -122
- data/test/integration/tags/statements_test.rb +3 -5
- data/test/integration/tags/table_row_test.rb +20 -19
- data/test/integration/tags/unless_else_tag_test.rb +6 -6
- data/test/integration/template_test.rb +190 -49
- data/test/integration/trim_mode_test.rb +525 -0
- data/test/integration/variable_test.rb +23 -13
- data/test/test_helper.rb +44 -9
- data/test/unit/block_unit_test.rb +8 -5
- data/test/unit/condition_unit_test.rb +86 -77
- data/test/unit/context_unit_test.rb +48 -57
- data/test/unit/file_system_unit_test.rb +3 -3
- data/test/unit/i18n_unit_test.rb +2 -2
- data/test/unit/lexer_unit_test.rb +11 -8
- data/test/unit/parser_unit_test.rb +2 -2
- data/test/unit/regexp_unit_test.rb +1 -1
- data/test/unit/strainer_unit_test.rb +85 -8
- data/test/unit/tag_unit_test.rb +7 -2
- data/test/unit/tags/case_tag_unit_test.rb +1 -1
- data/test/unit/tags/for_tag_unit_test.rb +2 -2
- data/test/unit/tags/if_tag_unit_test.rb +1 -1
- data/test/unit/template_unit_test.rb +14 -5
- data/test/unit/tokenizer_unit_test.rb +24 -7
- data/test/unit/variable_unit_test.rb +66 -43
- metadata +55 -50
- data/lib/liquid/module_ex.rb +0 -62
- data/lib/liquid/token.rb +0 -18
- data/test/unit/module_ex_unit_test.rb +0 -87
- /data/{MIT-LICENSE → LICENSE} +0 -0
@@ -34,7 +34,7 @@ class BlockUnitTest < Minitest::Test
|
|
34
34
|
template = Liquid::Template.parse(" {{funk}} {{so}} {{brother}} ")
|
35
35
|
assert_equal 7, template.root.nodelist.size
|
36
36
|
assert_equal [String, Variable, String, Variable, String, Variable, String],
|
37
|
-
|
37
|
+
block_types(template.root.nodelist)
|
38
38
|
end
|
39
39
|
|
40
40
|
def test_with_block
|
@@ -45,11 +45,14 @@ class BlockUnitTest < Minitest::Test
|
|
45
45
|
|
46
46
|
def test_with_custom_tag
|
47
47
|
Liquid::Template.register_tag("testtag", Block)
|
48
|
-
assert Liquid::Template.parse(
|
48
|
+
assert Liquid::Template.parse("{% testtag %} {% endtesttag %}")
|
49
|
+
ensure
|
50
|
+
Liquid::Template.tags.delete('testtag')
|
49
51
|
end
|
50
52
|
|
51
53
|
private
|
52
|
-
|
53
|
-
|
54
|
-
|
54
|
+
|
55
|
+
def block_types(nodelist)
|
56
|
+
nodelist.collect(&:class)
|
57
|
+
end
|
55
58
|
end # VariableTest
|
@@ -3,147 +3,156 @@ require 'test_helper'
|
|
3
3
|
class ConditionUnitTest < Minitest::Test
|
4
4
|
include Liquid
|
5
5
|
|
6
|
+
def setup
|
7
|
+
@context = Liquid::Context.new
|
8
|
+
end
|
9
|
+
|
6
10
|
def test_basic_condition
|
7
|
-
assert_equal false, Condition.new(
|
8
|
-
assert_equal true, Condition.new(
|
11
|
+
assert_equal false, Condition.new(1, '==', 2).evaluate
|
12
|
+
assert_equal true, Condition.new(1, '==', 1).evaluate
|
9
13
|
end
|
10
14
|
|
11
15
|
def test_default_operators_evalute_true
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
16
|
+
assert_evaluates_true 1, '==', 1
|
17
|
+
assert_evaluates_true 1, '!=', 2
|
18
|
+
assert_evaluates_true 1, '<>', 2
|
19
|
+
assert_evaluates_true 1, '<', 2
|
20
|
+
assert_evaluates_true 2, '>', 1
|
21
|
+
assert_evaluates_true 1, '>=', 1
|
22
|
+
assert_evaluates_true 2, '>=', 1
|
23
|
+
assert_evaluates_true 1, '<=', 2
|
24
|
+
assert_evaluates_true 1, '<=', 1
|
21
25
|
# negative numbers
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
+
assert_evaluates_true 1, '>', -1
|
27
|
+
assert_evaluates_true (-1), '<', 1
|
28
|
+
assert_evaluates_true 1.0, '>', -1.0
|
29
|
+
assert_evaluates_true (-1.0), '<', 1.0
|
26
30
|
end
|
27
31
|
|
28
32
|
def test_default_operators_evalute_false
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
33
|
+
assert_evaluates_false 1, '==', 2
|
34
|
+
assert_evaluates_false 1, '!=', 1
|
35
|
+
assert_evaluates_false 1, '<>', 1
|
36
|
+
assert_evaluates_false 1, '<', 0
|
37
|
+
assert_evaluates_false 2, '>', 4
|
38
|
+
assert_evaluates_false 1, '>=', 3
|
39
|
+
assert_evaluates_false 2, '>=', 4
|
40
|
+
assert_evaluates_false 1, '<=', 0
|
41
|
+
assert_evaluates_false 1, '<=', 0
|
38
42
|
end
|
39
43
|
|
40
44
|
def test_contains_works_on_strings
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
45
|
+
assert_evaluates_true 'bob', 'contains', 'o'
|
46
|
+
assert_evaluates_true 'bob', 'contains', 'b'
|
47
|
+
assert_evaluates_true 'bob', 'contains', 'bo'
|
48
|
+
assert_evaluates_true 'bob', 'contains', 'ob'
|
49
|
+
assert_evaluates_true 'bob', 'contains', 'bob'
|
50
|
+
|
51
|
+
assert_evaluates_false 'bob', 'contains', 'bob2'
|
52
|
+
assert_evaluates_false 'bob', 'contains', 'a'
|
53
|
+
assert_evaluates_false 'bob', 'contains', '---'
|
50
54
|
end
|
51
55
|
|
52
56
|
def test_invalid_comparation_operator
|
53
|
-
assert_evaluates_argument_error
|
57
|
+
assert_evaluates_argument_error 1, '~~', 0
|
54
58
|
end
|
55
59
|
|
56
60
|
def test_comparation_of_int_and_str
|
57
|
-
assert_evaluates_argument_error
|
58
|
-
assert_evaluates_argument_error
|
59
|
-
assert_evaluates_argument_error
|
60
|
-
assert_evaluates_argument_error
|
61
|
+
assert_evaluates_argument_error '1', '>', 0
|
62
|
+
assert_evaluates_argument_error '1', '<', 0
|
63
|
+
assert_evaluates_argument_error '1', '>=', 0
|
64
|
+
assert_evaluates_argument_error '1', '<=', 0
|
61
65
|
end
|
62
66
|
|
63
67
|
def test_contains_works_on_arrays
|
64
68
|
@context = Liquid::Context.new
|
65
|
-
@context['array'] = [1,2,3,4,5]
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
69
|
+
@context['array'] = [1, 2, 3, 4, 5]
|
70
|
+
array_expr = VariableLookup.new("array")
|
71
|
+
|
72
|
+
assert_evaluates_false array_expr, 'contains', 0
|
73
|
+
assert_evaluates_true array_expr, 'contains', 1
|
74
|
+
assert_evaluates_true array_expr, 'contains', 2
|
75
|
+
assert_evaluates_true array_expr, 'contains', 3
|
76
|
+
assert_evaluates_true array_expr, 'contains', 4
|
77
|
+
assert_evaluates_true array_expr, 'contains', 5
|
78
|
+
assert_evaluates_false array_expr, 'contains', 6
|
79
|
+
assert_evaluates_false array_expr, 'contains', "1"
|
75
80
|
end
|
76
81
|
|
77
82
|
def test_contains_returns_false_for_nil_operands
|
78
83
|
@context = Liquid::Context.new
|
79
|
-
|
80
|
-
|
84
|
+
assert_evaluates_false VariableLookup.new('not_assigned'), 'contains', '0'
|
85
|
+
assert_evaluates_false 0, 'contains', VariableLookup.new('not_assigned')
|
81
86
|
end
|
82
87
|
|
83
88
|
def test_contains_return_false_on_wrong_data_type
|
84
|
-
|
89
|
+
assert_evaluates_false 1, 'contains', 0
|
90
|
+
end
|
91
|
+
|
92
|
+
def test_contains_with_string_left_operand_coerces_right_operand_to_string
|
93
|
+
assert_evaluates_true ' 1 ', 'contains', 1
|
94
|
+
assert_evaluates_false ' 1 ', 'contains', 2
|
85
95
|
end
|
86
96
|
|
87
97
|
def test_or_condition
|
88
|
-
condition = Condition.new(
|
98
|
+
condition = Condition.new(1, '==', 2)
|
89
99
|
|
90
100
|
assert_equal false, condition.evaluate
|
91
101
|
|
92
|
-
condition.or Condition.new(
|
102
|
+
condition.or Condition.new(2, '==', 1)
|
93
103
|
|
94
104
|
assert_equal false, condition.evaluate
|
95
105
|
|
96
|
-
condition.or Condition.new(
|
106
|
+
condition.or Condition.new(1, '==', 1)
|
97
107
|
|
98
108
|
assert_equal true, condition.evaluate
|
99
109
|
end
|
100
110
|
|
101
111
|
def test_and_condition
|
102
|
-
condition = Condition.new(
|
112
|
+
condition = Condition.new(1, '==', 1)
|
103
113
|
|
104
114
|
assert_equal true, condition.evaluate
|
105
115
|
|
106
|
-
condition.and Condition.new(
|
116
|
+
condition.and Condition.new(2, '==', 2)
|
107
117
|
|
108
118
|
assert_equal true, condition.evaluate
|
109
119
|
|
110
|
-
condition.and Condition.new(
|
120
|
+
condition.and Condition.new(2, '==', 1)
|
111
121
|
|
112
122
|
assert_equal false, condition.evaluate
|
113
123
|
end
|
114
124
|
|
115
125
|
def test_should_allow_custom_proc_operator
|
116
|
-
Condition.operators['starts_with'] =
|
117
|
-
|
118
|
-
assert_evalutes_true "'bob'", 'starts_with', "'b'"
|
119
|
-
assert_evalutes_false "'bob'", 'starts_with', "'o'"
|
126
|
+
Condition.operators['starts_with'] = proc { |cond, left, right| left =~ %r{^#{right}} }
|
120
127
|
|
121
|
-
|
122
|
-
|
128
|
+
assert_evaluates_true 'bob', 'starts_with', 'b'
|
129
|
+
assert_evaluates_false 'bob', 'starts_with', 'o'
|
130
|
+
ensure
|
131
|
+
Condition.operators.delete 'starts_with'
|
123
132
|
end
|
124
133
|
|
125
134
|
def test_left_or_right_may_contain_operators
|
126
135
|
@context = Liquid::Context.new
|
127
136
|
@context['one'] = @context['another'] = "gnomeslab-and-or-liquid"
|
128
137
|
|
129
|
-
|
138
|
+
assert_evaluates_true VariableLookup.new("one"), '==', VariableLookup.new("another")
|
130
139
|
end
|
131
140
|
|
132
141
|
private
|
133
|
-
def assert_evalutes_true(left, op, right)
|
134
|
-
assert Condition.new(left, op, right).evaluate(@context || Liquid::Context.new),
|
135
|
-
"Evaluated false: #{left} #{op} #{right}"
|
136
|
-
end
|
137
142
|
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
143
|
+
def assert_evaluates_true(left, op, right)
|
144
|
+
assert Condition.new(left, op, right).evaluate(@context),
|
145
|
+
"Evaluated false: #{left} #{op} #{right}"
|
146
|
+
end
|
142
147
|
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
end
|
148
|
+
def assert_evaluates_false(left, op, right)
|
149
|
+
assert !Condition.new(left, op, right).evaluate(@context),
|
150
|
+
"Evaluated true: #{left} #{op} #{right}"
|
151
|
+
end
|
148
152
|
|
153
|
+
def assert_evaluates_argument_error(left, op, right)
|
154
|
+
assert_raises(Liquid::ArgumentError) do
|
155
|
+
Condition.new(left, op, right).evaluate(@context)
|
156
|
+
end
|
157
|
+
end
|
149
158
|
end # ConditionTest
|
@@ -122,30 +122,25 @@ class ContextUnitTest < Minitest::Test
|
|
122
122
|
end
|
123
123
|
|
124
124
|
def test_length_query
|
125
|
-
|
126
|
-
@context['numbers'] = [1,2,3,4]
|
125
|
+
@context['numbers'] = [1, 2, 3, 4]
|
127
126
|
|
128
127
|
assert_equal 4, @context['numbers.size']
|
129
128
|
|
130
|
-
@context['numbers'] = {1 => 1,2 => 2,3 => 3,4 => 4}
|
129
|
+
@context['numbers'] = { 1 => 1, 2 => 2, 3 => 3, 4 => 4 }
|
131
130
|
|
132
131
|
assert_equal 4, @context['numbers.size']
|
133
132
|
|
134
|
-
@context['numbers'] = {1 => 1,2 => 2,3 => 3,4 => 4, 'size' => 1000}
|
133
|
+
@context['numbers'] = { 1 => 1, 2 => 2, 3 => 3, 4 => 4, 'size' => 1000 }
|
135
134
|
|
136
135
|
assert_equal 1000, @context['numbers.size']
|
137
|
-
|
138
136
|
end
|
139
137
|
|
140
138
|
def test_hyphenated_variable
|
141
|
-
|
142
139
|
@context['oh-my'] = 'godz'
|
143
140
|
assert_equal 'godz', @context['oh-my']
|
144
|
-
|
145
141
|
end
|
146
142
|
|
147
143
|
def test_add_filter
|
148
|
-
|
149
144
|
filter = Module.new do
|
150
145
|
def hi(output)
|
151
146
|
output + ' hi!'
|
@@ -161,11 +156,9 @@ class ContextUnitTest < Minitest::Test
|
|
161
156
|
|
162
157
|
context.add_filters(filter)
|
163
158
|
assert_equal 'hi? hi!', context.invoke(:hi, 'hi?')
|
164
|
-
|
165
159
|
end
|
166
160
|
|
167
161
|
def test_only_intended_filters_make_it_there
|
168
|
-
|
169
162
|
filter = Module.new do
|
170
163
|
def hi(output)
|
171
164
|
output + ' hi!'
|
@@ -196,7 +189,7 @@ class ContextUnitTest < Minitest::Test
|
|
196
189
|
end
|
197
190
|
|
198
191
|
def test_hierachical_data
|
199
|
-
@context['hash'] = {"name" => 'tobi'}
|
192
|
+
@context['hash'] = { "name" => 'tobi' }
|
200
193
|
assert_equal 'tobi', @context['hash.name']
|
201
194
|
assert_equal 'tobi', @context['hash["name"]']
|
202
195
|
end
|
@@ -225,7 +218,7 @@ class ContextUnitTest < Minitest::Test
|
|
225
218
|
end
|
226
219
|
|
227
220
|
def test_array_notation
|
228
|
-
@context['test'] = [1,2,3,4,5]
|
221
|
+
@context['test'] = [1, 2, 3, 4, 5]
|
229
222
|
|
230
223
|
assert_equal 1, @context['test[0]']
|
231
224
|
assert_equal 2, @context['test[1]']
|
@@ -235,21 +228,21 @@ class ContextUnitTest < Minitest::Test
|
|
235
228
|
end
|
236
229
|
|
237
230
|
def test_recoursive_array_notation
|
238
|
-
@context['test'] = {'test' => [1,2,3,4,5]}
|
231
|
+
@context['test'] = { 'test' => [1, 2, 3, 4, 5] }
|
239
232
|
|
240
233
|
assert_equal 1, @context['test.test[0]']
|
241
234
|
|
242
|
-
@context['test'] = [{'test' => 'worked'}]
|
235
|
+
@context['test'] = [{ 'test' => 'worked' }]
|
243
236
|
|
244
237
|
assert_equal 'worked', @context['test[0].test']
|
245
238
|
end
|
246
239
|
|
247
240
|
def test_hash_to_array_transition
|
248
241
|
@context['colors'] = {
|
249
|
-
'Blue' => ['003366','336699', '6699CC', '99CCFF'],
|
250
|
-
'Green' => ['003300','336633', '669966', '99CC99'],
|
251
|
-
'Yellow' => ['CC9900','FFCC00', 'FFFF99', 'FFFFCC'],
|
252
|
-
'Red' => ['660000','993333', 'CC6666', 'FF9999']
|
242
|
+
'Blue' => ['003366', '336699', '6699CC', '99CCFF'],
|
243
|
+
'Green' => ['003300', '336633', '669966', '99CC99'],
|
244
|
+
'Yellow' => ['CC9900', 'FFCC00', 'FFFF99', 'FFFFCC'],
|
245
|
+
'Red' => ['660000', '993333', 'CC6666', 'FF9999']
|
253
246
|
}
|
254
247
|
|
255
248
|
assert_equal '003366', @context['colors.Blue[0]']
|
@@ -257,12 +250,12 @@ class ContextUnitTest < Minitest::Test
|
|
257
250
|
end
|
258
251
|
|
259
252
|
def test_try_first
|
260
|
-
@context['test'] = [1,2,3,4,5]
|
253
|
+
@context['test'] = [1, 2, 3, 4, 5]
|
261
254
|
|
262
255
|
assert_equal 1, @context['test.first']
|
263
256
|
assert_equal 5, @context['test.last']
|
264
257
|
|
265
|
-
@context['test'] = {'test' => [1,2,3,4,5]}
|
258
|
+
@context['test'] = { 'test' => [1, 2, 3, 4, 5] }
|
266
259
|
|
267
260
|
assert_equal 1, @context['test.test.first']
|
268
261
|
assert_equal 5, @context['test.test.last']
|
@@ -273,8 +266,8 @@ class ContextUnitTest < Minitest::Test
|
|
273
266
|
end
|
274
267
|
|
275
268
|
def test_access_hashes_with_hash_notation
|
276
|
-
@context['products'] = {'count' => 5, 'tags' => ['deepsnow', 'freestyle'] }
|
277
|
-
@context['product'] = {'variants' => [ {'title' => 'draft151cm'}, {'title' => 'element151cm'}
|
269
|
+
@context['products'] = { 'count' => 5, 'tags' => ['deepsnow', 'freestyle'] }
|
270
|
+
@context['product'] = { 'variants' => [ { 'title' => 'draft151cm' }, { 'title' => 'element151cm' } ] }
|
278
271
|
|
279
272
|
assert_equal 5, @context['products["count"]']
|
280
273
|
assert_equal 'deepsnow', @context['products["tags"][0]']
|
@@ -294,18 +287,17 @@ class ContextUnitTest < Minitest::Test
|
|
294
287
|
end
|
295
288
|
|
296
289
|
def test_access_hashes_with_hash_access_variables
|
297
|
-
|
298
290
|
@context['var'] = 'tags'
|
299
|
-
@context['nested'] = {'var' => 'tags'}
|
300
|
-
@context['products'] = {'count' => 5, 'tags' => ['deepsnow', 'freestyle'] }
|
291
|
+
@context['nested'] = { 'var' => 'tags' }
|
292
|
+
@context['products'] = { 'count' => 5, 'tags' => ['deepsnow', 'freestyle'] }
|
301
293
|
|
302
294
|
assert_equal 'deepsnow', @context['products[var].first']
|
303
295
|
assert_equal 'freestyle', @context['products[nested.var].last']
|
304
296
|
end
|
305
297
|
|
306
298
|
def test_hash_notation_only_for_hash_access
|
307
|
-
@context['array'] = [1,2,3,4,5]
|
308
|
-
@context['hash'] = {'first' => 'Hello'}
|
299
|
+
@context['array'] = [1, 2, 3, 4, 5]
|
300
|
+
@context['hash'] = { 'first' => 'Hello' }
|
309
301
|
|
310
302
|
assert_equal 1, @context['array.first']
|
311
303
|
assert_equal nil, @context['array["first"]']
|
@@ -313,66 +305,64 @@ class ContextUnitTest < Minitest::Test
|
|
313
305
|
end
|
314
306
|
|
315
307
|
def test_first_can_appear_in_middle_of_callchain
|
316
|
-
|
317
|
-
@context['product'] = {'variants' => [ {'title' => 'draft151cm'}, {'title' => 'element151cm'} ]}
|
308
|
+
@context['product'] = { 'variants' => [ { 'title' => 'draft151cm' }, { 'title' => 'element151cm' } ] }
|
318
309
|
|
319
310
|
assert_equal 'draft151cm', @context['product.variants[0].title']
|
320
311
|
assert_equal 'element151cm', @context['product.variants[1].title']
|
321
312
|
assert_equal 'draft151cm', @context['product.variants.first.title']
|
322
313
|
assert_equal 'element151cm', @context['product.variants.last.title']
|
323
|
-
|
324
314
|
end
|
325
315
|
|
326
316
|
def test_cents
|
327
|
-
@context.merge(
|
317
|
+
@context.merge("cents" => HundredCentes.new)
|
328
318
|
assert_equal 100, @context['cents']
|
329
319
|
end
|
330
320
|
|
331
321
|
def test_nested_cents
|
332
|
-
@context.merge(
|
322
|
+
@context.merge("cents" => { 'amount' => HundredCentes.new })
|
333
323
|
assert_equal 100, @context['cents.amount']
|
334
324
|
|
335
|
-
@context.merge(
|
325
|
+
@context.merge("cents" => { 'cents' => { 'amount' => HundredCentes.new } })
|
336
326
|
assert_equal 100, @context['cents.cents.amount']
|
337
327
|
end
|
338
328
|
|
339
329
|
def test_cents_through_drop
|
340
|
-
@context.merge(
|
330
|
+
@context.merge("cents" => CentsDrop.new)
|
341
331
|
assert_equal 100, @context['cents.amount']
|
342
332
|
end
|
343
333
|
|
344
334
|
def test_nested_cents_through_drop
|
345
|
-
@context.merge(
|
335
|
+
@context.merge("vars" => { "cents" => CentsDrop.new })
|
346
336
|
assert_equal 100, @context['vars.cents.amount']
|
347
337
|
end
|
348
338
|
|
349
339
|
def test_drop_methods_with_question_marks
|
350
|
-
@context.merge(
|
340
|
+
@context.merge("cents" => CentsDrop.new)
|
351
341
|
assert @context['cents.non_zero?']
|
352
342
|
end
|
353
343
|
|
354
344
|
def test_context_from_within_drop
|
355
|
-
@context.merge(
|
345
|
+
@context.merge("test" => '123', "vars" => ContextSensitiveDrop.new)
|
356
346
|
assert_equal '123', @context['vars.test']
|
357
347
|
end
|
358
348
|
|
359
349
|
def test_nested_context_from_within_drop
|
360
|
-
@context.merge(
|
350
|
+
@context.merge("test" => '123', "vars" => { "local" => ContextSensitiveDrop.new })
|
361
351
|
assert_equal '123', @context['vars.local.test']
|
362
352
|
end
|
363
353
|
|
364
354
|
def test_ranges
|
365
|
-
@context.merge(
|
355
|
+
@context.merge("test" => '5')
|
366
356
|
assert_equal (1..5), @context['(1..5)']
|
367
357
|
assert_equal (1..5), @context['(1..test)']
|
368
358
|
assert_equal (5..5), @context['(test..test)']
|
369
359
|
end
|
370
360
|
|
371
361
|
def test_cents_through_drop_nestedly
|
372
|
-
@context.merge(
|
362
|
+
@context.merge("cents" => { "cents" => CentsDrop.new })
|
373
363
|
assert_equal 100, @context['cents.cents.amount']
|
374
364
|
|
375
|
-
@context.merge(
|
365
|
+
@context.merge("cents" => { "cents" => { "cents" => CentsDrop.new } })
|
376
366
|
assert_equal 100, @context['cents.cents.cents.amount']
|
377
367
|
end
|
378
368
|
|
@@ -393,7 +383,7 @@ class ContextUnitTest < Minitest::Test
|
|
393
383
|
end
|
394
384
|
|
395
385
|
def test_proc_as_variable
|
396
|
-
@context['dynamic'] =
|
386
|
+
@context['dynamic'] = proc { 'Hello' }
|
397
387
|
|
398
388
|
assert_equal 'Hello', @context['dynamic']
|
399
389
|
end
|
@@ -411,7 +401,7 @@ class ContextUnitTest < Minitest::Test
|
|
411
401
|
end
|
412
402
|
|
413
403
|
def test_array_containing_lambda_as_variable
|
414
|
-
@context['dynamic'] = [1,2, proc { 'Hello' }
|
404
|
+
@context['dynamic'] = [1, 2, proc { 'Hello' }, 4, 5]
|
415
405
|
|
416
406
|
assert_equal 'Hello', @context['dynamic[2]']
|
417
407
|
end
|
@@ -437,7 +427,7 @@ class ContextUnitTest < Minitest::Test
|
|
437
427
|
end
|
438
428
|
|
439
429
|
def test_lambda_in_array_is_called_once
|
440
|
-
@context['callcount'] = [1,2, proc { @global ||= 0; @global += 1; @global.to_s }
|
430
|
+
@context['callcount'] = [1, 2, proc { @global ||= 0; @global += 1; @global.to_s }, 4, 5]
|
441
431
|
|
442
432
|
assert_equal '1', @context['callcount[2]']
|
443
433
|
assert_equal '1', @context['callcount[2]']
|
@@ -463,30 +453,31 @@ class ContextUnitTest < Minitest::Test
|
|
463
453
|
def test_use_empty_instead_of_any_in_interrupt_handling_to_avoid_lots_of_unnecessary_object_allocations
|
464
454
|
mock_any = Spy.on_instance_method(Array, :any?)
|
465
455
|
mock_empty = Spy.on_instance_method(Array, :empty?)
|
466
|
-
mock_has_interrupt = Spy.on(@context, :has_interrupt?).and_call_through
|
467
456
|
|
468
|
-
@context.
|
457
|
+
@context.interrupt?
|
469
458
|
|
470
459
|
refute mock_any.has_been_called?
|
471
460
|
assert mock_empty.has_been_called?
|
472
|
-
end
|
473
|
-
|
474
|
-
def test_variable_lookup_caches_markup
|
475
|
-
mock_scan = Spy.on_instance_method(String, :scan).and_return(["string"])
|
476
|
-
|
477
|
-
@context['string'] = 'string'
|
478
|
-
@context['string']
|
479
|
-
@context['string']
|
480
|
-
|
481
|
-
assert_equal 1, mock_scan.calls.size
|
482
461
|
end
|
483
462
|
|
484
463
|
def test_context_initialization_with_a_proc_in_environment
|
485
|
-
contx = Context.new([:
|
464
|
+
contx = Context.new([test: ->(c) { c['poutine'] }], { test: :foo })
|
486
465
|
|
487
466
|
assert contx
|
488
467
|
assert_nil contx['poutine']
|
489
468
|
end
|
490
469
|
|
470
|
+
def test_apply_global_filter
|
471
|
+
global_filter_proc = ->(output) { "#{output} filtered" }
|
472
|
+
|
473
|
+
context = Context.new
|
474
|
+
context.global_filter = global_filter_proc
|
475
|
+
|
476
|
+
assert_equal 'hi filtered', context.apply_global_filter('hi')
|
477
|
+
end
|
491
478
|
|
479
|
+
def test_apply_global_filter_when_no_global_filter_exist
|
480
|
+
context = Context.new
|
481
|
+
assert_equal 'hi', context.apply_global_filter('hi')
|
482
|
+
end
|
492
483
|
end # ContextTest
|
@@ -5,13 +5,13 @@ class FileSystemUnitTest < Minitest::Test
|
|
5
5
|
|
6
6
|
def test_default
|
7
7
|
assert_raises(FileSystemError) do
|
8
|
-
BlankFileSystem.new.read_template_file("dummy"
|
8
|
+
BlankFileSystem.new.read_template_file("dummy")
|
9
9
|
end
|
10
10
|
end
|
11
11
|
|
12
12
|
def test_local
|
13
13
|
file_system = Liquid::LocalFileSystem.new("/some/path")
|
14
|
-
assert_equal "/some/path/_mypartial.liquid"
|
14
|
+
assert_equal "/some/path/_mypartial.liquid", file_system.full_path("mypartial")
|
15
15
|
assert_equal "/some/path/dir/_mypartial.liquid", file_system.full_path("dir/mypartial")
|
16
16
|
|
17
17
|
assert_raises(FileSystemError) do
|
@@ -29,7 +29,7 @@ class FileSystemUnitTest < Minitest::Test
|
|
29
29
|
|
30
30
|
def test_custom_template_filename_patterns
|
31
31
|
file_system = Liquid::LocalFileSystem.new("/some/path", "%s.html")
|
32
|
-
assert_equal "/some/path/mypartial.html"
|
32
|
+
assert_equal "/some/path/mypartial.html", file_system.full_path("mypartial")
|
33
33
|
assert_equal "/some/path/dir/mypartial.html", file_system.full_path("dir/mypartial")
|
34
34
|
end
|
35
35
|
end # FileSystemTest
|
data/test/unit/i18n_unit_test.rb
CHANGED
@@ -16,7 +16,7 @@ class I18nUnitTest < Minitest::Test
|
|
16
16
|
end
|
17
17
|
|
18
18
|
def test_single_string_interpolation
|
19
|
-
assert_equal "something different", @i18n.translate("whatever", :
|
19
|
+
assert_equal "something different", @i18n.translate("whatever", something: "different")
|
20
20
|
end
|
21
21
|
|
22
22
|
# def test_raises_translation_error_on_undefined_interpolation_key
|
@@ -24,7 +24,7 @@ class I18nUnitTest < Minitest::Test
|
|
24
24
|
# @i18n.translate("whatever", :oopstypos => "yes")
|
25
25
|
# end
|
26
26
|
# end
|
27
|
-
|
27
|
+
|
28
28
|
def test_raises_unknown_translation
|
29
29
|
assert_raises I18n::TranslationError do
|
30
30
|
@i18n.translate("doesnt_exist")
|
@@ -4,23 +4,23 @@ class LexerUnitTest < Minitest::Test
|
|
4
4
|
include Liquid
|
5
5
|
|
6
6
|
def test_strings
|
7
|
-
tokens = Lexer.new(
|
8
|
-
assert_equal [[:string
|
7
|
+
tokens = Lexer.new(%( 'this is a test""' "wat 'lol'")).tokenize
|
8
|
+
assert_equal [[:string, %('this is a test""')], [:string, %("wat 'lol'")], [:end_of_string]], tokens
|
9
9
|
end
|
10
10
|
|
11
11
|
def test_integer
|
12
12
|
tokens = Lexer.new('hi 50').tokenize
|
13
|
-
assert_equal [[:id,'hi'], [:number, '50'], [:end_of_string]], tokens
|
13
|
+
assert_equal [[:id, 'hi'], [:number, '50'], [:end_of_string]], tokens
|
14
14
|
end
|
15
15
|
|
16
16
|
def test_float
|
17
17
|
tokens = Lexer.new('hi 5.0').tokenize
|
18
|
-
assert_equal [[:id,'hi'], [:number, '5.0'], [:end_of_string]], tokens
|
18
|
+
assert_equal [[:id, 'hi'], [:number, '5.0'], [:end_of_string]], tokens
|
19
19
|
end
|
20
20
|
|
21
21
|
def test_comparison
|
22
22
|
tokens = Lexer.new('== <> contains').tokenize
|
23
|
-
assert_equal [[:comparison,'=='], [:comparison, '<>'], [:comparison, 'contains'], [:end_of_string]], tokens
|
23
|
+
assert_equal [[:comparison, '=='], [:comparison, '<>'], [:comparison, 'contains'], [:end_of_string]], tokens
|
24
24
|
end
|
25
25
|
|
26
26
|
def test_specials
|
@@ -31,13 +31,16 @@ class LexerUnitTest < Minitest::Test
|
|
31
31
|
end
|
32
32
|
|
33
33
|
def test_fancy_identifiers
|
34
|
-
tokens = Lexer.new('hi
|
35
|
-
assert_equal [[:id,'hi
|
34
|
+
tokens = Lexer.new('hi five?').tokenize
|
35
|
+
assert_equal [[:id, 'hi'], [:id, 'five?'], [:end_of_string]], tokens
|
36
|
+
|
37
|
+
tokens = Lexer.new('2foo').tokenize
|
38
|
+
assert_equal [[:number, '2'], [:id, 'foo'], [:end_of_string]], tokens
|
36
39
|
end
|
37
40
|
|
38
41
|
def test_whitespace
|
39
42
|
tokens = Lexer.new("five|\n\t ==").tokenize
|
40
|
-
assert_equal [[:id,'five'], [:pipe, '|'], [:comparison, '=='], [:end_of_string]], tokens
|
43
|
+
assert_equal [[:id, 'five'], [:pipe, '|'], [:comparison, '=='], [:end_of_string]], tokens
|
41
44
|
end
|
42
45
|
|
43
46
|
def test_unexpected_character
|