liquid 4.0.2 → 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 +59 -0
- data/README.md +6 -0
- data/lib/liquid/block.rb +31 -14
- data/lib/liquid/block_body.rb +166 -53
- 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 +76 -52
- 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,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'test_helper'
|
2
4
|
|
3
5
|
class TrimModeTest < Minitest::Test
|
@@ -67,7 +69,7 @@ class TrimModeTest < Minitest::Test
|
|
67
69
|
# Make sure the trim isn't applied to standard tags
|
68
70
|
def test_standard_tags
|
69
71
|
whitespace = ' '
|
70
|
-
text
|
72
|
+
text = <<-END_TEMPLATE
|
71
73
|
<div>
|
72
74
|
<p>
|
73
75
|
{% if true %}
|
@@ -76,14 +78,14 @@ class TrimModeTest < Minitest::Test
|
|
76
78
|
</p>
|
77
79
|
</div>
|
78
80
|
END_TEMPLATE
|
79
|
-
expected =
|
80
|
-
|
81
|
-
|
82
|
-
#{whitespace}
|
83
|
-
|
84
|
-
#{whitespace}
|
85
|
-
|
86
|
-
|
81
|
+
expected = <<~END_EXPECTED
|
82
|
+
<div>
|
83
|
+
<p>
|
84
|
+
#{whitespace}
|
85
|
+
yes
|
86
|
+
#{whitespace}
|
87
|
+
</p>
|
88
|
+
</div>
|
87
89
|
END_EXPECTED
|
88
90
|
assert_template_result(expected, text)
|
89
91
|
|
@@ -96,70 +98,70 @@ class TrimModeTest < Minitest::Test
|
|
96
98
|
</p>
|
97
99
|
</div>
|
98
100
|
END_TEMPLATE
|
99
|
-
expected =
|
100
|
-
|
101
|
-
|
102
|
-
#{whitespace}
|
103
|
-
|
104
|
-
|
101
|
+
expected = <<~END_EXPECTED
|
102
|
+
<div>
|
103
|
+
<p>
|
104
|
+
#{whitespace}
|
105
|
+
</p>
|
106
|
+
</div>
|
105
107
|
END_EXPECTED
|
106
108
|
assert_template_result(expected, text)
|
107
109
|
end
|
108
110
|
|
109
111
|
# Make sure the trim isn't too agressive
|
110
112
|
def test_no_trim_output
|
111
|
-
text
|
113
|
+
text = '<p>{{- \'John\' -}}</p>'
|
112
114
|
expected = '<p>John</p>'
|
113
115
|
assert_template_result(expected, text)
|
114
116
|
end
|
115
117
|
|
116
118
|
# Make sure the trim isn't too agressive
|
117
119
|
def test_no_trim_tags
|
118
|
-
text
|
120
|
+
text = '<p>{%- if true -%}yes{%- endif -%}</p>'
|
119
121
|
expected = '<p>yes</p>'
|
120
122
|
assert_template_result(expected, text)
|
121
123
|
|
122
|
-
text
|
124
|
+
text = '<p>{%- if false -%}no{%- endif -%}</p>'
|
123
125
|
expected = '<p></p>'
|
124
126
|
assert_template_result(expected, text)
|
125
127
|
end
|
126
128
|
|
127
129
|
def test_single_line_outer_tag
|
128
|
-
text
|
130
|
+
text = '<p> {%- if true %} yes {% endif -%} </p>'
|
129
131
|
expected = '<p> yes </p>'
|
130
132
|
assert_template_result(expected, text)
|
131
133
|
|
132
|
-
text
|
134
|
+
text = '<p> {%- if false %} no {% endif -%} </p>'
|
133
135
|
expected = '<p></p>'
|
134
136
|
assert_template_result(expected, text)
|
135
137
|
end
|
136
138
|
|
137
139
|
def test_single_line_inner_tag
|
138
|
-
text
|
140
|
+
text = '<p> {% if true -%} yes {%- endif %} </p>'
|
139
141
|
expected = '<p> yes </p>'
|
140
142
|
assert_template_result(expected, text)
|
141
143
|
|
142
|
-
text
|
144
|
+
text = '<p> {% if false -%} no {%- endif %} </p>'
|
143
145
|
expected = '<p> </p>'
|
144
146
|
assert_template_result(expected, text)
|
145
147
|
end
|
146
148
|
|
147
149
|
def test_single_line_post_tag
|
148
|
-
text
|
150
|
+
text = '<p> {% if true -%} yes {% endif -%} </p>'
|
149
151
|
expected = '<p> yes </p>'
|
150
152
|
assert_template_result(expected, text)
|
151
153
|
|
152
|
-
text
|
154
|
+
text = '<p> {% if false -%} no {% endif -%} </p>'
|
153
155
|
expected = '<p> </p>'
|
154
156
|
assert_template_result(expected, text)
|
155
157
|
end
|
156
158
|
|
157
159
|
def test_single_line_pre_tag
|
158
|
-
text
|
160
|
+
text = '<p> {%- if true %} yes {%- endif %} </p>'
|
159
161
|
expected = '<p> yes </p>'
|
160
162
|
assert_template_result(expected, text)
|
161
163
|
|
162
|
-
text
|
164
|
+
text = '<p> {%- if false %} no {%- endif %} </p>'
|
163
165
|
expected = '<p> </p>'
|
164
166
|
assert_template_result(expected, text)
|
165
167
|
end
|
@@ -328,7 +330,7 @@ class TrimModeTest < Minitest::Test
|
|
328
330
|
assert_template_result(expected, text)
|
329
331
|
|
330
332
|
whitespace = ' '
|
331
|
-
text
|
333
|
+
text = <<-END_TEMPLATE
|
332
334
|
<div>
|
333
335
|
<p>
|
334
336
|
{% if false -%}
|
@@ -337,12 +339,12 @@ class TrimModeTest < Minitest::Test
|
|
337
339
|
</p>
|
338
340
|
</div>
|
339
341
|
END_TEMPLATE
|
340
|
-
expected =
|
341
|
-
|
342
|
-
|
343
|
-
#{whitespace}
|
344
|
-
|
345
|
-
|
342
|
+
expected = <<~END_EXPECTED
|
343
|
+
<div>
|
344
|
+
<p>
|
345
|
+
#{whitespace}
|
346
|
+
</p>
|
347
|
+
</div>
|
346
348
|
END_EXPECTED
|
347
349
|
assert_template_result(expected, text)
|
348
350
|
end
|
@@ -502,7 +504,7 @@ class TrimModeTest < Minitest::Test
|
|
502
504
|
|
503
505
|
def test_raw_output
|
504
506
|
whitespace = ' '
|
505
|
-
text
|
507
|
+
text = <<-END_TEMPLATE
|
506
508
|
<div>
|
507
509
|
{% raw %}
|
508
510
|
{%- if true -%}
|
@@ -513,17 +515,49 @@ class TrimModeTest < Minitest::Test
|
|
513
515
|
{% endraw %}
|
514
516
|
</div>
|
515
517
|
END_TEMPLATE
|
516
|
-
expected =
|
517
|
-
|
518
|
-
#{whitespace}
|
519
|
-
|
520
|
-
|
521
|
-
|
522
|
-
|
523
|
-
|
524
|
-
#{whitespace}
|
525
|
-
|
518
|
+
expected = <<~END_EXPECTED
|
519
|
+
<div>
|
520
|
+
#{whitespace}
|
521
|
+
{%- if true -%}
|
522
|
+
<p>
|
523
|
+
{{- 'John' -}}
|
524
|
+
</p>
|
525
|
+
{%- endif -%}
|
526
|
+
#{whitespace}
|
527
|
+
</div>
|
526
528
|
END_EXPECTED
|
527
529
|
assert_template_result(expected, text)
|
528
530
|
end
|
531
|
+
|
532
|
+
def test_pre_trim_blank_preceding_text
|
533
|
+
template = Liquid::Template.parse("\n{%- raw %}{% endraw %}")
|
534
|
+
assert_equal("", template.render)
|
535
|
+
|
536
|
+
template = Liquid::Template.parse("\n{%- if true %}{% endif %}")
|
537
|
+
assert_equal("", template.render)
|
538
|
+
|
539
|
+
template = Liquid::Template.parse("{{ 'B' }} \n{%- if true %}C{% endif %}")
|
540
|
+
assert_equal("BC", template.render)
|
541
|
+
end
|
542
|
+
|
543
|
+
def test_bug_compatible_pre_trim
|
544
|
+
template = Liquid::Template.parse("\n {%- raw %}{% endraw %}", bug_compatible_whitespace_trimming: true)
|
545
|
+
assert_equal("\n", template.render)
|
546
|
+
|
547
|
+
template = Liquid::Template.parse("\n {%- if true %}{% endif %}", bug_compatible_whitespace_trimming: true)
|
548
|
+
assert_equal("\n", template.render)
|
549
|
+
|
550
|
+
template = Liquid::Template.parse("{{ 'B' }} \n{%- if true %}C{% endif %}", bug_compatible_whitespace_trimming: true)
|
551
|
+
assert_equal("B C", template.render)
|
552
|
+
|
553
|
+
template = Liquid::Template.parse("B\n {%- raw %}{% endraw %}", bug_compatible_whitespace_trimming: true)
|
554
|
+
assert_equal("B", template.render)
|
555
|
+
|
556
|
+
template = Liquid::Template.parse("B\n {%- if true %}{% endif %}", bug_compatible_whitespace_trimming: true)
|
557
|
+
assert_equal("B", template.render)
|
558
|
+
end
|
559
|
+
|
560
|
+
def test_trim_blank
|
561
|
+
assert_template_result('foobar', 'foo {{-}} bar')
|
562
|
+
end
|
529
563
|
end # TrimModeTest
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'test_helper'
|
2
4
|
|
3
5
|
class VariableTest < Minitest::Test
|
@@ -5,92 +7,132 @@ class VariableTest < Minitest::Test
|
|
5
7
|
|
6
8
|
def test_simple_variable
|
7
9
|
template = Template.parse(%({{test}}))
|
8
|
-
assert_equal
|
9
|
-
assert_equal
|
10
|
+
assert_equal('worked', template.render!('test' => 'worked'))
|
11
|
+
assert_equal('worked wonderfully', template.render!('test' => 'worked wonderfully'))
|
10
12
|
end
|
11
13
|
|
12
14
|
def test_variable_render_calls_to_liquid
|
13
|
-
assert_template_result
|
15
|
+
assert_template_result('foobar', '{{ foo }}', 'foo' => ThingWithToLiquid.new)
|
16
|
+
end
|
17
|
+
|
18
|
+
def test_variable_lookup_calls_to_liquid_value
|
19
|
+
assert_template_result('1', '{{ foo }}', 'foo' => IntegerDrop.new('1'))
|
20
|
+
assert_template_result('2', '{{ list[foo] }}', 'foo' => IntegerDrop.new('1'), 'list' => [1, 2, 3])
|
21
|
+
assert_template_result('one', '{{ list[foo] }}', 'foo' => IntegerDrop.new('1'), 'list' => { 1 => 'one' })
|
22
|
+
assert_template_result('Yay', '{{ foo }}', 'foo' => BooleanDrop.new(true))
|
23
|
+
assert_template_result('YAY', '{{ foo | upcase }}', 'foo' => BooleanDrop.new(true))
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_if_tag_calls_to_liquid_value
|
27
|
+
assert_template_result('one', '{% if foo == 1 %}one{% endif %}', 'foo' => IntegerDrop.new('1'))
|
28
|
+
assert_template_result('one', '{% if 0 < foo %}one{% endif %}', 'foo' => IntegerDrop.new('1'))
|
29
|
+
assert_template_result('one', '{% if foo > 0 %}one{% endif %}', 'foo' => IntegerDrop.new('1'))
|
30
|
+
assert_template_result('true', '{% if foo == true %}true{% endif %}', 'foo' => BooleanDrop.new(true))
|
31
|
+
assert_template_result('true', '{% if foo %}true{% endif %}', 'foo' => BooleanDrop.new(true))
|
32
|
+
|
33
|
+
assert_template_result('', '{% if foo %}true{% endif %}', 'foo' => BooleanDrop.new(false))
|
34
|
+
assert_template_result('', '{% if foo == true %}True{% endif %}', 'foo' => BooleanDrop.new(false))
|
35
|
+
end
|
36
|
+
|
37
|
+
def test_unless_tag_calls_to_liquid_value
|
38
|
+
assert_template_result('', '{% unless foo %}true{% endunless %}', 'foo' => BooleanDrop.new(true))
|
39
|
+
end
|
40
|
+
|
41
|
+
def test_case_tag_calls_to_liquid_value
|
42
|
+
assert_template_result('One', '{% case foo %}{% when 1 %}One{% endcase %}', 'foo' => IntegerDrop.new('1'))
|
14
43
|
end
|
15
44
|
|
16
45
|
def test_simple_with_whitespaces
|
17
46
|
template = Template.parse(%( {{ test }} ))
|
18
|
-
assert_equal
|
19
|
-
assert_equal
|
47
|
+
assert_equal(' worked ', template.render!('test' => 'worked'))
|
48
|
+
assert_equal(' worked wonderfully ', template.render!('test' => 'worked wonderfully'))
|
49
|
+
end
|
50
|
+
|
51
|
+
def test_expression_with_whitespace_in_square_brackets
|
52
|
+
assert_template_result('result', "{{ a[ 'b' ] }}", 'a' => { 'b' => 'result' })
|
53
|
+
assert_template_result('result', "{{ a[ [ 'b' ] ] }}", 'b' => 'c', 'a' => { 'c' => 'result' })
|
20
54
|
end
|
21
55
|
|
22
56
|
def test_ignore_unknown
|
23
57
|
template = Template.parse(%({{ test }}))
|
24
|
-
assert_equal
|
58
|
+
assert_equal('', template.render!)
|
25
59
|
end
|
26
60
|
|
27
61
|
def test_using_blank_as_variable_name
|
28
62
|
template = Template.parse("{% assign foo = blank %}{{ foo }}")
|
29
|
-
assert_equal
|
63
|
+
assert_equal('', template.render!)
|
30
64
|
end
|
31
65
|
|
32
66
|
def test_using_empty_as_variable_name
|
33
67
|
template = Template.parse("{% assign foo = empty %}{{ foo }}")
|
34
|
-
assert_equal
|
68
|
+
assert_equal('', template.render!)
|
35
69
|
end
|
36
70
|
|
37
71
|
def test_hash_scoping
|
38
|
-
|
39
|
-
|
72
|
+
assert_template_result('worked', "{{ test.test }}", 'test' => { 'test' => 'worked' })
|
73
|
+
assert_template_result('worked', "{{ test . test }}", 'test' => { 'test' => 'worked' })
|
40
74
|
end
|
41
75
|
|
42
76
|
def test_false_renders_as_false
|
43
|
-
assert_equal
|
44
|
-
assert_equal
|
77
|
+
assert_equal('false', Template.parse("{{ foo }}").render!('foo' => false))
|
78
|
+
assert_equal('false', Template.parse("{{ false }}").render!)
|
45
79
|
end
|
46
80
|
|
47
81
|
def test_nil_renders_as_empty_string
|
48
|
-
assert_equal
|
49
|
-
assert_equal
|
82
|
+
assert_equal('', Template.parse("{{ nil }}").render!)
|
83
|
+
assert_equal('cat', Template.parse("{{ nil | append: 'cat' }}").render!)
|
50
84
|
end
|
51
85
|
|
52
86
|
def test_preset_assigns
|
53
|
-
template
|
87
|
+
template = Template.parse(%({{ test }}))
|
54
88
|
template.assigns['test'] = 'worked'
|
55
|
-
assert_equal
|
89
|
+
assert_equal('worked', template.render!)
|
56
90
|
end
|
57
91
|
|
58
92
|
def test_reuse_parsed_template
|
59
|
-
template
|
93
|
+
template = Template.parse(%({{ greeting }} {{ name }}))
|
60
94
|
template.assigns['greeting'] = 'Goodbye'
|
61
|
-
assert_equal
|
62
|
-
assert_equal
|
63
|
-
assert_equal
|
64
|
-
assert_equal
|
95
|
+
assert_equal('Hello Tobi', template.render!('greeting' => 'Hello', 'name' => 'Tobi'))
|
96
|
+
assert_equal('Hello ', template.render!('greeting' => 'Hello', 'unknown' => 'Tobi'))
|
97
|
+
assert_equal('Hello Brian', template.render!('greeting' => 'Hello', 'name' => 'Brian'))
|
98
|
+
assert_equal('Goodbye Brian', template.render!('name' => 'Brian'))
|
65
99
|
assert_equal({ 'greeting' => 'Goodbye' }, template.assigns)
|
66
100
|
end
|
67
101
|
|
68
102
|
def test_assigns_not_polluted_from_template
|
69
|
-
template
|
103
|
+
template = Template.parse(%({{ test }}{% assign test = 'bar' %}{{ test }}))
|
70
104
|
template.assigns['test'] = 'baz'
|
71
|
-
assert_equal
|
72
|
-
assert_equal
|
73
|
-
assert_equal
|
74
|
-
assert_equal
|
105
|
+
assert_equal('bazbar', template.render!)
|
106
|
+
assert_equal('bazbar', template.render!)
|
107
|
+
assert_equal('foobar', template.render!('test' => 'foo'))
|
108
|
+
assert_equal('bazbar', template.render!)
|
75
109
|
end
|
76
110
|
|
77
111
|
def test_hash_with_default_proc
|
78
|
-
template
|
79
|
-
assigns
|
112
|
+
template = Template.parse(%(Hello {{ test }}))
|
113
|
+
assigns = Hash.new { |_h, k| raise "Unknown variable '#{k}'" }
|
80
114
|
assigns['test'] = 'Tobi'
|
81
|
-
assert_equal
|
115
|
+
assert_equal('Hello Tobi', template.render!(assigns))
|
82
116
|
assigns.delete('test')
|
83
117
|
e = assert_raises(RuntimeError) do
|
84
118
|
template.render!(assigns)
|
85
119
|
end
|
86
|
-
assert_equal
|
120
|
+
assert_equal("Unknown variable 'test'", e.message)
|
87
121
|
end
|
88
122
|
|
89
123
|
def test_multiline_variable
|
90
|
-
assert_equal
|
124
|
+
assert_equal('worked', Template.parse("{{\ntest\n}}").render!('test' => 'worked'))
|
91
125
|
end
|
92
126
|
|
93
127
|
def test_render_symbol
|
94
|
-
assert_template_result
|
128
|
+
assert_template_result('bar', '{{ foo }}', 'foo' => :bar)
|
129
|
+
end
|
130
|
+
|
131
|
+
def test_dynamic_find_var
|
132
|
+
assert_template_result('bar', '{{ [key] }}', 'key' => 'foo', 'foo' => 'bar')
|
133
|
+
end
|
134
|
+
|
135
|
+
def test_raw_value_variable
|
136
|
+
assert_template_result('bar', '{{ [key] }}', 'key' => 'foo', 'foo' => 'bar')
|
95
137
|
end
|
96
138
|
end
|
data/test/test_helper.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
2
3
|
|
3
4
|
ENV["MT_NO_EXPECTATIONS"] = "1"
|
4
5
|
require 'minitest/autorun'
|
@@ -8,13 +9,13 @@ require 'liquid.rb'
|
|
8
9
|
require 'liquid/profiler'
|
9
10
|
|
10
11
|
mode = :strict
|
11
|
-
if env_mode = ENV['LIQUID_PARSER_MODE']
|
12
|
+
if (env_mode = ENV['LIQUID_PARSER_MODE'])
|
12
13
|
puts "-- #{env_mode.upcase} ERROR MODE"
|
13
14
|
mode = env_mode.to_sym
|
14
15
|
end
|
15
16
|
Liquid::Template.error_mode = mode
|
16
17
|
|
17
|
-
if ENV['
|
18
|
+
if ENV['LIQUID_C'] == '1'
|
18
19
|
puts "-- LIQUID C"
|
19
20
|
require 'liquid/c'
|
20
21
|
end
|
@@ -37,44 +38,55 @@ module Minitest
|
|
37
38
|
include Liquid
|
38
39
|
|
39
40
|
def assert_template_result(expected, template, assigns = {}, message = nil)
|
40
|
-
assert_equal
|
41
|
+
assert_equal(expected, Template.parse(template, line_numbers: true).render!(assigns), message)
|
41
42
|
end
|
42
43
|
|
43
44
|
def assert_template_result_matches(expected, template, assigns = {}, message = nil)
|
44
|
-
return assert_template_result(expected, template, assigns, message) unless expected.is_a?
|
45
|
+
return assert_template_result(expected, template, assigns, message) unless expected.is_a?(Regexp)
|
45
46
|
|
46
|
-
assert_match
|
47
|
+
assert_match(expected, Template.parse(template, line_numbers: true).render!(assigns), message)
|
47
48
|
end
|
48
49
|
|
49
50
|
def assert_match_syntax_error(match, template, assigns = {})
|
50
51
|
exception = assert_raises(Liquid::SyntaxError) do
|
51
|
-
Template.parse(template).render(assigns)
|
52
|
+
Template.parse(template, line_numbers: true).render(assigns)
|
52
53
|
end
|
53
|
-
assert_match
|
54
|
+
assert_match(match, exception.message)
|
55
|
+
end
|
56
|
+
|
57
|
+
def assert_usage_increment(name, times: 1)
|
58
|
+
old_method = Liquid::Usage.method(:increment)
|
59
|
+
calls = 0
|
60
|
+
begin
|
61
|
+
Liquid::Usage.singleton_class.send(:remove_method, :increment)
|
62
|
+
Liquid::Usage.define_singleton_method(:increment) do |got_name|
|
63
|
+
calls += 1 if got_name == name
|
64
|
+
old_method.call(got_name)
|
65
|
+
end
|
66
|
+
yield
|
67
|
+
ensure
|
68
|
+
Liquid::Usage.singleton_class.send(:remove_method, :increment)
|
69
|
+
Liquid::Usage.define_singleton_method(:increment, old_method)
|
70
|
+
end
|
71
|
+
assert_equal(times, calls, "Number of calls to Usage.increment with #{name.inspect}")
|
54
72
|
end
|
55
73
|
|
56
74
|
def with_global_filter(*globals)
|
57
|
-
|
58
|
-
Liquid::
|
59
|
-
|
60
|
-
|
61
|
-
|
75
|
+
original_global_filters = Liquid::StrainerFactory.instance_variable_get(:@global_filters)
|
76
|
+
Liquid::StrainerFactory.instance_variable_set(:@global_filters, [])
|
77
|
+
globals.each do |global|
|
78
|
+
Liquid::StrainerFactory.add_global_filter(global)
|
79
|
+
end
|
80
|
+
|
81
|
+
Liquid::StrainerFactory.send(:strainer_class_cache).clear
|
62
82
|
|
63
83
|
globals.each do |global|
|
64
84
|
Liquid::Template.register_filter(global)
|
65
85
|
end
|
66
86
|
yield
|
67
87
|
ensure
|
68
|
-
Liquid::
|
69
|
-
Liquid::
|
70
|
-
end
|
71
|
-
|
72
|
-
def with_taint_mode(mode)
|
73
|
-
old_mode = Liquid::Template.taint_mode
|
74
|
-
Liquid::Template.taint_mode = mode
|
75
|
-
yield
|
76
|
-
ensure
|
77
|
-
Liquid::Template.taint_mode = old_mode
|
88
|
+
Liquid::StrainerFactory.send(:strainer_class_cache).clear
|
89
|
+
Liquid::StrainerFactory.instance_variable_set(:@global_filters, original_global_filters)
|
78
90
|
end
|
79
91
|
|
80
92
|
def with_error_mode(mode)
|
@@ -84,6 +96,20 @@ module Minitest
|
|
84
96
|
ensure
|
85
97
|
Liquid::Template.error_mode = old_mode
|
86
98
|
end
|
99
|
+
|
100
|
+
def with_custom_tag(tag_name, tag_class)
|
101
|
+
old_tag = Liquid::Template.tags[tag_name]
|
102
|
+
begin
|
103
|
+
Liquid::Template.register_tag(tag_name, tag_class)
|
104
|
+
yield
|
105
|
+
ensure
|
106
|
+
if old_tag
|
107
|
+
Liquid::Template.tags[tag_name] = old_tag
|
108
|
+
else
|
109
|
+
Liquid::Template.tags.delete(tag_name)
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
87
113
|
end
|
88
114
|
end
|
89
115
|
|
@@ -93,6 +119,44 @@ class ThingWithToLiquid
|
|
93
119
|
end
|
94
120
|
end
|
95
121
|
|
122
|
+
class IntegerDrop < Liquid::Drop
|
123
|
+
def initialize(value)
|
124
|
+
super()
|
125
|
+
@value = value.to_i
|
126
|
+
end
|
127
|
+
|
128
|
+
def ==(other)
|
129
|
+
@value == other
|
130
|
+
end
|
131
|
+
|
132
|
+
def to_s
|
133
|
+
@value.to_s
|
134
|
+
end
|
135
|
+
|
136
|
+
def to_liquid_value
|
137
|
+
@value
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
class BooleanDrop < Liquid::Drop
|
142
|
+
def initialize(value)
|
143
|
+
super()
|
144
|
+
@value = value
|
145
|
+
end
|
146
|
+
|
147
|
+
def ==(other)
|
148
|
+
@value == other
|
149
|
+
end
|
150
|
+
|
151
|
+
def to_liquid_value
|
152
|
+
@value
|
153
|
+
end
|
154
|
+
|
155
|
+
def to_s
|
156
|
+
@value ? "Yay" : "Nay"
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
96
160
|
class ErrorDrop < Liquid::Drop
|
97
161
|
def standard_error
|
98
162
|
raise Liquid::StandardError, 'standard error'
|
@@ -114,3 +178,30 @@ class ErrorDrop < Liquid::Drop
|
|
114
178
|
raise Exception, 'exception'
|
115
179
|
end
|
116
180
|
end
|
181
|
+
|
182
|
+
class StubFileSystem
|
183
|
+
attr_reader :file_read_count
|
184
|
+
|
185
|
+
def initialize(values)
|
186
|
+
@file_read_count = 0
|
187
|
+
@values = values
|
188
|
+
end
|
189
|
+
|
190
|
+
def read_template_file(template_path)
|
191
|
+
@file_read_count += 1
|
192
|
+
@values.fetch(template_path)
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
196
|
+
class StubTemplateFactory
|
197
|
+
attr_reader :count
|
198
|
+
|
199
|
+
def initialize
|
200
|
+
@count = 0
|
201
|
+
end
|
202
|
+
|
203
|
+
def for(_template_name)
|
204
|
+
@count += 1
|
205
|
+
Liquid::Template.new
|
206
|
+
end
|
207
|
+
end
|