liquid 2.5.5 → 2.6.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +13 -5
- data/History.md +26 -11
- data/MIT-LICENSE +1 -1
- data/README.md +6 -0
- data/lib/extras/liquid_view.rb +9 -9
- data/lib/liquid.rb +1 -0
- data/lib/liquid/block.rb +16 -5
- data/lib/liquid/context.rb +17 -9
- data/lib/liquid/document.rb +1 -1
- data/lib/liquid/errors.rb +2 -1
- data/lib/liquid/file_system.rb +12 -12
- data/lib/liquid/htmltags.rb +1 -1
- data/lib/liquid/module_ex.rb +1 -1
- data/lib/liquid/standardfilters.rb +44 -22
- data/lib/liquid/strainer.rb +3 -3
- data/lib/liquid/tag.rb +1 -1
- data/lib/liquid/tags/assign.rb +14 -12
- data/lib/liquid/tags/break.rb +2 -2
- data/lib/liquid/tags/capture.rb +1 -0
- data/lib/liquid/tags/case.rb +28 -28
- data/lib/liquid/tags/continue.rb +1 -1
- data/lib/liquid/tags/cycle.rb +21 -21
- data/lib/liquid/tags/decrement.rb +7 -7
- data/lib/liquid/tags/for.rb +26 -26
- data/lib/liquid/tags/if.rb +3 -3
- data/lib/liquid/tags/ifchanged.rb +9 -9
- data/lib/liquid/tags/include.rb +42 -14
- data/lib/liquid/tags/increment.rb +7 -7
- data/lib/liquid/tags/raw.rb +5 -4
- data/lib/liquid/tags/unless.rb +8 -8
- data/lib/liquid/template.rb +11 -5
- data/lib/liquid/utils.rb +0 -1
- data/lib/liquid/variable.rb +2 -2
- data/lib/liquid/version.rb +4 -0
- data/test/liquid/assign_test.rb +1 -1
- data/test/liquid/condition_test.rb +1 -1
- data/test/liquid/hash_ordering_test.rb +25 -0
- data/test/liquid/output_test.rb +2 -2
- data/test/liquid/standard_filter_test.rb +18 -0
- data/test/liquid/tags/for_tag_test.rb +47 -34
- data/test/liquid/tags/html_tag_test.rb +2 -2
- data/test/liquid/tags/if_else_tag_test.rb +0 -6
- data/test/liquid/tags/include_tag_test.rb +28 -1
- data/test/liquid/tags/raw_tag_test.rb +11 -2
- data/test/liquid/template_test.rb +72 -0
- data/test/liquid/variable_test.rb +6 -0
- metadata +8 -5
@@ -42,11 +42,11 @@ class HtmlTagTest < Test::Unit::TestCase
|
|
42
42
|
def test_quoted_fragment
|
43
43
|
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",
|
44
44
|
"{% tablerow n in collections.frontpage cols:3%} {{n}} {% endtablerow %}",
|
45
|
-
'collections' => {'frontpage' => [1,2,3,4,5,6]})
|
45
|
+
'collections' => {'frontpage' => [1,2,3,4,5,6]})
|
46
46
|
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",
|
47
47
|
"{% tablerow n in collections['frontpage'] cols:3%} {{n}} {% endtablerow %}",
|
48
48
|
'collections' => {'frontpage' => [1,2,3,4,5,6]})
|
49
|
-
|
49
|
+
|
50
50
|
end
|
51
51
|
|
52
52
|
def test_enumerable_drop
|
@@ -157,10 +157,4 @@ class IfElseTagTest < Test::Unit::TestCase
|
|
157
157
|
assert_template_result('yes',
|
158
158
|
%({% if 'gnomeslab-and-or-liquid' contains 'gnomeslab-and-or-liquid' %}yes{% endif %}))
|
159
159
|
end
|
160
|
-
|
161
|
-
def test_operators_are_whitelisted
|
162
|
-
assert_raise(SyntaxError) do
|
163
|
-
assert_template_result('', %({% if 1 or throw or or 1 %}yes{% endif %}))
|
164
|
-
end
|
165
|
-
end
|
166
160
|
end # IfElseTest
|
@@ -39,6 +39,15 @@ class OtherFileSystem
|
|
39
39
|
end
|
40
40
|
end
|
41
41
|
|
42
|
+
class CountingFileSystem
|
43
|
+
attr_reader :count
|
44
|
+
def read_template_file(template_path, context)
|
45
|
+
@count ||= 0
|
46
|
+
@count += 1
|
47
|
+
'from CountingFileSystem'
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
42
51
|
class IncludeTagTest < Test::Unit::TestCase
|
43
52
|
include Liquid
|
44
53
|
|
@@ -136,4 +145,22 @@ class IncludeTagTest < Test::Unit::TestCase
|
|
136
145
|
|
137
146
|
assert_equal "Product: Draft 151cm ", Template.parse("{% include template for product %}").render("template" => 'product', 'product' => { 'title' => 'Draft 151cm'})
|
138
147
|
end
|
139
|
-
|
148
|
+
|
149
|
+
def test_include_tag_caches_second_read_of_same_partial
|
150
|
+
file_system = CountingFileSystem.new
|
151
|
+
assert_equal 'from CountingFileSystemfrom CountingFileSystem',
|
152
|
+
Template.parse("{% include 'pick_a_source' %}{% include 'pick_a_source' %}").render({}, :registers => {:file_system => file_system})
|
153
|
+
assert_equal 1, file_system.count
|
154
|
+
end
|
155
|
+
|
156
|
+
def test_include_tag_doesnt_cache_partials_across_renders
|
157
|
+
file_system = CountingFileSystem.new
|
158
|
+
assert_equal 'from CountingFileSystem',
|
159
|
+
Template.parse("{% include 'pick_a_source' %}").render({}, :registers => {:file_system => file_system})
|
160
|
+
assert_equal 1, file_system.count
|
161
|
+
|
162
|
+
assert_equal 'from CountingFileSystem',
|
163
|
+
Template.parse("{% include 'pick_a_source' %}").render({}, :registers => {:file_system => file_system})
|
164
|
+
assert_equal 2, file_system.count
|
165
|
+
end
|
166
|
+
end # IncludeTagTest
|
@@ -9,7 +9,16 @@ class RawTagTest < Test::Unit::TestCase
|
|
9
9
|
end
|
10
10
|
|
11
11
|
def test_output_in_raw
|
12
|
-
assert_template_result '{{ test }}',
|
13
|
-
|
12
|
+
assert_template_result '{{ test }}', '{% raw %}{{ test }}{% endraw %}'
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_open_tag_in_raw
|
16
|
+
assert_template_result ' Foobar {% invalid ', '{% raw %} Foobar {% invalid {% endraw %}'
|
17
|
+
assert_template_result ' Foobar invalid %} ', '{% raw %} Foobar invalid %} {% endraw %}'
|
18
|
+
assert_template_result ' Foobar {{ invalid ', '{% raw %} Foobar {{ invalid {% endraw %}'
|
19
|
+
assert_template_result ' Foobar invalid }} ', '{% raw %} Foobar invalid }} {% endraw %}'
|
20
|
+
assert_template_result ' Foobar {% invalid {% {% endraw ', '{% raw %} Foobar {% invalid {% {% endraw {% endraw %}'
|
21
|
+
assert_template_result ' Foobar {% {% {% ', '{% raw %} Foobar {% {% {% {% endraw %}'
|
22
|
+
assert_template_result ' test {% raw %} {% endraw %}', '{% raw %} test {% raw %} {% {% endraw %}endraw %}'
|
14
23
|
end
|
15
24
|
end
|
@@ -1,5 +1,19 @@
|
|
1
1
|
require 'test_helper'
|
2
2
|
|
3
|
+
class TemplateContextDrop < Liquid::Drop
|
4
|
+
def before_method(method)
|
5
|
+
method
|
6
|
+
end
|
7
|
+
|
8
|
+
def foo
|
9
|
+
'fizzbuzz'
|
10
|
+
end
|
11
|
+
|
12
|
+
def baz
|
13
|
+
@context.registers['lulz']
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
3
17
|
class TemplateTest < Test::Unit::TestCase
|
4
18
|
include Liquid
|
5
19
|
|
@@ -71,4 +85,62 @@ class TemplateTest < Test::Unit::TestCase
|
|
71
85
|
assert_equal '1', t.render(assigns)
|
72
86
|
@global = nil
|
73
87
|
end
|
88
|
+
|
89
|
+
def test_resource_limits_render_length
|
90
|
+
t = Template.parse("0123456789")
|
91
|
+
t.resource_limits = { :render_length_limit => 5 }
|
92
|
+
assert_equal "Liquid error: Memory limits exceeded", t.render()
|
93
|
+
assert t.resource_limits[:reached]
|
94
|
+
t.resource_limits = { :render_length_limit => 10 }
|
95
|
+
assert_equal "0123456789", t.render()
|
96
|
+
assert_not_nil t.resource_limits[:render_length_current]
|
97
|
+
end
|
98
|
+
|
99
|
+
def test_resource_limits_render_score
|
100
|
+
t = Template.parse("{% for a in (1..10) %} {% for a in (1..10) %} foo {% endfor %} {% endfor %}")
|
101
|
+
t.resource_limits = { :render_score_limit => 50 }
|
102
|
+
assert_equal "Liquid error: Memory limits exceeded", t.render()
|
103
|
+
assert t.resource_limits[:reached]
|
104
|
+
t = Template.parse("{% for a in (1..100) %} foo {% endfor %}")
|
105
|
+
t.resource_limits = { :render_score_limit => 50 }
|
106
|
+
assert_equal "Liquid error: Memory limits exceeded", t.render()
|
107
|
+
assert t.resource_limits[:reached]
|
108
|
+
t.resource_limits = { :render_score_limit => 200 }
|
109
|
+
assert_equal (" foo " * 100), t.render()
|
110
|
+
assert_not_nil t.resource_limits[:render_score_current]
|
111
|
+
end
|
112
|
+
|
113
|
+
def test_resource_limits_assign_score
|
114
|
+
t = Template.parse("{% assign foo = 42 %}{% assign bar = 23 %}")
|
115
|
+
t.resource_limits = { :assign_score_limit => 1 }
|
116
|
+
assert_equal "Liquid error: Memory limits exceeded", t.render()
|
117
|
+
assert t.resource_limits[:reached]
|
118
|
+
t.resource_limits = { :assign_score_limit => 2 }
|
119
|
+
assert_equal "", t.render()
|
120
|
+
assert_not_nil t.resource_limits[:assign_score_current]
|
121
|
+
end
|
122
|
+
|
123
|
+
def test_resource_limits_aborts_rendering_after_first_error
|
124
|
+
t = Template.parse("{% for a in (1..100) %} foo1 {% endfor %} bar {% for a in (1..100) %} foo2 {% endfor %}")
|
125
|
+
t.resource_limits = { :render_score_limit => 50 }
|
126
|
+
assert_equal "Liquid error: Memory limits exceeded", t.render()
|
127
|
+
assert t.resource_limits[:reached]
|
128
|
+
end
|
129
|
+
|
130
|
+
def test_resource_limits_hash_in_template_gets_updated_even_if_no_limits_are_set
|
131
|
+
t = Template.parse("{% for a in (1..100) %} {% assign foo = 1 %} {% endfor %}")
|
132
|
+
t.render()
|
133
|
+
assert t.resource_limits[:assign_score_current] > 0
|
134
|
+
assert t.resource_limits[:render_score_current] > 0
|
135
|
+
assert t.resource_limits[:render_length_current] > 0
|
136
|
+
end
|
137
|
+
|
138
|
+
def test_can_use_drop_as_context
|
139
|
+
t = Template.new
|
140
|
+
t.registers['lulz'] = 'haha'
|
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)
|
145
|
+
end
|
74
146
|
end # TemplateTest
|
@@ -113,6 +113,12 @@ class VariableTest < Test::Unit::TestCase
|
|
113
113
|
assert_equal 'hello', var.name
|
114
114
|
assert_equal [['things',["greeting: \"world\"","farewell: 'goodbye'"]]], var.filters
|
115
115
|
end
|
116
|
+
|
117
|
+
def test_lax_filter_argument_parsing
|
118
|
+
var = Variable.new(%! number_of_comments | pluralize: 'comment': 'comments' !)
|
119
|
+
assert_equal 'number_of_comments', var.name
|
120
|
+
assert_equal [['pluralize',["'comment'","'comments'"]]], var.filters
|
121
|
+
end
|
116
122
|
end
|
117
123
|
|
118
124
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: liquid
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.6.0.rc1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tobias Luetke
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2013-10-10 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description:
|
14
14
|
email:
|
@@ -52,6 +52,7 @@ files:
|
|
52
52
|
- lib/liquid/template.rb
|
53
53
|
- lib/liquid/utils.rb
|
54
54
|
- lib/liquid/variable.rb
|
55
|
+
- lib/liquid/version.rb
|
55
56
|
- lib/liquid.rb
|
56
57
|
- MIT-LICENSE
|
57
58
|
- README.md
|
@@ -64,6 +65,7 @@ files:
|
|
64
65
|
- test/liquid/error_handling_test.rb
|
65
66
|
- test/liquid/file_system_test.rb
|
66
67
|
- test/liquid/filter_test.rb
|
68
|
+
- test/liquid/hash_ordering_test.rb
|
67
69
|
- test/liquid/module_ex_test.rb
|
68
70
|
- test/liquid/output_test.rb
|
69
71
|
- test/liquid/parsing_quirks_test.rb
|
@@ -95,17 +97,17 @@ require_paths:
|
|
95
97
|
- lib
|
96
98
|
required_ruby_version: !ruby/object:Gem::Requirement
|
97
99
|
requirements:
|
98
|
-
- - '>='
|
100
|
+
- - ! '>='
|
99
101
|
- !ruby/object:Gem::Version
|
100
102
|
version: '0'
|
101
103
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
102
104
|
requirements:
|
103
|
-
- - '>='
|
105
|
+
- - ! '>='
|
104
106
|
- !ruby/object:Gem::Version
|
105
107
|
version: 1.3.7
|
106
108
|
requirements: []
|
107
109
|
rubyforge_project:
|
108
|
-
rubygems_version: 2.
|
110
|
+
rubygems_version: 2.1.6
|
109
111
|
signing_key:
|
110
112
|
specification_version: 4
|
111
113
|
summary: A secure, non-evaling end user template engine with aesthetic markup.
|
@@ -119,6 +121,7 @@ test_files:
|
|
119
121
|
- test/liquid/error_handling_test.rb
|
120
122
|
- test/liquid/file_system_test.rb
|
121
123
|
- test/liquid/filter_test.rb
|
124
|
+
- test/liquid/hash_ordering_test.rb
|
122
125
|
- test/liquid/module_ex_test.rb
|
123
126
|
- test/liquid/output_test.rb
|
124
127
|
- test/liquid/parsing_quirks_test.rb
|