liquid 2.6.1 → 4.0.3
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 +5 -5
- data/History.md +194 -29
- data/{MIT-LICENSE → LICENSE} +0 -0
- data/README.md +60 -2
- data/lib/liquid.rb +25 -14
- data/lib/liquid/block.rb +47 -96
- data/lib/liquid/block_body.rb +143 -0
- data/lib/liquid/condition.rb +70 -39
- data/lib/liquid/context.rb +116 -157
- data/lib/liquid/document.rb +19 -9
- data/lib/liquid/drop.rb +31 -14
- data/lib/liquid/errors.rb +54 -10
- data/lib/liquid/expression.rb +49 -0
- data/lib/liquid/extensions.rb +19 -7
- data/lib/liquid/file_system.rb +25 -14
- data/lib/liquid/forloop_drop.rb +42 -0
- data/lib/liquid/i18n.rb +39 -0
- data/lib/liquid/interrupts.rb +2 -3
- 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 +311 -77
- data/lib/liquid/strainer.rb +39 -26
- data/lib/liquid/tablerowloop_drop.rb +62 -0
- data/lib/liquid/tag.rb +28 -11
- data/lib/liquid/tags/assign.rb +34 -10
- data/lib/liquid/tags/break.rb +1 -4
- data/lib/liquid/tags/capture.rb +11 -9
- data/lib/liquid/tags/case.rb +37 -22
- data/lib/liquid/tags/comment.rb +10 -3
- data/lib/liquid/tags/continue.rb +1 -4
- data/lib/liquid/tags/cycle.rb +20 -14
- data/lib/liquid/tags/decrement.rb +4 -8
- data/lib/liquid/tags/for.rb +121 -60
- data/lib/liquid/tags/if.rb +73 -30
- data/lib/liquid/tags/ifchanged.rb +3 -5
- data/lib/liquid/tags/include.rb +77 -46
- data/lib/liquid/tags/increment.rb +4 -8
- data/lib/liquid/tags/raw.rb +35 -10
- data/lib/liquid/tags/table_row.rb +62 -0
- data/lib/liquid/tags/unless.rb +6 -9
- data/lib/liquid/template.rb +130 -32
- data/lib/liquid/tokenizer.rb +31 -0
- data/lib/liquid/truffle.rb +5 -0
- data/lib/liquid/utils.rb +57 -4
- data/lib/liquid/variable.rb +121 -30
- data/lib/liquid/variable_lookup.rb +88 -0
- data/lib/liquid/version.rb +2 -1
- 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/{liquid → integration}/capture_test.rb +13 -3
- 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 +776 -0
- data/test/{liquid → integration}/tags/break_tag_test.rb +2 -3
- data/test/{liquid → integration}/tags/continue_tag_test.rb +1 -2
- 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 +253 -0
- data/test/integration/tags/increment_tag_test.rb +23 -0
- data/test/{liquid → integration}/tags/raw_tag_test.rb +9 -2
- data/test/integration/tags/standard_tag_test.rb +296 -0
- data/test/integration/tags/statements_test.rb +111 -0
- data/test/{liquid/tags/html_tag_test.rb → integration/tags/table_row_test.rb} +25 -24
- 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 +106 -19
- data/test/truffle/truffle_test.rb +9 -0
- data/test/{liquid/block_test.rb → unit/block_unit_test.rb} +9 -9
- data/test/unit/condition_unit_test.rb +166 -0
- data/test/{liquid/context_test.rb → unit/context_unit_test.rb} +85 -74
- 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/{liquid/regexp_test.rb → unit/regexp_unit_test.rb} +4 -4
- 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 +157 -77
- data/lib/extras/liquid_view.rb +0 -51
- data/lib/liquid/htmltags.rb +0 -74
- data/lib/liquid/module_ex.rb +0 -62
- data/test/liquid/assign_test.rb +0 -21
- data/test/liquid/condition_test.rb +0 -127
- data/test/liquid/drop_test.rb +0 -180
- data/test/liquid/error_handling_test.rb +0 -81
- data/test/liquid/file_system_test.rb +0 -29
- data/test/liquid/filter_test.rb +0 -125
- data/test/liquid/hash_ordering_test.rb +0 -25
- data/test/liquid/module_ex_test.rb +0 -87
- data/test/liquid/output_test.rb +0 -116
- data/test/liquid/parsing_quirks_test.rb +0 -52
- data/test/liquid/security_test.rb +0 -64
- data/test/liquid/standard_filter_test.rb +0 -251
- data/test/liquid/strainer_test.rb +0 -52
- data/test/liquid/tags/for_tag_test.rb +0 -297
- data/test/liquid/tags/if_else_tag_test.rb +0 -166
- data/test/liquid/tags/include_tag_test.rb +0 -166
- data/test/liquid/tags/increment_tag_test.rb +0 -24
- data/test/liquid/tags/standard_tag_test.rb +0 -295
- data/test/liquid/tags/statements_test.rb +0 -134
- data/test/liquid/tags/unless_else_tag_test.rb +0 -26
- data/test/liquid/template_test.rb +0 -146
- data/test/liquid/variable_test.rb +0 -186
@@ -1,52 +0,0 @@
|
|
1
|
-
require 'test_helper'
|
2
|
-
|
3
|
-
class ParsingQuirksTest < Test::Unit::TestCase
|
4
|
-
include Liquid
|
5
|
-
|
6
|
-
def test_error_with_css
|
7
|
-
text = %| div { font-weight: bold; } |
|
8
|
-
template = Template.parse(text)
|
9
|
-
|
10
|
-
assert_equal text, template.render
|
11
|
-
assert_equal [String], template.root.nodelist.collect {|i| i.class}
|
12
|
-
end
|
13
|
-
|
14
|
-
def test_raise_on_single_close_bracet
|
15
|
-
assert_raise(SyntaxError) do
|
16
|
-
Template.parse("text {{method} oh nos!")
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
def test_raise_on_label_and_no_close_bracets
|
21
|
-
assert_raise(SyntaxError) do
|
22
|
-
Template.parse("TEST {{ ")
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
def test_raise_on_label_and_no_close_bracets_percent
|
27
|
-
assert_raise(SyntaxError) do
|
28
|
-
Template.parse("TEST {% ")
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
def test_error_on_empty_filter
|
33
|
-
assert_nothing_raised do
|
34
|
-
Template.parse("{{test |a|b|}}")
|
35
|
-
Template.parse("{{test}}")
|
36
|
-
Template.parse("{{|test|}}")
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
def test_meaningless_parens
|
41
|
-
assigns = {'b' => 'bar', 'c' => 'baz'}
|
42
|
-
markup = "a == 'foo' or (b == 'bar' and c == 'baz') or false"
|
43
|
-
assert_template_result(' YES ',"{% if #{markup} %} YES {% endif %}", assigns)
|
44
|
-
end
|
45
|
-
|
46
|
-
def test_unexpected_characters_silently_eat_logic
|
47
|
-
markup = "true && false"
|
48
|
-
assert_template_result(' YES ',"{% if #{markup} %} YES {% endif %}")
|
49
|
-
markup = "false || true"
|
50
|
-
assert_template_result('',"{% if #{markup} %} YES {% endif %}")
|
51
|
-
end
|
52
|
-
end # ParsingQuirksTest
|
@@ -1,64 +0,0 @@
|
|
1
|
-
require 'test_helper'
|
2
|
-
|
3
|
-
module SecurityFilter
|
4
|
-
def add_one(input)
|
5
|
-
"#{input} + 1"
|
6
|
-
end
|
7
|
-
end
|
8
|
-
|
9
|
-
class SecurityTest < Test::Unit::TestCase
|
10
|
-
include Liquid
|
11
|
-
|
12
|
-
def test_no_instance_eval
|
13
|
-
text = %( {{ '1+1' | instance_eval }} )
|
14
|
-
expected = %| 1+1 |
|
15
|
-
|
16
|
-
assert_equal expected, Template.parse(text).render(@assigns)
|
17
|
-
end
|
18
|
-
|
19
|
-
def test_no_existing_instance_eval
|
20
|
-
text = %( {{ '1+1' | __instance_eval__ }} )
|
21
|
-
expected = %| 1+1 |
|
22
|
-
|
23
|
-
assert_equal expected, Template.parse(text).render(@assigns)
|
24
|
-
end
|
25
|
-
|
26
|
-
|
27
|
-
def test_no_instance_eval_after_mixing_in_new_filter
|
28
|
-
text = %( {{ '1+1' | instance_eval }} )
|
29
|
-
expected = %| 1+1 |
|
30
|
-
|
31
|
-
assert_equal expected, Template.parse(text).render(@assigns)
|
32
|
-
end
|
33
|
-
|
34
|
-
|
35
|
-
def test_no_instance_eval_later_in_chain
|
36
|
-
text = %( {{ '1+1' | add_one | instance_eval }} )
|
37
|
-
expected = %| 1+1 + 1 |
|
38
|
-
|
39
|
-
assert_equal expected, Template.parse(text).render(@assigns, :filters => SecurityFilter)
|
40
|
-
end
|
41
|
-
|
42
|
-
def test_does_not_add_filters_to_symbol_table
|
43
|
-
current_symbols = Symbol.all_symbols
|
44
|
-
|
45
|
-
test = %( {{ "some_string" | a_bad_filter }} )
|
46
|
-
|
47
|
-
template = Template.parse(test)
|
48
|
-
assert_equal [], (Symbol.all_symbols - current_symbols)
|
49
|
-
|
50
|
-
template.render
|
51
|
-
assert_equal [], (Symbol.all_symbols - current_symbols)
|
52
|
-
end
|
53
|
-
|
54
|
-
def test_does_not_add_drop_methods_to_symbol_table
|
55
|
-
current_symbols = Symbol.all_symbols
|
56
|
-
|
57
|
-
drop = Drop.new
|
58
|
-
drop.invoke_drop("custom_method_1")
|
59
|
-
drop.invoke_drop("custom_method_2")
|
60
|
-
drop.invoke_drop("custom_method_3")
|
61
|
-
|
62
|
-
assert_equal [], (Symbol.all_symbols - current_symbols)
|
63
|
-
end
|
64
|
-
end # SecurityTest
|
@@ -1,251 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
require 'test_helper'
|
4
|
-
|
5
|
-
class Filters
|
6
|
-
include Liquid::StandardFilters
|
7
|
-
end
|
8
|
-
|
9
|
-
class TestThing
|
10
|
-
def initialize
|
11
|
-
@foo = 0
|
12
|
-
end
|
13
|
-
|
14
|
-
def to_s
|
15
|
-
"woot: #{@foo}"
|
16
|
-
end
|
17
|
-
|
18
|
-
def to_liquid
|
19
|
-
@foo += 1
|
20
|
-
self
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
class TestDrop < Liquid::Drop
|
25
|
-
def test
|
26
|
-
"testfoo"
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
|
-
class StandardFiltersTest < Test::Unit::TestCase
|
31
|
-
include Liquid
|
32
|
-
|
33
|
-
def setup
|
34
|
-
@filters = Filters.new
|
35
|
-
end
|
36
|
-
|
37
|
-
def test_size
|
38
|
-
assert_equal 3, @filters.size([1,2,3])
|
39
|
-
assert_equal 0, @filters.size([])
|
40
|
-
assert_equal 0, @filters.size(nil)
|
41
|
-
end
|
42
|
-
|
43
|
-
def test_downcase
|
44
|
-
assert_equal 'testing', @filters.downcase("Testing")
|
45
|
-
assert_equal '', @filters.downcase(nil)
|
46
|
-
end
|
47
|
-
|
48
|
-
def test_upcase
|
49
|
-
assert_equal 'TESTING', @filters.upcase("Testing")
|
50
|
-
assert_equal '', @filters.upcase(nil)
|
51
|
-
end
|
52
|
-
|
53
|
-
def test_upcase
|
54
|
-
assert_equal 'TESTING', @filters.upcase("Testing")
|
55
|
-
assert_equal '', @filters.upcase(nil)
|
56
|
-
end
|
57
|
-
|
58
|
-
def test_truncate
|
59
|
-
assert_equal '1234...', @filters.truncate('1234567890', 7)
|
60
|
-
assert_equal '1234567890', @filters.truncate('1234567890', 20)
|
61
|
-
assert_equal '...', @filters.truncate('1234567890', 0)
|
62
|
-
assert_equal '1234567890', @filters.truncate('1234567890')
|
63
|
-
assert_equal "测试...", @filters.truncate("测试测试测试测试", 5)
|
64
|
-
end
|
65
|
-
|
66
|
-
def test_strip
|
67
|
-
assert_equal ['12','34'], @filters.split('12~34', '~')
|
68
|
-
assert_equal ['A? ',' ,Z'], @filters.split('A? ~ ~ ~ ,Z', '~ ~ ~')
|
69
|
-
assert_equal ['A?Z'], @filters.split('A?Z', '~')
|
70
|
-
# Regexp works although Liquid does not support.
|
71
|
-
assert_equal ['A','Z'], @filters.split('AxZ', /x/)
|
72
|
-
end
|
73
|
-
|
74
|
-
def test_escape
|
75
|
-
assert_equal '<strong>', @filters.escape('<strong>')
|
76
|
-
assert_equal '<strong>', @filters.h('<strong>')
|
77
|
-
end
|
78
|
-
|
79
|
-
def test_escape_once
|
80
|
-
assert_equal '<strong>', @filters.escape_once(@filters.escape('<strong>'))
|
81
|
-
end
|
82
|
-
|
83
|
-
def test_truncatewords
|
84
|
-
assert_equal 'one two three', @filters.truncatewords('one two three', 4)
|
85
|
-
assert_equal 'one two...', @filters.truncatewords('one two three', 2)
|
86
|
-
assert_equal 'one two three', @filters.truncatewords('one two three')
|
87
|
-
assert_equal 'Two small (13” x 5.5” x 10” high) baskets fit inside one large basket (13”...', @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)
|
88
|
-
assert_equal "测试测试测试测试", @filters.truncatewords('测试测试测试测试', 5)
|
89
|
-
end
|
90
|
-
|
91
|
-
def test_strip_html
|
92
|
-
assert_equal 'test', @filters.strip_html("<div>test</div>")
|
93
|
-
assert_equal 'test', @filters.strip_html("<div id='test'>test</div>")
|
94
|
-
assert_equal '', @filters.strip_html("<script type='text/javascript'>document.write('some stuff');</script>")
|
95
|
-
assert_equal '', @filters.strip_html("<style type='text/css'>foo bar</style>")
|
96
|
-
assert_equal 'test', @filters.strip_html("<div\nclass='multiline'>test</div>")
|
97
|
-
assert_equal 'test', @filters.strip_html("<!-- foo bar \n test -->test")
|
98
|
-
assert_equal '', @filters.strip_html(nil)
|
99
|
-
end
|
100
|
-
|
101
|
-
def test_join
|
102
|
-
assert_equal '1 2 3 4', @filters.join([1,2,3,4])
|
103
|
-
assert_equal '1 - 2 - 3 - 4', @filters.join([1,2,3,4], ' - ')
|
104
|
-
end
|
105
|
-
|
106
|
-
def test_sort
|
107
|
-
assert_equal [1,2,3,4], @filters.sort([4,3,2,1])
|
108
|
-
assert_equal [{"a" => 1}, {"a" => 2}, {"a" => 3}, {"a" => 4}], @filters.sort([{"a" => 4}, {"a" => 3}, {"a" => 1}, {"a" => 2}], "a")
|
109
|
-
end
|
110
|
-
|
111
|
-
def test_reverse
|
112
|
-
assert_equal [4,3,2,1], @filters.reverse([1,2,3,4])
|
113
|
-
end
|
114
|
-
|
115
|
-
def test_map
|
116
|
-
assert_equal [1,2,3,4], @filters.map([{"a" => 1}, {"a" => 2}, {"a" => 3}, {"a" => 4}], 'a')
|
117
|
-
assert_template_result 'abc', "{{ ary | map:'foo' | map:'bar' }}",
|
118
|
-
'ary' => [{'foo' => {'bar' => 'a'}}, {'foo' => {'bar' => 'b'}}, {'foo' => {'bar' => 'c'}}]
|
119
|
-
end
|
120
|
-
|
121
|
-
def test_map_doesnt_call_arbitrary_stuff
|
122
|
-
assert_equal "", Liquid::Template.parse('{{ "foo" | map: "__id__" }}').render
|
123
|
-
assert_equal "", Liquid::Template.parse('{{ "foo" | map: "inspect" }}').render
|
124
|
-
end
|
125
|
-
|
126
|
-
def test_map_calls_to_liquid
|
127
|
-
t = TestThing.new
|
128
|
-
assert_equal "woot: 1", Liquid::Template.parse('{{ foo }}').render("foo" => t)
|
129
|
-
end
|
130
|
-
|
131
|
-
def test_map_over_proc
|
132
|
-
drop = TestDrop.new
|
133
|
-
p = Proc.new{ drop }
|
134
|
-
templ = '{{ procs | map: "test" }}'
|
135
|
-
assert_equal "testfoo", Liquid::Template.parse(templ).render("procs" => [p])
|
136
|
-
end
|
137
|
-
|
138
|
-
def test_date
|
139
|
-
assert_equal 'May', @filters.date(Time.parse("2006-05-05 10:00:00"), "%B")
|
140
|
-
assert_equal 'June', @filters.date(Time.parse("2006-06-05 10:00:00"), "%B")
|
141
|
-
assert_equal 'July', @filters.date(Time.parse("2006-07-05 10:00:00"), "%B")
|
142
|
-
|
143
|
-
assert_equal 'May', @filters.date("2006-05-05 10:00:00", "%B")
|
144
|
-
assert_equal 'June', @filters.date("2006-06-05 10:00:00", "%B")
|
145
|
-
assert_equal 'July', @filters.date("2006-07-05 10:00:00", "%B")
|
146
|
-
|
147
|
-
assert_equal '2006-07-05 10:00:00', @filters.date("2006-07-05 10:00:00", "")
|
148
|
-
assert_equal '2006-07-05 10:00:00', @filters.date("2006-07-05 10:00:00", "")
|
149
|
-
assert_equal '2006-07-05 10:00:00', @filters.date("2006-07-05 10:00:00", "")
|
150
|
-
assert_equal '2006-07-05 10:00:00', @filters.date("2006-07-05 10:00:00", nil)
|
151
|
-
|
152
|
-
assert_equal '07/05/2006', @filters.date("2006-07-05 10:00:00", "%m/%d/%Y")
|
153
|
-
|
154
|
-
assert_equal "07/16/2004", @filters.date("Fri Jul 16 01:00:00 2004", "%m/%d/%Y")
|
155
|
-
assert_equal "#{Date.today.year}", @filters.date('now', '%Y')
|
156
|
-
assert_equal "#{Date.today.year}", @filters.date('today', '%Y')
|
157
|
-
|
158
|
-
assert_equal nil, @filters.date(nil, "%B")
|
159
|
-
|
160
|
-
assert_equal "07/05/2006", @filters.date(1152098955, "%m/%d/%Y")
|
161
|
-
assert_equal "07/05/2006", @filters.date("1152098955", "%m/%d/%Y")
|
162
|
-
end
|
163
|
-
|
164
|
-
|
165
|
-
def test_first_last
|
166
|
-
assert_equal 1, @filters.first([1,2,3])
|
167
|
-
assert_equal 3, @filters.last([1,2,3])
|
168
|
-
assert_equal nil, @filters.first([])
|
169
|
-
assert_equal nil, @filters.last([])
|
170
|
-
end
|
171
|
-
|
172
|
-
def test_replace
|
173
|
-
assert_equal '2 2 2 2', @filters.replace('1 1 1 1', '1', 2)
|
174
|
-
assert_equal '2 1 1 1', @filters.replace_first('1 1 1 1', '1', 2)
|
175
|
-
assert_template_result '2 1 1 1', "{{ '1 1 1 1' | replace_first: '1', 2 }}"
|
176
|
-
end
|
177
|
-
|
178
|
-
def test_remove
|
179
|
-
assert_equal ' ', @filters.remove("a a a a", 'a')
|
180
|
-
assert_equal 'a a a', @filters.remove_first("a a a a", 'a ')
|
181
|
-
assert_template_result 'a a a', "{{ 'a a a a' | remove_first: 'a ' }}"
|
182
|
-
end
|
183
|
-
|
184
|
-
def test_pipes_in_string_arguments
|
185
|
-
assert_template_result 'foobar', "{{ 'foo|bar' | remove: '|' }}"
|
186
|
-
end
|
187
|
-
|
188
|
-
def test_strip_newlines
|
189
|
-
assert_template_result 'abc', "{{ source | strip_newlines }}", 'source' => "a\nb\nc"
|
190
|
-
assert_template_result 'abc', "{{ source | strip_newlines }}", 'source' => "a\r\nb\nc"
|
191
|
-
end
|
192
|
-
|
193
|
-
def test_newlines_to_br
|
194
|
-
assert_template_result "a<br />\nb<br />\nc", "{{ source | newline_to_br }}", 'source' => "a\nb\nc"
|
195
|
-
end
|
196
|
-
|
197
|
-
def test_plus
|
198
|
-
assert_template_result "2", "{{ 1 | plus:1 }}"
|
199
|
-
assert_template_result "2.0", "{{ '1' | plus:'1.0' }}"
|
200
|
-
end
|
201
|
-
|
202
|
-
def test_minus
|
203
|
-
assert_template_result "4", "{{ input | minus:operand }}", 'input' => 5, 'operand' => 1
|
204
|
-
assert_template_result "2.3", "{{ '4.3' | minus:'2' }}"
|
205
|
-
end
|
206
|
-
|
207
|
-
def test_times
|
208
|
-
assert_template_result "12", "{{ 3 | times:4 }}"
|
209
|
-
assert_template_result "0", "{{ 'foo' | times:4 }}"
|
210
|
-
|
211
|
-
# Ruby v1.9.2-rc1, or higher, backwards compatible Float test
|
212
|
-
assert_match(/(6\.3)|(6\.(0{13})1)/, Template.parse("{{ '2.1' | times:3 }}").render)
|
213
|
-
|
214
|
-
assert_template_result "6", "{{ '2.1' | times:3 | replace: '.','-' | plus:0}}"
|
215
|
-
|
216
|
-
assert_template_result "7.25", "{{ 0.0725 | times:100 }}"
|
217
|
-
end
|
218
|
-
|
219
|
-
def test_divided_by
|
220
|
-
assert_template_result "4", "{{ 12 | divided_by:3 }}"
|
221
|
-
assert_template_result "4", "{{ 14 | divided_by:3 }}"
|
222
|
-
|
223
|
-
# Ruby v1.9.2-rc1, or higher, backwards compatible Float test
|
224
|
-
assert_match(/4\.(6{13,14})7/, Template.parse("{{ 14 | divided_by:'3.0' }}").render)
|
225
|
-
|
226
|
-
assert_template_result "5", "{{ 15 | divided_by:3 }}"
|
227
|
-
assert_template_result "Liquid error: divided by 0", "{{ 5 | divided_by:0 }}"
|
228
|
-
|
229
|
-
assert_template_result "0.5", "{{ 2.0 | divided_by:4 }}"
|
230
|
-
end
|
231
|
-
|
232
|
-
def test_modulo
|
233
|
-
assert_template_result "1", "{{ 3 | modulo:2 }}"
|
234
|
-
end
|
235
|
-
|
236
|
-
def test_append
|
237
|
-
assigns = {'a' => 'bc', 'b' => 'd' }
|
238
|
-
assert_template_result('bcd',"{{ a | append: 'd'}}",assigns)
|
239
|
-
assert_template_result('bcd',"{{ a | append: b}}",assigns)
|
240
|
-
end
|
241
|
-
|
242
|
-
def test_prepend
|
243
|
-
assigns = {'a' => 'bc', 'b' => 'a' }
|
244
|
-
assert_template_result('abc',"{{ a | prepend: 'a'}}",assigns)
|
245
|
-
assert_template_result('abc',"{{ a | prepend: b}}",assigns)
|
246
|
-
end
|
247
|
-
|
248
|
-
def test_cannot_access_private_methods
|
249
|
-
assert_template_result('a',"{{ 'a' | to_number }}")
|
250
|
-
end
|
251
|
-
end # StandardFiltersTest
|
@@ -1,52 +0,0 @@
|
|
1
|
-
require 'test_helper'
|
2
|
-
|
3
|
-
class StrainerTest < Test::Unit::TestCase
|
4
|
-
include Liquid
|
5
|
-
|
6
|
-
module AccessScopeFilters
|
7
|
-
def public_filter
|
8
|
-
"public"
|
9
|
-
end
|
10
|
-
|
11
|
-
def private_filter
|
12
|
-
"private"
|
13
|
-
end
|
14
|
-
private :private_filter
|
15
|
-
end
|
16
|
-
|
17
|
-
Strainer.global_filter(AccessScopeFilters)
|
18
|
-
|
19
|
-
def test_strainer
|
20
|
-
strainer = Strainer.create(nil)
|
21
|
-
assert_equal 5, strainer.invoke('size', 'input')
|
22
|
-
assert_equal "public", strainer.invoke("public_filter")
|
23
|
-
end
|
24
|
-
|
25
|
-
def test_strainer_only_invokes_public_filter_methods
|
26
|
-
strainer = Strainer.create(nil)
|
27
|
-
assert_equal false, strainer.invokable?('__test__')
|
28
|
-
assert_equal false, strainer.invokable?('test')
|
29
|
-
assert_equal false, strainer.invokable?('instance_eval')
|
30
|
-
assert_equal false, strainer.invokable?('__send__')
|
31
|
-
assert_equal true, strainer.invokable?('size') # from the standard lib
|
32
|
-
end
|
33
|
-
|
34
|
-
def test_strainer_returns_nil_if_no_filter_method_found
|
35
|
-
strainer = Strainer.create(nil)
|
36
|
-
assert_nil strainer.invoke("private_filter")
|
37
|
-
assert_nil strainer.invoke("undef_the_filter")
|
38
|
-
end
|
39
|
-
|
40
|
-
def test_strainer_returns_first_argument_if_no_method_and_arguments_given
|
41
|
-
strainer = Strainer.create(nil)
|
42
|
-
assert_equal "password", strainer.invoke("undef_the_method", "password")
|
43
|
-
end
|
44
|
-
|
45
|
-
def test_strainer_only_allows_methods_defined_in_filters
|
46
|
-
strainer = Strainer.create(nil)
|
47
|
-
assert_equal "1 + 1", strainer.invoke("instance_eval", "1 + 1")
|
48
|
-
assert_equal "puts", strainer.invoke("__send__", "puts", "Hi Mom")
|
49
|
-
assert_equal "has_method?", strainer.invoke("invoke", "has_method?", "invoke")
|
50
|
-
end
|
51
|
-
|
52
|
-
end # StrainerTest
|
@@ -1,297 +0,0 @@
|
|
1
|
-
require 'test_helper'
|
2
|
-
|
3
|
-
class ForTagTest < Test::Unit::TestCase
|
4
|
-
include Liquid
|
5
|
-
|
6
|
-
def test_for
|
7
|
-
assert_template_result(' yo yo yo yo ','{%for item in array%} yo {%endfor%}','array' => [1,2,3,4])
|
8
|
-
assert_template_result('yoyo','{%for item in array%}yo{%endfor%}','array' => [1,2])
|
9
|
-
assert_template_result(' yo ','{%for item in array%} yo {%endfor%}','array' => [1])
|
10
|
-
assert_template_result('','{%for item in array%}{%endfor%}','array' => [1,2])
|
11
|
-
expected = <<HERE
|
12
|
-
|
13
|
-
yo
|
14
|
-
|
15
|
-
yo
|
16
|
-
|
17
|
-
yo
|
18
|
-
|
19
|
-
HERE
|
20
|
-
template = <<HERE
|
21
|
-
{%for item in array%}
|
22
|
-
yo
|
23
|
-
{%endfor%}
|
24
|
-
HERE
|
25
|
-
assert_template_result(expected,template,'array' => [1,2,3])
|
26
|
-
end
|
27
|
-
|
28
|
-
def test_for_reversed
|
29
|
-
assigns = {'array' => [ 1, 2, 3] }
|
30
|
-
assert_template_result('321','{%for item in array reversed %}{{item}}{%endfor%}',assigns)
|
31
|
-
end
|
32
|
-
|
33
|
-
def test_for_with_range
|
34
|
-
assert_template_result(' 1 2 3 ','{%for item in (1..3) %} {{item}} {%endfor%}')
|
35
|
-
end
|
36
|
-
|
37
|
-
def test_for_with_variable
|
38
|
-
assert_template_result(' 1 2 3 ','{%for item in array%} {{item}} {%endfor%}','array' => [1,2,3])
|
39
|
-
assert_template_result('123','{%for item in array%}{{item}}{%endfor%}','array' => [1,2,3])
|
40
|
-
assert_template_result('123','{% for item in array %}{{item}}{% endfor %}','array' => [1,2,3])
|
41
|
-
assert_template_result('abcd','{%for item in array%}{{item}}{%endfor%}','array' => ['a','b','c','d'])
|
42
|
-
assert_template_result('a b c','{%for item in array%}{{item}}{%endfor%}','array' => ['a',' ','b',' ','c'])
|
43
|
-
assert_template_result('abc','{%for item in array%}{{item}}{%endfor%}','array' => ['a','','b','','c'])
|
44
|
-
end
|
45
|
-
|
46
|
-
def test_for_helpers
|
47
|
-
assigns = {'array' => [1,2,3] }
|
48
|
-
assert_template_result(' 1/3 2/3 3/3 ',
|
49
|
-
'{%for item in array%} {{forloop.index}}/{{forloop.length}} {%endfor%}',
|
50
|
-
assigns)
|
51
|
-
assert_template_result(' 1 2 3 ', '{%for item in array%} {{forloop.index}} {%endfor%}', assigns)
|
52
|
-
assert_template_result(' 0 1 2 ', '{%for item in array%} {{forloop.index0}} {%endfor%}', assigns)
|
53
|
-
assert_template_result(' 2 1 0 ', '{%for item in array%} {{forloop.rindex0}} {%endfor%}', assigns)
|
54
|
-
assert_template_result(' 3 2 1 ', '{%for item in array%} {{forloop.rindex}} {%endfor%}', assigns)
|
55
|
-
assert_template_result(' true false false ', '{%for item in array%} {{forloop.first}} {%endfor%}', assigns)
|
56
|
-
assert_template_result(' false false true ', '{%for item in array%} {{forloop.last}} {%endfor%}', assigns)
|
57
|
-
end
|
58
|
-
|
59
|
-
def test_for_and_if
|
60
|
-
assigns = {'array' => [1,2,3] }
|
61
|
-
assert_template_result('+--',
|
62
|
-
'{%for item in array%}{% if forloop.first %}+{% else %}-{% endif %}{%endfor%}',
|
63
|
-
assigns)
|
64
|
-
end
|
65
|
-
|
66
|
-
def test_for_else
|
67
|
-
assert_template_result('+++', '{%for item in array%}+{%else%}-{%endfor%}', 'array'=>[1,2,3])
|
68
|
-
assert_template_result('-', '{%for item in array%}+{%else%}-{%endfor%}', 'array'=>[])
|
69
|
-
assert_template_result('-', '{%for item in array%}+{%else%}-{%endfor%}', 'array'=>nil)
|
70
|
-
end
|
71
|
-
|
72
|
-
def test_limiting
|
73
|
-
assigns = {'array' => [1,2,3,4,5,6,7,8,9,0]}
|
74
|
-
assert_template_result('12', '{%for i in array limit:2 %}{{ i }}{%endfor%}', assigns)
|
75
|
-
assert_template_result('1234', '{%for i in array limit:4 %}{{ i }}{%endfor%}', assigns)
|
76
|
-
assert_template_result('3456', '{%for i in array limit:4 offset:2 %}{{ i }}{%endfor%}', assigns)
|
77
|
-
assert_template_result('3456', '{%for i in array limit: 4 offset: 2 %}{{ i }}{%endfor%}', assigns)
|
78
|
-
end
|
79
|
-
|
80
|
-
def test_dynamic_variable_limiting
|
81
|
-
assigns = {'array' => [1,2,3,4,5,6,7,8,9,0]}
|
82
|
-
assigns['limit'] = 2
|
83
|
-
assigns['offset'] = 2
|
84
|
-
|
85
|
-
assert_template_result('34', '{%for i in array limit: limit offset: offset %}{{ i }}{%endfor%}', assigns)
|
86
|
-
end
|
87
|
-
|
88
|
-
def test_nested_for
|
89
|
-
assigns = {'array' => [[1,2],[3,4],[5,6]] }
|
90
|
-
assert_template_result('123456', '{%for item in array%}{%for i in item%}{{ i }}{%endfor%}{%endfor%}', assigns)
|
91
|
-
end
|
92
|
-
|
93
|
-
def test_offset_only
|
94
|
-
assigns = {'array' => [1,2,3,4,5,6,7,8,9,0]}
|
95
|
-
assert_template_result('890', '{%for i in array offset:7 %}{{ i }}{%endfor%}', assigns)
|
96
|
-
end
|
97
|
-
|
98
|
-
def test_pause_resume
|
99
|
-
assigns = {'array' => {'items' => [1,2,3,4,5,6,7,8,9,0]}}
|
100
|
-
markup = <<-MKUP
|
101
|
-
{%for i in array.items limit: 3 %}{{i}}{%endfor%}
|
102
|
-
next
|
103
|
-
{%for i in array.items offset:continue limit: 3 %}{{i}}{%endfor%}
|
104
|
-
next
|
105
|
-
{%for i in array.items offset:continue limit: 3 %}{{i}}{%endfor%}
|
106
|
-
MKUP
|
107
|
-
expected = <<-XPCTD
|
108
|
-
123
|
109
|
-
next
|
110
|
-
456
|
111
|
-
next
|
112
|
-
789
|
113
|
-
XPCTD
|
114
|
-
assert_template_result(expected,markup,assigns)
|
115
|
-
end
|
116
|
-
|
117
|
-
def test_pause_resume_limit
|
118
|
-
assigns = {'array' => {'items' => [1,2,3,4,5,6,7,8,9,0]}}
|
119
|
-
markup = <<-MKUP
|
120
|
-
{%for i in array.items limit:3 %}{{i}}{%endfor%}
|
121
|
-
next
|
122
|
-
{%for i in array.items offset:continue limit:3 %}{{i}}{%endfor%}
|
123
|
-
next
|
124
|
-
{%for i in array.items offset:continue limit:1 %}{{i}}{%endfor%}
|
125
|
-
MKUP
|
126
|
-
expected = <<-XPCTD
|
127
|
-
123
|
128
|
-
next
|
129
|
-
456
|
130
|
-
next
|
131
|
-
7
|
132
|
-
XPCTD
|
133
|
-
assert_template_result(expected,markup,assigns)
|
134
|
-
end
|
135
|
-
|
136
|
-
def test_pause_resume_BIG_limit
|
137
|
-
assigns = {'array' => {'items' => [1,2,3,4,5,6,7,8,9,0]}}
|
138
|
-
markup = <<-MKUP
|
139
|
-
{%for i in array.items limit:3 %}{{i}}{%endfor%}
|
140
|
-
next
|
141
|
-
{%for i in array.items offset:continue limit:3 %}{{i}}{%endfor%}
|
142
|
-
next
|
143
|
-
{%for i in array.items offset:continue limit:1000 %}{{i}}{%endfor%}
|
144
|
-
MKUP
|
145
|
-
expected = <<-XPCTD
|
146
|
-
123
|
147
|
-
next
|
148
|
-
456
|
149
|
-
next
|
150
|
-
7890
|
151
|
-
XPCTD
|
152
|
-
assert_template_result(expected,markup,assigns)
|
153
|
-
end
|
154
|
-
|
155
|
-
|
156
|
-
def test_pause_resume_BIG_offset
|
157
|
-
assigns = {'array' => {'items' => [1,2,3,4,5,6,7,8,9,0]}}
|
158
|
-
markup = %q({%for i in array.items limit:3 %}{{i}}{%endfor%}
|
159
|
-
next
|
160
|
-
{%for i in array.items offset:continue limit:3 %}{{i}}{%endfor%}
|
161
|
-
next
|
162
|
-
{%for i in array.items offset:continue limit:3 offset:1000 %}{{i}}{%endfor%})
|
163
|
-
expected = %q(123
|
164
|
-
next
|
165
|
-
456
|
166
|
-
next
|
167
|
-
)
|
168
|
-
assert_template_result(expected,markup,assigns)
|
169
|
-
end
|
170
|
-
|
171
|
-
def test_for_with_break
|
172
|
-
assigns = {'array' => {'items' => [1,2,3,4,5,6,7,8,9,10]}}
|
173
|
-
|
174
|
-
markup = '{% for i in array.items %}{% break %}{% endfor %}'
|
175
|
-
expected = ""
|
176
|
-
assert_template_result(expected,markup,assigns)
|
177
|
-
|
178
|
-
markup = '{% for i in array.items %}{{ i }}{% break %}{% endfor %}'
|
179
|
-
expected = "1"
|
180
|
-
assert_template_result(expected,markup,assigns)
|
181
|
-
|
182
|
-
markup = '{% for i in array.items %}{% break %}{{ i }}{% endfor %}'
|
183
|
-
expected = ""
|
184
|
-
assert_template_result(expected,markup,assigns)
|
185
|
-
|
186
|
-
markup = '{% for i in array.items %}{{ i }}{% if i > 3 %}{% break %}{% endif %}{% endfor %}'
|
187
|
-
expected = "1234"
|
188
|
-
assert_template_result(expected,markup,assigns)
|
189
|
-
|
190
|
-
# tests to ensure it only breaks out of the local for loop
|
191
|
-
# and not all of them.
|
192
|
-
assigns = {'array' => [[1,2],[3,4],[5,6]] }
|
193
|
-
markup = '{% for item in array %}' +
|
194
|
-
'{% for i in item %}' +
|
195
|
-
'{% if i == 1 %}' +
|
196
|
-
'{% break %}' +
|
197
|
-
'{% endif %}' +
|
198
|
-
'{{ i }}' +
|
199
|
-
'{% endfor %}' +
|
200
|
-
'{% endfor %}'
|
201
|
-
expected = '3456'
|
202
|
-
assert_template_result(expected, markup, assigns)
|
203
|
-
|
204
|
-
# test break does nothing when unreached
|
205
|
-
assigns = {'array' => {'items' => [1,2,3,4,5]}}
|
206
|
-
markup = '{% for i in array.items %}{% if i == 9999 %}{% break %}{% endif %}{{ i }}{% endfor %}'
|
207
|
-
expected = '12345'
|
208
|
-
assert_template_result(expected, markup, assigns)
|
209
|
-
end
|
210
|
-
|
211
|
-
def test_for_with_continue
|
212
|
-
assigns = {'array' => {'items' => [1,2,3,4,5]}}
|
213
|
-
|
214
|
-
markup = '{% for i in array.items %}{% continue %}{% endfor %}'
|
215
|
-
expected = ""
|
216
|
-
assert_template_result(expected,markup,assigns)
|
217
|
-
|
218
|
-
markup = '{% for i in array.items %}{{ i }}{% continue %}{% endfor %}'
|
219
|
-
expected = "12345"
|
220
|
-
assert_template_result(expected,markup,assigns)
|
221
|
-
|
222
|
-
markup = '{% for i in array.items %}{% continue %}{{ i }}{% endfor %}'
|
223
|
-
expected = ""
|
224
|
-
assert_template_result(expected,markup,assigns)
|
225
|
-
|
226
|
-
markup = '{% for i in array.items %}{% if i > 3 %}{% continue %}{% endif %}{{ i }}{% endfor %}'
|
227
|
-
expected = "123"
|
228
|
-
assert_template_result(expected,markup,assigns)
|
229
|
-
|
230
|
-
markup = '{% for i in array.items %}{% if i == 3 %}{% continue %}{% else %}{{ i }}{% endif %}{% endfor %}'
|
231
|
-
expected = "1245"
|
232
|
-
assert_template_result(expected,markup,assigns)
|
233
|
-
|
234
|
-
# tests to ensure it only continues the local for loop and not all of them.
|
235
|
-
assigns = {'array' => [[1,2],[3,4],[5,6]] }
|
236
|
-
markup = '{% for item in array %}' +
|
237
|
-
'{% for i in item %}' +
|
238
|
-
'{% if i == 1 %}' +
|
239
|
-
'{% continue %}' +
|
240
|
-
'{% endif %}' +
|
241
|
-
'{{ i }}' +
|
242
|
-
'{% endfor %}' +
|
243
|
-
'{% endfor %}'
|
244
|
-
expected = '23456'
|
245
|
-
assert_template_result(expected, markup, assigns)
|
246
|
-
|
247
|
-
# test continue does nothing when unreached
|
248
|
-
assigns = {'array' => {'items' => [1,2,3,4,5]}}
|
249
|
-
markup = '{% for i in array.items %}{% if i == 9999 %}{% continue %}{% endif %}{{ i }}{% endfor %}'
|
250
|
-
expected = '12345'
|
251
|
-
assert_template_result(expected, markup, assigns)
|
252
|
-
end
|
253
|
-
|
254
|
-
def test_for_tag_string
|
255
|
-
# ruby 1.8.7 "String".each => Enumerator with single "String" element.
|
256
|
-
# ruby 1.9.3 no longer supports .each on String though we mimic
|
257
|
-
# the functionality for backwards compatibility
|
258
|
-
|
259
|
-
assert_template_result('test string',
|
260
|
-
'{%for val in string%}{{val}}{%endfor%}',
|
261
|
-
'string' => "test string")
|
262
|
-
|
263
|
-
assert_template_result('test string',
|
264
|
-
'{%for val in string limit:1%}{{val}}{%endfor%}',
|
265
|
-
'string' => "test string")
|
266
|
-
|
267
|
-
assert_template_result('val-string-1-1-0-1-0-true-true-test string',
|
268
|
-
'{%for val in string%}' +
|
269
|
-
'{{forloop.name}}-' +
|
270
|
-
'{{forloop.index}}-' +
|
271
|
-
'{{forloop.length}}-' +
|
272
|
-
'{{forloop.index0}}-' +
|
273
|
-
'{{forloop.rindex}}-' +
|
274
|
-
'{{forloop.rindex0}}-' +
|
275
|
-
'{{forloop.first}}-' +
|
276
|
-
'{{forloop.last}}-' +
|
277
|
-
'{{val}}{%endfor%}',
|
278
|
-
'string' => "test string")
|
279
|
-
end
|
280
|
-
|
281
|
-
def test_blank_string_not_iterable
|
282
|
-
assert_template_result('', "{% for char in characters %}I WILL NOT BE OUTPUT{% endfor %}", 'characters' => '')
|
283
|
-
end
|
284
|
-
|
285
|
-
def test_bad_variable_naming_in_for_loop
|
286
|
-
assert_raise(Liquid::SyntaxError) do
|
287
|
-
Liquid::Template.parse('{% for a/b in x %}{% endfor %}')
|
288
|
-
end
|
289
|
-
end
|
290
|
-
|
291
|
-
def test_spacing_with_variable_naming_in_for_loop
|
292
|
-
expected = '12345'
|
293
|
-
template = '{% for item in items %}{{item}}{% endfor %}'
|
294
|
-
assigns = {'items' => [1,2,3,4,5]}
|
295
|
-
assert_template_result(expected, template, assigns)
|
296
|
-
end
|
297
|
-
end
|