liquid 2.6.3 → 3.0.0.rc1
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 +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
|