liquid-4-0-2 4.0.2
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 +7 -0
- data/History.md +235 -0
- data/LICENSE +20 -0
- data/README.md +108 -0
- data/lib/liquid.rb +80 -0
- data/lib/liquid/block.rb +77 -0
- data/lib/liquid/block_body.rb +142 -0
- data/lib/liquid/condition.rb +151 -0
- data/lib/liquid/context.rb +226 -0
- data/lib/liquid/document.rb +27 -0
- data/lib/liquid/drop.rb +78 -0
- data/lib/liquid/errors.rb +56 -0
- data/lib/liquid/expression.rb +49 -0
- data/lib/liquid/extensions.rb +74 -0
- data/lib/liquid/file_system.rb +73 -0
- data/lib/liquid/forloop_drop.rb +42 -0
- data/lib/liquid/i18n.rb +39 -0
- data/lib/liquid/interrupts.rb +16 -0
- data/lib/liquid/lexer.rb +55 -0
- data/lib/liquid/locales/en.yml +26 -0
- data/lib/liquid/parse_context.rb +38 -0
- data/lib/liquid/parse_tree_visitor.rb +42 -0
- data/lib/liquid/parser.rb +90 -0
- data/lib/liquid/parser_switching.rb +31 -0
- data/lib/liquid/profiler.rb +158 -0
- data/lib/liquid/profiler/hooks.rb +23 -0
- data/lib/liquid/range_lookup.rb +37 -0
- data/lib/liquid/resource_limits.rb +23 -0
- data/lib/liquid/standardfilters.rb +485 -0
- data/lib/liquid/strainer.rb +66 -0
- data/lib/liquid/tablerowloop_drop.rb +62 -0
- data/lib/liquid/tag.rb +43 -0
- data/lib/liquid/tags/assign.rb +59 -0
- data/lib/liquid/tags/break.rb +18 -0
- data/lib/liquid/tags/capture.rb +38 -0
- data/lib/liquid/tags/case.rb +94 -0
- data/lib/liquid/tags/comment.rb +16 -0
- data/lib/liquid/tags/continue.rb +18 -0
- data/lib/liquid/tags/cycle.rb +65 -0
- data/lib/liquid/tags/decrement.rb +35 -0
- data/lib/liquid/tags/for.rb +203 -0
- data/lib/liquid/tags/if.rb +122 -0
- data/lib/liquid/tags/ifchanged.rb +18 -0
- data/lib/liquid/tags/include.rb +124 -0
- data/lib/liquid/tags/increment.rb +31 -0
- data/lib/liquid/tags/raw.rb +47 -0
- data/lib/liquid/tags/table_row.rb +62 -0
- data/lib/liquid/tags/unless.rb +30 -0
- data/lib/liquid/template.rb +254 -0
- data/lib/liquid/tokenizer.rb +31 -0
- data/lib/liquid/utils.rb +83 -0
- data/lib/liquid/variable.rb +148 -0
- data/lib/liquid/variable_lookup.rb +88 -0
- data/lib/liquid/version.rb +4 -0
- data/test/fixtures/en_locale.yml +9 -0
- data/test/integration/assign_test.rb +48 -0
- data/test/integration/blank_test.rb +106 -0
- data/test/integration/block_test.rb +12 -0
- data/test/integration/capture_test.rb +50 -0
- data/test/integration/context_test.rb +32 -0
- data/test/integration/document_test.rb +19 -0
- data/test/integration/drop_test.rb +273 -0
- data/test/integration/error_handling_test.rb +260 -0
- data/test/integration/filter_test.rb +178 -0
- data/test/integration/hash_ordering_test.rb +23 -0
- data/test/integration/output_test.rb +123 -0
- data/test/integration/parse_tree_visitor_test.rb +247 -0
- data/test/integration/parsing_quirks_test.rb +122 -0
- data/test/integration/render_profiling_test.rb +154 -0
- data/test/integration/security_test.rb +80 -0
- data/test/integration/standard_filter_test.rb +698 -0
- data/test/integration/tags/break_tag_test.rb +15 -0
- data/test/integration/tags/continue_tag_test.rb +15 -0
- data/test/integration/tags/for_tag_test.rb +410 -0
- data/test/integration/tags/if_else_tag_test.rb +188 -0
- data/test/integration/tags/include_tag_test.rb +245 -0
- data/test/integration/tags/increment_tag_test.rb +23 -0
- data/test/integration/tags/raw_tag_test.rb +31 -0
- data/test/integration/tags/standard_tag_test.rb +296 -0
- data/test/integration/tags/statements_test.rb +111 -0
- data/test/integration/tags/table_row_test.rb +64 -0
- data/test/integration/tags/unless_else_tag_test.rb +26 -0
- data/test/integration/template_test.rb +332 -0
- data/test/integration/trim_mode_test.rb +529 -0
- data/test/integration/variable_test.rb +96 -0
- data/test/test_helper.rb +116 -0
- data/test/unit/block_unit_test.rb +58 -0
- data/test/unit/condition_unit_test.rb +166 -0
- data/test/unit/context_unit_test.rb +489 -0
- data/test/unit/file_system_unit_test.rb +35 -0
- data/test/unit/i18n_unit_test.rb +37 -0
- data/test/unit/lexer_unit_test.rb +51 -0
- data/test/unit/parser_unit_test.rb +82 -0
- data/test/unit/regexp_unit_test.rb +44 -0
- data/test/unit/strainer_unit_test.rb +164 -0
- data/test/unit/tag_unit_test.rb +21 -0
- data/test/unit/tags/case_tag_unit_test.rb +10 -0
- data/test/unit/tags/for_tag_unit_test.rb +13 -0
- data/test/unit/tags/if_tag_unit_test.rb +8 -0
- data/test/unit/template_unit_test.rb +78 -0
- data/test/unit/tokenizer_unit_test.rb +55 -0
- data/test/unit/variable_unit_test.rb +162 -0
- metadata +224 -0
@@ -0,0 +1,178 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
module MoneyFilter
|
4
|
+
def money(input)
|
5
|
+
sprintf(' %d$ ', input)
|
6
|
+
end
|
7
|
+
|
8
|
+
def money_with_underscore(input)
|
9
|
+
sprintf(' %d$ ', input)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
module CanadianMoneyFilter
|
14
|
+
def money(input)
|
15
|
+
sprintf(' %d$ CAD ', input)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
module SubstituteFilter
|
20
|
+
def substitute(input, params = {})
|
21
|
+
input.gsub(/%\{(\w+)\}/) { |match| params[$1] }
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
class FiltersTest < Minitest::Test
|
26
|
+
include Liquid
|
27
|
+
|
28
|
+
module OverrideObjectMethodFilter
|
29
|
+
def tap(input)
|
30
|
+
"tap overridden"
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def setup
|
35
|
+
@context = Context.new
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_local_filter
|
39
|
+
@context['var'] = 1000
|
40
|
+
@context.add_filters(MoneyFilter)
|
41
|
+
|
42
|
+
assert_equal ' 1000$ ', Template.parse("{{var | money}}").render(@context)
|
43
|
+
end
|
44
|
+
|
45
|
+
def test_underscore_in_filter_name
|
46
|
+
@context['var'] = 1000
|
47
|
+
@context.add_filters(MoneyFilter)
|
48
|
+
assert_equal ' 1000$ ', Template.parse("{{var | money_with_underscore}}").render(@context)
|
49
|
+
end
|
50
|
+
|
51
|
+
def test_second_filter_overwrites_first
|
52
|
+
@context['var'] = 1000
|
53
|
+
@context.add_filters(MoneyFilter)
|
54
|
+
@context.add_filters(CanadianMoneyFilter)
|
55
|
+
|
56
|
+
assert_equal ' 1000$ CAD ', Template.parse("{{var | money}}").render(@context)
|
57
|
+
end
|
58
|
+
|
59
|
+
def test_size
|
60
|
+
@context['var'] = 'abcd'
|
61
|
+
@context.add_filters(MoneyFilter)
|
62
|
+
|
63
|
+
assert_equal '4', Template.parse("{{var | size}}").render(@context)
|
64
|
+
end
|
65
|
+
|
66
|
+
def test_join
|
67
|
+
@context['var'] = [1, 2, 3, 4]
|
68
|
+
|
69
|
+
assert_equal "1 2 3 4", Template.parse("{{var | join}}").render(@context)
|
70
|
+
end
|
71
|
+
|
72
|
+
def test_sort
|
73
|
+
@context['value'] = 3
|
74
|
+
@context['numbers'] = [2, 1, 4, 3]
|
75
|
+
@context['words'] = ['expected', 'as', 'alphabetic']
|
76
|
+
@context['arrays'] = ['flower', 'are']
|
77
|
+
@context['case_sensitive'] = ['sensitive', 'Expected', 'case']
|
78
|
+
|
79
|
+
assert_equal '1 2 3 4', Template.parse("{{numbers | sort | join}}").render(@context)
|
80
|
+
assert_equal 'alphabetic as expected', Template.parse("{{words | sort | join}}").render(@context)
|
81
|
+
assert_equal '3', Template.parse("{{value | sort}}").render(@context)
|
82
|
+
assert_equal 'are flower', Template.parse("{{arrays | sort | join}}").render(@context)
|
83
|
+
assert_equal 'Expected case sensitive', Template.parse("{{case_sensitive | sort | join}}").render(@context)
|
84
|
+
end
|
85
|
+
|
86
|
+
def test_sort_natural
|
87
|
+
@context['words'] = ['case', 'Assert', 'Insensitive']
|
88
|
+
@context['hashes'] = [{ 'a' => 'A' }, { 'a' => 'b' }, { 'a' => 'C' }]
|
89
|
+
@context['objects'] = [TestObject.new('A'), TestObject.new('b'), TestObject.new('C')]
|
90
|
+
|
91
|
+
# Test strings
|
92
|
+
assert_equal 'Assert case Insensitive', Template.parse("{{words | sort_natural | join}}").render(@context)
|
93
|
+
|
94
|
+
# Test hashes
|
95
|
+
assert_equal 'A b C', Template.parse("{{hashes | sort_natural: 'a' | map: 'a' | join}}").render(@context)
|
96
|
+
|
97
|
+
# Test objects
|
98
|
+
assert_equal 'A b C', Template.parse("{{objects | sort_natural: 'a' | map: 'a' | join}}").render(@context)
|
99
|
+
end
|
100
|
+
|
101
|
+
def test_compact
|
102
|
+
@context['words'] = ['a', nil, 'b', nil, 'c']
|
103
|
+
@context['hashes'] = [{ 'a' => 'A' }, { 'a' => nil }, { 'a' => 'C' }]
|
104
|
+
@context['objects'] = [TestObject.new('A'), TestObject.new(nil), TestObject.new('C')]
|
105
|
+
|
106
|
+
# Test strings
|
107
|
+
assert_equal 'a b c', Template.parse("{{words | compact | join}}").render(@context)
|
108
|
+
|
109
|
+
# Test hashes
|
110
|
+
assert_equal 'A C', Template.parse("{{hashes | compact: 'a' | map: 'a' | join}}").render(@context)
|
111
|
+
|
112
|
+
# Test objects
|
113
|
+
assert_equal 'A C', Template.parse("{{objects | compact: 'a' | map: 'a' | join}}").render(@context)
|
114
|
+
end
|
115
|
+
|
116
|
+
def test_strip_html
|
117
|
+
@context['var'] = "<b>bla blub</a>"
|
118
|
+
|
119
|
+
assert_equal "bla blub", Template.parse("{{ var | strip_html }}").render(@context)
|
120
|
+
end
|
121
|
+
|
122
|
+
def test_strip_html_ignore_comments_with_html
|
123
|
+
@context['var'] = "<!-- split and some <ul> tag --><b>bla blub</a>"
|
124
|
+
|
125
|
+
assert_equal "bla blub", Template.parse("{{ var | strip_html }}").render(@context)
|
126
|
+
end
|
127
|
+
|
128
|
+
def test_capitalize
|
129
|
+
@context['var'] = "blub"
|
130
|
+
|
131
|
+
assert_equal "Blub", Template.parse("{{ var | capitalize }}").render(@context)
|
132
|
+
end
|
133
|
+
|
134
|
+
def test_nonexistent_filter_is_ignored
|
135
|
+
@context['var'] = 1000
|
136
|
+
|
137
|
+
assert_equal '1000', Template.parse("{{ var | xyzzy }}").render(@context)
|
138
|
+
end
|
139
|
+
|
140
|
+
def test_filter_with_keyword_arguments
|
141
|
+
@context['surname'] = 'john'
|
142
|
+
@context['input'] = 'hello %{first_name}, %{last_name}'
|
143
|
+
@context.add_filters(SubstituteFilter)
|
144
|
+
output = Template.parse(%({{ input | substitute: first_name: surname, last_name: 'doe' }})).render(@context)
|
145
|
+
assert_equal 'hello john, doe', output
|
146
|
+
end
|
147
|
+
|
148
|
+
def test_override_object_method_in_filter
|
149
|
+
assert_equal "tap overridden", Template.parse("{{var | tap}}").render!({ 'var' => 1000 }, filters: [OverrideObjectMethodFilter])
|
150
|
+
|
151
|
+
# tap still treated as a non-existent filter
|
152
|
+
assert_equal "1000", Template.parse("{{var | tap}}").render!({ 'var' => 1000 })
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
class FiltersInTemplate < Minitest::Test
|
157
|
+
include Liquid
|
158
|
+
|
159
|
+
def test_local_global
|
160
|
+
with_global_filter(MoneyFilter) do
|
161
|
+
assert_equal " 1000$ ", Template.parse("{{1000 | money}}").render!(nil, nil)
|
162
|
+
assert_equal " 1000$ CAD ", Template.parse("{{1000 | money}}").render!(nil, filters: CanadianMoneyFilter)
|
163
|
+
assert_equal " 1000$ CAD ", Template.parse("{{1000 | money}}").render!(nil, filters: [CanadianMoneyFilter])
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
def test_local_filter_with_deprecated_syntax
|
168
|
+
assert_equal " 1000$ CAD ", Template.parse("{{1000 | money}}").render!(nil, CanadianMoneyFilter)
|
169
|
+
assert_equal " 1000$ CAD ", Template.parse("{{1000 | money}}").render!(nil, [CanadianMoneyFilter])
|
170
|
+
end
|
171
|
+
end # FiltersTest
|
172
|
+
|
173
|
+
class TestObject < Liquid::Drop
|
174
|
+
attr_accessor :a
|
175
|
+
def initialize(a)
|
176
|
+
@a = a
|
177
|
+
end
|
178
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class HashOrderingTest < Minitest::Test
|
4
|
+
module MoneyFilter
|
5
|
+
def money(input)
|
6
|
+
sprintf(' %d$ ', input)
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
module CanadianMoneyFilter
|
11
|
+
def money(input)
|
12
|
+
sprintf(' %d$ CAD ', input)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
include Liquid
|
17
|
+
|
18
|
+
def test_global_register_order
|
19
|
+
with_global_filter(MoneyFilter, CanadianMoneyFilter) do
|
20
|
+
assert_equal " 1000$ CAD ", Template.parse("{{1000 | money}}").render(nil, nil)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,123 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
module FunnyFilter
|
4
|
+
def make_funny(input)
|
5
|
+
'LOL'
|
6
|
+
end
|
7
|
+
|
8
|
+
def cite_funny(input)
|
9
|
+
"LOL: #{input}"
|
10
|
+
end
|
11
|
+
|
12
|
+
def add_smiley(input, smiley = ":-)")
|
13
|
+
"#{input} #{smiley}"
|
14
|
+
end
|
15
|
+
|
16
|
+
def add_tag(input, tag = "p", id = "foo")
|
17
|
+
%(<#{tag} id="#{id}">#{input}</#{tag}>)
|
18
|
+
end
|
19
|
+
|
20
|
+
def paragraph(input)
|
21
|
+
"<p>#{input}</p>"
|
22
|
+
end
|
23
|
+
|
24
|
+
def link_to(name, url)
|
25
|
+
%(<a href="#{url}">#{name}</a>)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
class OutputTest < Minitest::Test
|
30
|
+
include Liquid
|
31
|
+
|
32
|
+
def setup
|
33
|
+
@assigns = {
|
34
|
+
'best_cars' => 'bmw',
|
35
|
+
'car' => { 'bmw' => 'good', 'gm' => 'bad' }
|
36
|
+
}
|
37
|
+
end
|
38
|
+
|
39
|
+
def test_variable
|
40
|
+
text = %( {{best_cars}} )
|
41
|
+
|
42
|
+
expected = %( bmw )
|
43
|
+
assert_equal expected, Template.parse(text).render!(@assigns)
|
44
|
+
end
|
45
|
+
|
46
|
+
def test_variable_traversing_with_two_brackets
|
47
|
+
text = %({{ site.data.menu[include.menu][include.locale] }})
|
48
|
+
assert_equal "it works!", Template.parse(text).render!(
|
49
|
+
"site" => { "data" => { "menu" => { "foo" => { "bar" => "it works!" } } } },
|
50
|
+
"include" => { "menu" => "foo", "locale" => "bar" }
|
51
|
+
)
|
52
|
+
end
|
53
|
+
|
54
|
+
def test_variable_traversing
|
55
|
+
text = %( {{car.bmw}} {{car.gm}} {{car.bmw}} )
|
56
|
+
|
57
|
+
expected = %( good bad good )
|
58
|
+
assert_equal expected, Template.parse(text).render!(@assigns)
|
59
|
+
end
|
60
|
+
|
61
|
+
def test_variable_piping
|
62
|
+
text = %( {{ car.gm | make_funny }} )
|
63
|
+
expected = %( LOL )
|
64
|
+
|
65
|
+
assert_equal expected, Template.parse(text).render!(@assigns, filters: [FunnyFilter])
|
66
|
+
end
|
67
|
+
|
68
|
+
def test_variable_piping_with_input
|
69
|
+
text = %( {{ car.gm | cite_funny }} )
|
70
|
+
expected = %( LOL: bad )
|
71
|
+
|
72
|
+
assert_equal expected, Template.parse(text).render!(@assigns, filters: [FunnyFilter])
|
73
|
+
end
|
74
|
+
|
75
|
+
def test_variable_piping_with_args
|
76
|
+
text = %! {{ car.gm | add_smiley : ':-(' }} !
|
77
|
+
expected = %| bad :-( |
|
78
|
+
|
79
|
+
assert_equal expected, Template.parse(text).render!(@assigns, filters: [FunnyFilter])
|
80
|
+
end
|
81
|
+
|
82
|
+
def test_variable_piping_with_no_args
|
83
|
+
text = %( {{ car.gm | add_smiley }} )
|
84
|
+
expected = %| bad :-) |
|
85
|
+
|
86
|
+
assert_equal expected, Template.parse(text).render!(@assigns, filters: [FunnyFilter])
|
87
|
+
end
|
88
|
+
|
89
|
+
def test_multiple_variable_piping_with_args
|
90
|
+
text = %! {{ car.gm | add_smiley : ':-(' | add_smiley : ':-('}} !
|
91
|
+
expected = %| bad :-( :-( |
|
92
|
+
|
93
|
+
assert_equal expected, Template.parse(text).render!(@assigns, filters: [FunnyFilter])
|
94
|
+
end
|
95
|
+
|
96
|
+
def test_variable_piping_with_multiple_args
|
97
|
+
text = %( {{ car.gm | add_tag : 'span', 'bar'}} )
|
98
|
+
expected = %( <span id="bar">bad</span> )
|
99
|
+
|
100
|
+
assert_equal expected, Template.parse(text).render!(@assigns, filters: [FunnyFilter])
|
101
|
+
end
|
102
|
+
|
103
|
+
def test_variable_piping_with_variable_args
|
104
|
+
text = %( {{ car.gm | add_tag : 'span', car.bmw}} )
|
105
|
+
expected = %( <span id="good">bad</span> )
|
106
|
+
|
107
|
+
assert_equal expected, Template.parse(text).render!(@assigns, filters: [FunnyFilter])
|
108
|
+
end
|
109
|
+
|
110
|
+
def test_multiple_pipings
|
111
|
+
text = %( {{ best_cars | cite_funny | paragraph }} )
|
112
|
+
expected = %( <p>LOL: bmw</p> )
|
113
|
+
|
114
|
+
assert_equal expected, Template.parse(text).render!(@assigns, filters: [FunnyFilter])
|
115
|
+
end
|
116
|
+
|
117
|
+
def test_link_to
|
118
|
+
text = %( {{ 'Typo' | link_to: 'http://typo.leetsoft.com' }} )
|
119
|
+
expected = %( <a href="http://typo.leetsoft.com">Typo</a> )
|
120
|
+
|
121
|
+
assert_equal expected, Template.parse(text).render!(@assigns, filters: [FunnyFilter])
|
122
|
+
end
|
123
|
+
end # OutputTest
|
@@ -0,0 +1,247 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'test_helper'
|
4
|
+
|
5
|
+
class ParseTreeVisitorTest < Minitest::Test
|
6
|
+
include Liquid
|
7
|
+
|
8
|
+
def test_variable
|
9
|
+
assert_equal(
|
10
|
+
["test"],
|
11
|
+
visit(%({{ test }}))
|
12
|
+
)
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_varible_with_filter
|
16
|
+
assert_equal(
|
17
|
+
["test", "infilter"],
|
18
|
+
visit(%({{ test | split: infilter }}))
|
19
|
+
)
|
20
|
+
end
|
21
|
+
|
22
|
+
def test_dynamic_variable
|
23
|
+
assert_equal(
|
24
|
+
["test", "inlookup"],
|
25
|
+
visit(%({{ test[inlookup] }}))
|
26
|
+
)
|
27
|
+
end
|
28
|
+
|
29
|
+
def test_if_condition
|
30
|
+
assert_equal(
|
31
|
+
["test"],
|
32
|
+
visit(%({% if test %}{% endif %}))
|
33
|
+
)
|
34
|
+
end
|
35
|
+
|
36
|
+
def test_complex_if_condition
|
37
|
+
assert_equal(
|
38
|
+
["test"],
|
39
|
+
visit(%({% if 1 == 1 and 2 == test %}{% endif %}))
|
40
|
+
)
|
41
|
+
end
|
42
|
+
|
43
|
+
def test_if_body
|
44
|
+
assert_equal(
|
45
|
+
["test"],
|
46
|
+
visit(%({% if 1 == 1 %}{{ test }}{% endif %}))
|
47
|
+
)
|
48
|
+
end
|
49
|
+
|
50
|
+
def test_unless_condition
|
51
|
+
assert_equal(
|
52
|
+
["test"],
|
53
|
+
visit(%({% unless test %}{% endunless %}))
|
54
|
+
)
|
55
|
+
end
|
56
|
+
|
57
|
+
def test_complex_unless_condition
|
58
|
+
assert_equal(
|
59
|
+
["test"],
|
60
|
+
visit(%({% unless 1 == 1 and 2 == test %}{% endunless %}))
|
61
|
+
)
|
62
|
+
end
|
63
|
+
|
64
|
+
def test_unless_body
|
65
|
+
assert_equal(
|
66
|
+
["test"],
|
67
|
+
visit(%({% unless 1 == 1 %}{{ test }}{% endunless %}))
|
68
|
+
)
|
69
|
+
end
|
70
|
+
|
71
|
+
def test_elsif_condition
|
72
|
+
assert_equal(
|
73
|
+
["test"],
|
74
|
+
visit(%({% if 1 == 1 %}{% elsif test %}{% endif %}))
|
75
|
+
)
|
76
|
+
end
|
77
|
+
|
78
|
+
def test_complex_elsif_condition
|
79
|
+
assert_equal(
|
80
|
+
["test"],
|
81
|
+
visit(%({% if 1 == 1 %}{% elsif 1 == 1 and 2 == test %}{% endif %}))
|
82
|
+
)
|
83
|
+
end
|
84
|
+
|
85
|
+
def test_elsif_body
|
86
|
+
assert_equal(
|
87
|
+
["test"],
|
88
|
+
visit(%({% if 1 == 1 %}{% elsif 2 == 2 %}{{ test }}{% endif %}))
|
89
|
+
)
|
90
|
+
end
|
91
|
+
|
92
|
+
def test_else_body
|
93
|
+
assert_equal(
|
94
|
+
["test"],
|
95
|
+
visit(%({% if 1 == 1 %}{% else %}{{ test }}{% endif %}))
|
96
|
+
)
|
97
|
+
end
|
98
|
+
|
99
|
+
def test_case_left
|
100
|
+
assert_equal(
|
101
|
+
["test"],
|
102
|
+
visit(%({% case test %}{% endcase %}))
|
103
|
+
)
|
104
|
+
end
|
105
|
+
|
106
|
+
def test_case_condition
|
107
|
+
assert_equal(
|
108
|
+
["test"],
|
109
|
+
visit(%({% case 1 %}{% when test %}{% endcase %}))
|
110
|
+
)
|
111
|
+
end
|
112
|
+
|
113
|
+
def test_case_when_body
|
114
|
+
assert_equal(
|
115
|
+
["test"],
|
116
|
+
visit(%({% case 1 %}{% when 2 %}{{ test }}{% endcase %}))
|
117
|
+
)
|
118
|
+
end
|
119
|
+
|
120
|
+
def test_case_else_body
|
121
|
+
assert_equal(
|
122
|
+
["test"],
|
123
|
+
visit(%({% case 1 %}{% else %}{{ test }}{% endcase %}))
|
124
|
+
)
|
125
|
+
end
|
126
|
+
|
127
|
+
def test_for_in
|
128
|
+
assert_equal(
|
129
|
+
["test"],
|
130
|
+
visit(%({% for x in test %}{% endfor %}))
|
131
|
+
)
|
132
|
+
end
|
133
|
+
|
134
|
+
def test_for_limit
|
135
|
+
assert_equal(
|
136
|
+
["test"],
|
137
|
+
visit(%({% for x in (1..5) limit: test %}{% endfor %}))
|
138
|
+
)
|
139
|
+
end
|
140
|
+
|
141
|
+
def test_for_offset
|
142
|
+
assert_equal(
|
143
|
+
["test"],
|
144
|
+
visit(%({% for x in (1..5) offset: test %}{% endfor %}))
|
145
|
+
)
|
146
|
+
end
|
147
|
+
|
148
|
+
def test_for_body
|
149
|
+
assert_equal(
|
150
|
+
["test"],
|
151
|
+
visit(%({% for x in (1..5) %}{{ test }}{% endfor %}))
|
152
|
+
)
|
153
|
+
end
|
154
|
+
|
155
|
+
def test_tablerow_in
|
156
|
+
assert_equal(
|
157
|
+
["test"],
|
158
|
+
visit(%({% tablerow x in test %}{% endtablerow %}))
|
159
|
+
)
|
160
|
+
end
|
161
|
+
|
162
|
+
def test_tablerow_limit
|
163
|
+
assert_equal(
|
164
|
+
["test"],
|
165
|
+
visit(%({% tablerow x in (1..5) limit: test %}{% endtablerow %}))
|
166
|
+
)
|
167
|
+
end
|
168
|
+
|
169
|
+
def test_tablerow_offset
|
170
|
+
assert_equal(
|
171
|
+
["test"],
|
172
|
+
visit(%({% tablerow x in (1..5) offset: test %}{% endtablerow %}))
|
173
|
+
)
|
174
|
+
end
|
175
|
+
|
176
|
+
def test_tablerow_body
|
177
|
+
assert_equal(
|
178
|
+
["test"],
|
179
|
+
visit(%({% tablerow x in (1..5) %}{{ test }}{% endtablerow %}))
|
180
|
+
)
|
181
|
+
end
|
182
|
+
|
183
|
+
def test_cycle
|
184
|
+
assert_equal(
|
185
|
+
["test"],
|
186
|
+
visit(%({% cycle test %}))
|
187
|
+
)
|
188
|
+
end
|
189
|
+
|
190
|
+
def test_assign
|
191
|
+
assert_equal(
|
192
|
+
["test"],
|
193
|
+
visit(%({% assign x = test %}))
|
194
|
+
)
|
195
|
+
end
|
196
|
+
|
197
|
+
def test_capture
|
198
|
+
assert_equal(
|
199
|
+
["test"],
|
200
|
+
visit(%({% capture x %}{{ test }}{% endcapture %}))
|
201
|
+
)
|
202
|
+
end
|
203
|
+
|
204
|
+
def test_include
|
205
|
+
assert_equal(
|
206
|
+
["test"],
|
207
|
+
visit(%({% include test %}))
|
208
|
+
)
|
209
|
+
end
|
210
|
+
|
211
|
+
def test_include_with
|
212
|
+
assert_equal(
|
213
|
+
["test"],
|
214
|
+
visit(%({% include "hai" with test %}))
|
215
|
+
)
|
216
|
+
end
|
217
|
+
|
218
|
+
def test_include_for
|
219
|
+
assert_equal(
|
220
|
+
["test"],
|
221
|
+
visit(%({% include "hai" for test %}))
|
222
|
+
)
|
223
|
+
end
|
224
|
+
|
225
|
+
def test_preserve_tree_structure
|
226
|
+
assert_equal(
|
227
|
+
[[nil, [
|
228
|
+
[nil, [[nil, [["other", []]]]]],
|
229
|
+
["test", []],
|
230
|
+
["xs", []]
|
231
|
+
]]],
|
232
|
+
traversal(%({% for x in xs offset: test %}{{ other }}{% endfor %})).visit
|
233
|
+
)
|
234
|
+
end
|
235
|
+
|
236
|
+
private
|
237
|
+
|
238
|
+
def traversal(template)
|
239
|
+
ParseTreeVisitor
|
240
|
+
.for(Template.parse(template).root)
|
241
|
+
.add_callback_for(VariableLookup, &:name)
|
242
|
+
end
|
243
|
+
|
244
|
+
def visit(template)
|
245
|
+
traversal(template).visit.flatten.compact
|
246
|
+
end
|
247
|
+
end
|