liquid 2.6.3 → 3.0.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/History.md +42 -13
- data/README.md +27 -2
- data/lib/liquid.rb +11 -11
- data/lib/liquid/block.rb +75 -45
- data/lib/liquid/condition.rb +15 -11
- data/lib/liquid/context.rb +68 -29
- data/lib/liquid/document.rb +3 -3
- data/lib/liquid/drop.rb +17 -1
- data/lib/liquid/file_system.rb +17 -6
- data/lib/liquid/i18n.rb +39 -0
- data/lib/liquid/interrupts.rb +1 -1
- data/lib/liquid/lexer.rb +51 -0
- data/lib/liquid/locales/en.yml +22 -0
- data/lib/liquid/parser.rb +90 -0
- data/lib/liquid/standardfilters.rb +115 -52
- data/lib/liquid/strainer.rb +14 -4
- data/lib/liquid/tag.rb +42 -7
- data/lib/liquid/tags/assign.rb +10 -8
- data/lib/liquid/tags/break.rb +1 -1
- data/lib/liquid/tags/capture.rb +10 -8
- data/lib/liquid/tags/case.rb +13 -13
- data/lib/liquid/tags/comment.rb +9 -2
- data/lib/liquid/tags/continue.rb +1 -4
- data/lib/liquid/tags/cycle.rb +5 -7
- data/lib/liquid/tags/decrement.rb +3 -4
- data/lib/liquid/tags/for.rb +69 -36
- data/lib/liquid/tags/if.rb +52 -25
- data/lib/liquid/tags/ifchanged.rb +2 -2
- data/lib/liquid/tags/include.rb +8 -7
- data/lib/liquid/tags/increment.rb +4 -8
- data/lib/liquid/tags/raw.rb +3 -3
- data/lib/liquid/tags/table_row.rb +73 -0
- data/lib/liquid/tags/unless.rb +2 -4
- data/lib/liquid/template.rb +69 -10
- data/lib/liquid/utils.rb +13 -4
- data/lib/liquid/variable.rb +59 -8
- data/lib/liquid/version.rb +1 -1
- data/test/fixtures/en_locale.yml +9 -0
- data/test/{liquid → integration}/assign_test.rb +6 -0
- data/test/integration/blank_test.rb +106 -0
- data/test/{liquid → integration}/capture_test.rb +2 -2
- data/test/integration/context_test.rb +33 -0
- data/test/integration/drop_test.rb +245 -0
- data/test/{liquid → integration}/error_handling_test.rb +31 -2
- data/test/{liquid → integration}/filter_test.rb +7 -7
- data/test/{liquid → integration}/hash_ordering_test.rb +0 -0
- data/test/{liquid → integration}/output_test.rb +12 -12
- data/test/integration/parsing_quirks_test.rb +94 -0
- data/test/{liquid → integration}/security_test.rb +9 -9
- data/test/{liquid → integration}/standard_filter_test.rb +103 -33
- data/test/{liquid → integration}/tags/break_tag_test.rb +0 -0
- data/test/{liquid → integration}/tags/continue_tag_test.rb +0 -0
- data/test/{liquid → integration}/tags/for_tag_test.rb +78 -0
- data/test/{liquid → integration}/tags/if_else_tag_test.rb +1 -1
- data/test/integration/tags/include_tag_test.rb +212 -0
- data/test/{liquid → integration}/tags/increment_tag_test.rb +0 -0
- data/test/{liquid → integration}/tags/raw_tag_test.rb +1 -0
- data/test/{liquid → integration}/tags/standard_tag_test.rb +24 -22
- data/test/integration/tags/statements_test.rb +113 -0
- data/test/{liquid/tags/html_tag_test.rb → integration/tags/table_row_test.rb} +5 -5
- data/test/{liquid → integration}/tags/unless_else_tag_test.rb +0 -0
- data/test/{liquid → integration}/template_test.rb +66 -42
- data/test/integration/variable_test.rb +72 -0
- data/test/test_helper.rb +32 -7
- data/test/{liquid/block_test.rb → unit/block_unit_test.rb} +1 -1
- data/test/{liquid/condition_test.rb → unit/condition_unit_test.rb} +19 -1
- data/test/{liquid/context_test.rb → unit/context_unit_test.rb} +27 -19
- data/test/{liquid/file_system_test.rb → unit/file_system_unit_test.rb} +7 -1
- data/test/unit/i18n_unit_test.rb +37 -0
- data/test/unit/lexer_unit_test.rb +48 -0
- data/test/{liquid/module_ex_test.rb → unit/module_ex_unit_test.rb} +7 -7
- data/test/unit/parser_unit_test.rb +82 -0
- data/test/{liquid/regexp_test.rb → unit/regexp_unit_test.rb} +3 -3
- data/test/{liquid/strainer_test.rb → unit/strainer_unit_test.rb} +19 -1
- data/test/unit/tag_unit_test.rb +11 -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 +69 -0
- data/test/unit/tokenizer_unit_test.rb +29 -0
- data/test/{liquid/variable_test.rb → unit/variable_unit_test.rb} +17 -67
- metadata +117 -73
- data/lib/extras/liquid_view.rb +0 -51
- data/lib/liquid/htmltags.rb +0 -73
- data/test/liquid/drop_test.rb +0 -180
- data/test/liquid/parsing_quirks_test.rb +0 -52
- data/test/liquid/tags/include_tag_test.rb +0 -166
- data/test/liquid/tags/statements_test.rb +0 -134
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'test_helper'
|
2
2
|
|
3
|
-
class
|
3
|
+
class TableRowTest < Test::Unit::TestCase
|
4
4
|
include Liquid
|
5
5
|
|
6
6
|
class ArrayDrop < Liquid::Drop
|
@@ -15,7 +15,7 @@ class HtmlTagTest < Test::Unit::TestCase
|
|
15
15
|
end
|
16
16
|
end
|
17
17
|
|
18
|
-
def
|
18
|
+
def test_table_row
|
19
19
|
|
20
20
|
assert_template_result("<tr class=\"row1\">\n<td class=\"col1\"> 1 </td><td class=\"col2\"> 2 </td><td class=\"col3\"> 3 </td></tr>\n<tr class=\"row2\"><td class=\"col1\"> 4 </td><td class=\"col2\"> 5 </td><td class=\"col3\"> 6 </td></tr>\n",
|
21
21
|
'{% tablerow n in numbers cols:3%} {{n}} {% endtablerow %}',
|
@@ -26,14 +26,14 @@ class HtmlTagTest < Test::Unit::TestCase
|
|
26
26
|
'numbers' => [])
|
27
27
|
end
|
28
28
|
|
29
|
-
def
|
29
|
+
def test_table_row_with_different_cols
|
30
30
|
assert_template_result("<tr class=\"row1\">\n<td class=\"col1\"> 1 </td><td class=\"col2\"> 2 </td><td class=\"col3\"> 3 </td><td class=\"col4\"> 4 </td><td class=\"col5\"> 5 </td></tr>\n<tr class=\"row2\"><td class=\"col1\"> 6 </td></tr>\n",
|
31
31
|
'{% tablerow n in numbers cols:5%} {{n}} {% endtablerow %}',
|
32
32
|
'numbers' => [1,2,3,4,5,6])
|
33
33
|
|
34
34
|
end
|
35
35
|
|
36
|
-
def
|
36
|
+
def test_table_col_counter
|
37
37
|
assert_template_result("<tr class=\"row1\">\n<td class=\"col1\">1</td><td class=\"col2\">2</td></tr>\n<tr class=\"row2\"><td class=\"col1\">1</td><td class=\"col2\">2</td></tr>\n<tr class=\"row3\"><td class=\"col1\">1</td><td class=\"col2\">2</td></tr>\n",
|
38
38
|
'{% tablerow n in numbers cols:2%}{{tablerowloop.col}}{% endtablerow %}',
|
39
39
|
'numbers' => [1,2,3,4,5,6])
|
@@ -60,4 +60,4 @@ class HtmlTagTest < Test::Unit::TestCase
|
|
60
60
|
'{% tablerow n in numbers cols:3 offset:1 limit:6%} {{n}} {% endtablerow %}',
|
61
61
|
'numbers' => [0,1,2,3,4,5,6,7])
|
62
62
|
end
|
63
|
-
end
|
63
|
+
end
|
File without changes
|
@@ -14,85 +14,85 @@ class TemplateContextDrop < Liquid::Drop
|
|
14
14
|
end
|
15
15
|
end
|
16
16
|
|
17
|
-
class
|
18
|
-
|
19
|
-
|
20
|
-
def test_tokenize_strings
|
21
|
-
assert_equal [' '], Template.new.send(:tokenize, ' ')
|
22
|
-
assert_equal ['hello world'], Template.new.send(:tokenize, 'hello world')
|
23
|
-
end
|
24
|
-
|
25
|
-
def test_tokenize_variables
|
26
|
-
assert_equal ['{{funk}}'], Template.new.send(:tokenize, '{{funk}}')
|
27
|
-
assert_equal [' ', '{{funk}}', ' '], Template.new.send(:tokenize, ' {{funk}} ')
|
28
|
-
assert_equal [' ', '{{funk}}', ' ', '{{so}}', ' ', '{{brother}}', ' '], Template.new.send(:tokenize, ' {{funk}} {{so}} {{brother}} ')
|
29
|
-
assert_equal [' ', '{{ funk }}', ' '], Template.new.send(:tokenize, ' {{ funk }} ')
|
17
|
+
class SomethingWithLength
|
18
|
+
def length
|
19
|
+
nil
|
30
20
|
end
|
31
21
|
|
32
|
-
|
33
|
-
|
34
|
-
assert_equal [' ', '{%comment%}', ' '], Template.new.send(:tokenize, ' {%comment%} ')
|
22
|
+
liquid_methods :length
|
23
|
+
end
|
35
24
|
|
36
|
-
|
37
|
-
|
25
|
+
class ErroneousDrop < Liquid::Drop
|
26
|
+
def bad_method
|
27
|
+
raise 'ruby error in drop'
|
38
28
|
end
|
29
|
+
end
|
30
|
+
|
31
|
+
class TemplateTest < Test::Unit::TestCase
|
32
|
+
include Liquid
|
39
33
|
|
40
34
|
def test_instance_assigns_persist_on_same_template_object_between_parses
|
41
35
|
t = Template.new
|
42
|
-
assert_equal 'from instance assigns', t.parse("{% assign foo = 'from instance assigns' %}{{ foo }}").render
|
43
|
-
assert_equal 'from instance assigns', t.parse("{{ foo }}").render
|
36
|
+
assert_equal 'from instance assigns', t.parse("{% assign foo = 'from instance assigns' %}{{ foo }}").render!
|
37
|
+
assert_equal 'from instance assigns', t.parse("{{ foo }}").render!
|
44
38
|
end
|
45
39
|
|
46
40
|
def test_instance_assigns_persist_on_same_template_parsing_between_renders
|
47
41
|
t = Template.new.parse("{{ foo }}{% assign foo = 'foo' %}{{ foo }}")
|
48
|
-
assert_equal 'foo', t.render
|
49
|
-
assert_equal 'foofoo', t.render
|
42
|
+
assert_equal 'foo', t.render!
|
43
|
+
assert_equal 'foofoo', t.render!
|
50
44
|
end
|
51
45
|
|
52
46
|
def test_custom_assigns_do_not_persist_on_same_template
|
53
47
|
t = Template.new
|
54
|
-
assert_equal 'from custom assigns', t.parse("{{ foo }}").render('foo' => 'from custom assigns')
|
55
|
-
assert_equal '', t.parse("{{ foo }}").render
|
48
|
+
assert_equal 'from custom assigns', t.parse("{{ foo }}").render!('foo' => 'from custom assigns')
|
49
|
+
assert_equal '', t.parse("{{ foo }}").render!
|
56
50
|
end
|
57
51
|
|
58
52
|
def test_custom_assigns_squash_instance_assigns
|
59
53
|
t = Template.new
|
60
|
-
assert_equal 'from instance assigns', t.parse("{% assign foo = 'from instance assigns' %}{{ foo }}").render
|
61
|
-
assert_equal 'from custom assigns', t.parse("{{ foo }}").render('foo' => 'from custom assigns')
|
54
|
+
assert_equal 'from instance assigns', t.parse("{% assign foo = 'from instance assigns' %}{{ foo }}").render!
|
55
|
+
assert_equal 'from custom assigns', t.parse("{{ foo }}").render!('foo' => 'from custom assigns')
|
62
56
|
end
|
63
57
|
|
64
58
|
def test_persistent_assigns_squash_instance_assigns
|
65
59
|
t = Template.new
|
66
|
-
assert_equal 'from instance assigns', t.parse("{% assign foo = 'from instance assigns' %}{{ foo }}").render
|
60
|
+
assert_equal 'from instance assigns', t.parse("{% assign foo = 'from instance assigns' %}{{ foo }}").render!
|
67
61
|
t.assigns['foo'] = 'from persistent assigns'
|
68
|
-
assert_equal 'from persistent assigns', t.parse("{{ foo }}").render
|
62
|
+
assert_equal 'from persistent assigns', t.parse("{{ foo }}").render!
|
69
63
|
end
|
70
64
|
|
71
65
|
def test_lambda_is_called_once_from_persistent_assigns_over_multiple_parses_and_renders
|
72
66
|
t = Template.new
|
73
67
|
t.assigns['number'] = lambda { @global ||= 0; @global += 1 }
|
74
|
-
assert_equal '1', t.parse("{{number}}").render
|
75
|
-
assert_equal '1', t.parse("{{number}}").render
|
76
|
-
assert_equal '1', t.render
|
68
|
+
assert_equal '1', t.parse("{{number}}").render!
|
69
|
+
assert_equal '1', t.parse("{{number}}").render!
|
70
|
+
assert_equal '1', t.render!
|
77
71
|
@global = nil
|
78
72
|
end
|
79
73
|
|
80
74
|
def test_lambda_is_called_once_from_custom_assigns_over_multiple_parses_and_renders
|
81
75
|
t = Template.new
|
82
76
|
assigns = {'number' => lambda { @global ||= 0; @global += 1 }}
|
83
|
-
assert_equal '1', t.parse("{{number}}").render(assigns)
|
84
|
-
assert_equal '1', t.parse("{{number}}").render(assigns)
|
85
|
-
assert_equal '1', t.render(assigns)
|
77
|
+
assert_equal '1', t.parse("{{number}}").render!(assigns)
|
78
|
+
assert_equal '1', t.parse("{{number}}").render!(assigns)
|
79
|
+
assert_equal '1', t.render!(assigns)
|
86
80
|
@global = nil
|
87
81
|
end
|
88
82
|
|
83
|
+
def test_resource_limits_works_with_custom_length_method
|
84
|
+
t = Template.parse("{% assign foo = bar %}")
|
85
|
+
t.resource_limits = { :render_length_limit => 42 }
|
86
|
+
assert_equal "", t.render!("bar" => SomethingWithLength.new)
|
87
|
+
end
|
88
|
+
|
89
89
|
def test_resource_limits_render_length
|
90
90
|
t = Template.parse("0123456789")
|
91
91
|
t.resource_limits = { :render_length_limit => 5 }
|
92
92
|
assert_equal "Liquid error: Memory limits exceeded", t.render()
|
93
93
|
assert t.resource_limits[:reached]
|
94
94
|
t.resource_limits = { :render_length_limit => 10 }
|
95
|
-
assert_equal "0123456789", t.render()
|
95
|
+
assert_equal "0123456789", t.render!()
|
96
96
|
assert_not_nil t.resource_limits[:render_length_current]
|
97
97
|
end
|
98
98
|
|
@@ -106,7 +106,7 @@ class TemplateTest < Test::Unit::TestCase
|
|
106
106
|
assert_equal "Liquid error: Memory limits exceeded", t.render()
|
107
107
|
assert t.resource_limits[:reached]
|
108
108
|
t.resource_limits = { :render_score_limit => 200 }
|
109
|
-
assert_equal (" foo " * 100), t.render()
|
109
|
+
assert_equal (" foo " * 100), t.render!()
|
110
110
|
assert_not_nil t.resource_limits[:render_score_current]
|
111
111
|
end
|
112
112
|
|
@@ -116,7 +116,7 @@ class TemplateTest < Test::Unit::TestCase
|
|
116
116
|
assert_equal "Liquid error: Memory limits exceeded", t.render()
|
117
117
|
assert t.resource_limits[:reached]
|
118
118
|
t.resource_limits = { :assign_score_limit => 2 }
|
119
|
-
assert_equal "", t.render()
|
119
|
+
assert_equal "", t.render!()
|
120
120
|
assert_not_nil t.resource_limits[:assign_score_current]
|
121
121
|
end
|
122
122
|
|
@@ -129,7 +129,7 @@ class TemplateTest < Test::Unit::TestCase
|
|
129
129
|
|
130
130
|
def test_resource_limits_hash_in_template_gets_updated_even_if_no_limits_are_set
|
131
131
|
t = Template.parse("{% for a in (1..100) %} {% assign foo = 1 %} {% endfor %}")
|
132
|
-
t.render()
|
132
|
+
t.render!()
|
133
133
|
assert t.resource_limits[:assign_score_current] > 0
|
134
134
|
assert t.resource_limits[:render_score_current] > 0
|
135
135
|
assert t.resource_limits[:render_length_current] > 0
|
@@ -139,8 +139,32 @@ class TemplateTest < Test::Unit::TestCase
|
|
139
139
|
t = Template.new
|
140
140
|
t.registers['lulz'] = 'haha'
|
141
141
|
drop = TemplateContextDrop.new
|
142
|
-
assert_equal 'fizzbuzz', t.parse('{{foo}}').render(drop)
|
143
|
-
assert_equal 'bar', t.parse('{{bar}}').render(drop)
|
144
|
-
assert_equal 'haha', t.parse("{{baz}}").render(drop)
|
142
|
+
assert_equal 'fizzbuzz', t.parse('{{foo}}').render!(drop)
|
143
|
+
assert_equal 'bar', t.parse('{{bar}}').render!(drop)
|
144
|
+
assert_equal 'haha', t.parse("{{baz}}").render!(drop)
|
145
|
+
end
|
146
|
+
|
147
|
+
def test_render_bang_force_rethrow_errors_on_passed_context
|
148
|
+
context = Context.new({'drop' => ErroneousDrop.new})
|
149
|
+
t = Template.new.parse('{{ drop.bad_method }}')
|
150
|
+
|
151
|
+
e = assert_raises RuntimeError do
|
152
|
+
t.render!(context)
|
153
|
+
end
|
154
|
+
assert_equal 'ruby error in drop', e.message
|
145
155
|
end
|
146
|
-
|
156
|
+
|
157
|
+
def test_exception_handler_doesnt_reraise_if_it_returns_false
|
158
|
+
exception = nil
|
159
|
+
Template.parse("{{ 1 | divided_by: 0 }}").render({}, exception_handler: ->(e) { exception = e; false })
|
160
|
+
assert exception.is_a?(ZeroDivisionError)
|
161
|
+
end
|
162
|
+
|
163
|
+
def test_exception_handler_does_reraise_if_it_returns_true
|
164
|
+
exception = nil
|
165
|
+
assert_raises(ZeroDivisionError) do
|
166
|
+
Template.parse("{{ 1 | divided_by: 0 }}").render({}, exception_handler: ->(e) { exception = e; true })
|
167
|
+
end
|
168
|
+
assert exception.is_a?(ZeroDivisionError)
|
169
|
+
end
|
170
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class VariableTest < Test::Unit::TestCase
|
4
|
+
include Liquid
|
5
|
+
|
6
|
+
def test_simple_variable
|
7
|
+
template = Template.parse(%|{{test}}|)
|
8
|
+
assert_equal 'worked', template.render!('test' => 'worked')
|
9
|
+
assert_equal 'worked wonderfully', template.render!('test' => 'worked wonderfully')
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_simple_with_whitespaces
|
13
|
+
template = Template.parse(%| {{ test }} |)
|
14
|
+
assert_equal ' worked ', template.render!('test' => 'worked')
|
15
|
+
assert_equal ' worked wonderfully ', template.render!('test' => 'worked wonderfully')
|
16
|
+
end
|
17
|
+
|
18
|
+
def test_ignore_unknown
|
19
|
+
template = Template.parse(%|{{ test }}|)
|
20
|
+
assert_equal '', template.render!
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_hash_scoping
|
24
|
+
template = Template.parse(%|{{ test.test }}|)
|
25
|
+
assert_equal 'worked', template.render!('test' => {'test' => 'worked'})
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_false_renders_as_false
|
29
|
+
assert_equal 'false', Template.parse("{{ foo }}").render!('foo' => false)
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_preset_assigns
|
33
|
+
template = Template.parse(%|{{ test }}|)
|
34
|
+
template.assigns['test'] = 'worked'
|
35
|
+
assert_equal 'worked', template.render!
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_reuse_parsed_template
|
39
|
+
template = Template.parse(%|{{ greeting }} {{ name }}|)
|
40
|
+
template.assigns['greeting'] = 'Goodbye'
|
41
|
+
assert_equal 'Hello Tobi', template.render!('greeting' => 'Hello', 'name' => 'Tobi')
|
42
|
+
assert_equal 'Hello ', template.render!('greeting' => 'Hello', 'unknown' => 'Tobi')
|
43
|
+
assert_equal 'Hello Brian', template.render!('greeting' => 'Hello', 'name' => 'Brian')
|
44
|
+
assert_equal 'Goodbye Brian', template.render!('name' => 'Brian')
|
45
|
+
assert_equal({'greeting'=>'Goodbye'}, template.assigns)
|
46
|
+
end
|
47
|
+
|
48
|
+
def test_assigns_not_polluted_from_template
|
49
|
+
template = Template.parse(%|{{ test }}{% assign test = 'bar' %}{{ test }}|)
|
50
|
+
template.assigns['test'] = 'baz'
|
51
|
+
assert_equal 'bazbar', template.render!
|
52
|
+
assert_equal 'bazbar', template.render!
|
53
|
+
assert_equal 'foobar', template.render!('test' => 'foo')
|
54
|
+
assert_equal 'bazbar', template.render!
|
55
|
+
end
|
56
|
+
|
57
|
+
def test_hash_with_default_proc
|
58
|
+
template = Template.parse(%|Hello {{ test }}|)
|
59
|
+
assigns = Hash.new { |h,k| raise "Unknown variable '#{k}'" }
|
60
|
+
assigns['test'] = 'Tobi'
|
61
|
+
assert_equal 'Hello Tobi', template.render!(assigns)
|
62
|
+
assigns.delete('test')
|
63
|
+
e = assert_raises(RuntimeError) {
|
64
|
+
template.render!(assigns)
|
65
|
+
}
|
66
|
+
assert_equal "Unknown variable 'test'", e.message
|
67
|
+
end
|
68
|
+
|
69
|
+
def test_multiline_variable
|
70
|
+
assert_equal 'worked', Template.parse("{{\ntest\n}}").render!('test' => 'worked')
|
71
|
+
end
|
72
|
+
end
|
data/test/test_helper.rb
CHANGED
@@ -2,27 +2,52 @@
|
|
2
2
|
|
3
3
|
require 'test/unit'
|
4
4
|
require 'test/unit/assertions'
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
5
|
+
require 'spy/integration'
|
6
|
+
|
7
|
+
$:.unshift(File.join(File.expand_path(File.dirname(__FILE__)), '..', 'lib'))
|
8
|
+
require 'liquid.rb'
|
9
|
+
|
10
|
+
mode = :strict
|
11
|
+
if env_mode = ENV['LIQUID_PARSER_MODE']
|
12
|
+
puts "-- #{env_mode.upcase} ERROR MODE"
|
13
|
+
mode = env_mode.to_sym
|
9
14
|
end
|
10
|
-
|
15
|
+
Liquid::Template.error_mode = mode
|
11
16
|
|
12
17
|
|
13
18
|
module Test
|
14
19
|
module Unit
|
20
|
+
class TestCase
|
21
|
+
def fixture(name)
|
22
|
+
File.join(File.expand_path(File.dirname(__FILE__)), "fixtures", name)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
15
26
|
module Assertions
|
16
27
|
include Liquid
|
17
28
|
|
18
29
|
def assert_template_result(expected, template, assigns = {}, message = nil)
|
19
|
-
assert_equal expected, Template.parse(template).render(assigns)
|
30
|
+
assert_equal expected, Template.parse(template).render!(assigns)
|
20
31
|
end
|
21
32
|
|
22
33
|
def assert_template_result_matches(expected, template, assigns = {}, message = nil)
|
23
34
|
return assert_template_result(expected, template, assigns, message) unless expected.is_a? Regexp
|
24
35
|
|
25
|
-
assert_match expected, Template.parse(template).render(assigns)
|
36
|
+
assert_match expected, Template.parse(template).render!(assigns)
|
37
|
+
end
|
38
|
+
|
39
|
+
def assert_match_syntax_error(match, template, registers = {})
|
40
|
+
exception = assert_raise(Liquid::SyntaxError) {
|
41
|
+
Template.parse(template).render(assigns)
|
42
|
+
}
|
43
|
+
assert_match match, exception.message
|
44
|
+
end
|
45
|
+
|
46
|
+
def with_error_mode(mode)
|
47
|
+
old_mode = Liquid::Template.error_mode
|
48
|
+
Liquid::Template.error_mode = mode
|
49
|
+
yield
|
50
|
+
Liquid::Template.error_mode = old_mode
|
26
51
|
end
|
27
52
|
end # Assertions
|
28
53
|
end # Unit
|
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'test_helper'
|
2
2
|
|
3
|
-
class
|
3
|
+
class ConditionUnitTest < Test::Unit::TestCase
|
4
4
|
include Liquid
|
5
5
|
|
6
6
|
def test_basic_condition
|
@@ -49,6 +49,17 @@ class ConditionTest < Test::Unit::TestCase
|
|
49
49
|
assert_evalutes_false "'bob'", 'contains', "'---'"
|
50
50
|
end
|
51
51
|
|
52
|
+
def test_invalid_comparation_operator
|
53
|
+
assert_evaluates_argument_error "1", '~~', '0'
|
54
|
+
end
|
55
|
+
|
56
|
+
def test_comparation_of_int_and_str
|
57
|
+
assert_evaluates_argument_error "'1'", '>', '0'
|
58
|
+
assert_evaluates_argument_error "'1'", '<', '0'
|
59
|
+
assert_evaluates_argument_error "'1'", '>=', '0'
|
60
|
+
assert_evaluates_argument_error "'1'", '<=', '0'
|
61
|
+
end
|
62
|
+
|
52
63
|
def test_contains_works_on_arrays
|
53
64
|
@context = Liquid::Context.new
|
54
65
|
@context['array'] = [1,2,3,4,5]
|
@@ -124,4 +135,11 @@ class ConditionTest < Test::Unit::TestCase
|
|
124
135
|
assert !Condition.new(left, op, right).evaluate(@context || Liquid::Context.new),
|
125
136
|
"Evaluated true: #{left} #{op} #{right}"
|
126
137
|
end
|
138
|
+
|
139
|
+
def assert_evaluates_argument_error(left, op, right)
|
140
|
+
assert_raises(Liquid::ArgumentError) do
|
141
|
+
Condition.new(left, op, right).evaluate(@context || Liquid::Context.new)
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
127
145
|
end # ConditionTest
|
@@ -63,13 +63,17 @@ class ArrayLike
|
|
63
63
|
end
|
64
64
|
end
|
65
65
|
|
66
|
-
class
|
66
|
+
class ContextUnitTest < Test::Unit::TestCase
|
67
67
|
include Liquid
|
68
68
|
|
69
69
|
def setup
|
70
70
|
@context = Liquid::Context.new
|
71
71
|
end
|
72
72
|
|
73
|
+
def teardown
|
74
|
+
Spy.teardown
|
75
|
+
end
|
76
|
+
|
73
77
|
def test_variables
|
74
78
|
@context['string'] = 'string'
|
75
79
|
assert_equal 'string', @context['string']
|
@@ -162,24 +166,6 @@ class ContextTest < Test::Unit::TestCase
|
|
162
166
|
|
163
167
|
end
|
164
168
|
|
165
|
-
def test_override_global_filter
|
166
|
-
global = Module.new do
|
167
|
-
def notice(output)
|
168
|
-
"Global #{output}"
|
169
|
-
end
|
170
|
-
end
|
171
|
-
|
172
|
-
local = Module.new do
|
173
|
-
def notice(output)
|
174
|
-
"Local #{output}"
|
175
|
-
end
|
176
|
-
end
|
177
|
-
|
178
|
-
Template.register_filter(global)
|
179
|
-
assert_equal 'Global test', Template.parse("{{'test' | notice }}").render
|
180
|
-
assert_equal 'Local test', Template.parse("{{'test' | notice }}").render({}, :filters => [local])
|
181
|
-
end
|
182
|
-
|
183
169
|
def test_only_intended_filters_make_it_there
|
184
170
|
|
185
171
|
filter = Module.new do
|
@@ -475,4 +461,26 @@ class ContextTest < Test::Unit::TestCase
|
|
475
461
|
assert_kind_of CategoryDrop, @context['category']
|
476
462
|
assert_equal @context, @context['category'].context
|
477
463
|
end
|
464
|
+
|
465
|
+
def test_use_empty_instead_of_any_in_interrupt_handling_to_avoid_lots_of_unnecessary_object_allocations
|
466
|
+
mock_any = Spy.on_instance_method(Array, :any?)
|
467
|
+
mock_empty = Spy.on_instance_method(Array, :empty?)
|
468
|
+
mock_has_interrupt = Spy.on(@context, :has_interrupt?).and_call_through
|
469
|
+
|
470
|
+
@context.has_interrupt?
|
471
|
+
|
472
|
+
refute mock_any.has_been_called?
|
473
|
+
assert mock_empty.has_been_called?
|
474
|
+
end
|
475
|
+
|
476
|
+
def test_variable_lookup_caches_markup
|
477
|
+
mock_scan = Spy.on_instance_method(String, :scan).and_return(["string"])
|
478
|
+
|
479
|
+
@context['string'] = 'string'
|
480
|
+
@context['string']
|
481
|
+
@context['string']
|
482
|
+
|
483
|
+
assert_equal 1, mock_scan.calls.size
|
484
|
+
end
|
485
|
+
|
478
486
|
end # ContextTest
|