liquid 4.0.0 → 4.0.1
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 +5 -2
- data/README.md +2 -0
- data/lib/liquid/block.rb +22 -12
- data/lib/liquid/block_body.rb +62 -59
- data/lib/liquid/condition.rb +20 -10
- data/lib/liquid/context.rb +10 -8
- data/lib/liquid/expression.rb +10 -6
- data/lib/liquid/extensions.rb +6 -0
- data/lib/liquid/lexer.rb +5 -3
- data/lib/liquid/locales/en.yml +1 -1
- data/lib/liquid/parse_context.rb +2 -1
- data/lib/liquid/profiler/hooks.rb +4 -4
- data/lib/liquid/standardfilters.rb +47 -11
- data/lib/liquid/strainer.rb +1 -1
- data/lib/liquid/tags/cycle.rb +2 -2
- data/lib/liquid/tags/for.rb +6 -3
- data/lib/liquid/tags/if.rb +8 -5
- data/lib/liquid/tags/include.rb +1 -1
- data/lib/liquid/tags/table_row.rb +1 -1
- data/lib/liquid/utils.rb +2 -2
- data/lib/liquid/variable.rb +10 -4
- data/lib/liquid/version.rb +1 -1
- data/test/integration/block_test.rb +12 -0
- data/test/integration/parsing_quirks_test.rb +4 -0
- data/test/integration/security_test.rb +14 -0
- data/test/integration/standard_filter_test.rb +97 -6
- data/test/integration/tags/for_tag_test.rb +2 -2
- data/test/integration/tags/include_tag_test.rb +8 -1
- data/test/integration/template_test.rb +9 -0
- data/test/integration/trim_mode_test.rb +4 -0
- data/test/integration/variable_test.rb +4 -0
- data/test/test_helper.rb +0 -1
- data/test/unit/condition_unit_test.rb +8 -0
- data/test/unit/context_unit_test.rb +23 -17
- data/test/unit/lexer_unit_test.rb +1 -1
- data/test/unit/strainer_unit_test.rb +16 -0
- metadata +42 -40
@@ -159,7 +159,7 @@ HERE
|
|
159
159
|
assert_template_result(expected, markup, assigns)
|
160
160
|
end
|
161
161
|
|
162
|
-
def
|
162
|
+
def test_pause_resume_big_limit
|
163
163
|
assigns = { 'array' => { 'items' => [1, 2, 3, 4, 5, 6, 7, 8, 9, 0] } }
|
164
164
|
markup = <<-MKUP
|
165
165
|
{%for i in array.items limit:3 %}{{i}}{%endfor%}
|
@@ -178,7 +178,7 @@ HERE
|
|
178
178
|
assert_template_result(expected, markup, assigns)
|
179
179
|
end
|
180
180
|
|
181
|
-
def
|
181
|
+
def test_pause_resume_big_offset
|
182
182
|
assigns = { 'array' => { 'items' => [1, 2, 3, 4, 5, 6, 7, 8, 9, 0] } }
|
183
183
|
markup = '{%for i in array.items limit:3 %}{{i}}{%endfor%}
|
184
184
|
next
|
@@ -137,7 +137,7 @@ class IncludeTagTest < Minitest::Test
|
|
137
137
|
|
138
138
|
Liquid::Template.file_system = infinite_file_system.new
|
139
139
|
|
140
|
-
assert_raises(Liquid::StackLevelError
|
140
|
+
assert_raises(Liquid::StackLevelError) do
|
141
141
|
Template.parse("{% include 'loop' %}").render!
|
142
142
|
end
|
143
143
|
end
|
@@ -235,4 +235,11 @@ class IncludeTagTest < Minitest::Test
|
|
235
235
|
|
236
236
|
assert_template_result "Product: Draft 151cm ", "{% assign page = 'product' %}{% include page for foo %}", "foo" => { 'title' => 'Draft 151cm' }
|
237
237
|
end
|
238
|
+
|
239
|
+
def test_including_with_strict_variables
|
240
|
+
template = Liquid::Template.parse("{% include 'simple' %}", error_mode: :warn)
|
241
|
+
template.render(nil, strict_variables: true)
|
242
|
+
|
243
|
+
assert_equal [], template.errors
|
244
|
+
end
|
238
245
|
end # IncludeTagTest
|
@@ -261,6 +261,15 @@ class TemplateTest < Minitest::Test
|
|
261
261
|
assert_equal 'Liquid error: undefined variable d', t.errors[2].message
|
262
262
|
end
|
263
263
|
|
264
|
+
def test_nil_value_does_not_raise
|
265
|
+
Liquid::Template.error_mode = :strict
|
266
|
+
t = Template.parse("some{{x}}thing")
|
267
|
+
result = t.render!({ 'x' => nil }, strict_variables: true)
|
268
|
+
|
269
|
+
assert_equal 0, t.errors.count
|
270
|
+
assert_equal 'something', result
|
271
|
+
end
|
272
|
+
|
264
273
|
def test_undefined_variables_raise
|
265
274
|
t = Template.parse("{{x}} {{y}} {{z.a}} {{z.b}} {{z.c.d}}")
|
266
275
|
|
@@ -496,6 +496,10 @@ class TrimModeTest < Minitest::Test
|
|
496
496
|
assert_template_result(expected, text)
|
497
497
|
end
|
498
498
|
|
499
|
+
def test_right_trim_followed_by_tag
|
500
|
+
assert_template_result('ab c', '{{ "a" -}}{{ "b" }} c')
|
501
|
+
end
|
502
|
+
|
499
503
|
def test_raw_output
|
500
504
|
whitespace = ' '
|
501
505
|
text = <<-END_TEMPLATE
|
data/test/test_helper.rb
CHANGED
@@ -64,6 +64,14 @@ class ConditionUnitTest < Minitest::Test
|
|
64
64
|
assert_evaluates_argument_error '1', '<=', 0
|
65
65
|
end
|
66
66
|
|
67
|
+
def test_hash_compare_backwards_compatibility
|
68
|
+
assert_nil Condition.new({}, '>', 2).evaluate
|
69
|
+
assert_nil Condition.new(2, '>', {}).evaluate
|
70
|
+
assert_equal false, Condition.new({}, '==', 2).evaluate
|
71
|
+
assert_equal true, Condition.new({ 'a' => 1 }, '==', { 'a' => 1 }).evaluate
|
72
|
+
assert_equal true, Condition.new({ 'a' => 2 }, 'contains', 'a').evaluate
|
73
|
+
end
|
74
|
+
|
67
75
|
def test_contains_works_on_arrays
|
68
76
|
@context = Liquid::Context.new
|
69
77
|
@context['array'] = [1, 2, 3, 4, 5]
|
@@ -70,10 +70,6 @@ class ContextUnitTest < Minitest::Test
|
|
70
70
|
@context = Liquid::Context.new
|
71
71
|
end
|
72
72
|
|
73
|
-
def teardown
|
74
|
-
Spy.teardown
|
75
|
-
end
|
76
|
-
|
77
73
|
def test_variables
|
78
74
|
@context['string'] = 'string'
|
79
75
|
assert_equal 'string', @context['string']
|
@@ -98,12 +94,12 @@ class ContextUnitTest < Minitest::Test
|
|
98
94
|
assert_equal false, @context['bool']
|
99
95
|
|
100
96
|
@context['nil'] = nil
|
101
|
-
|
102
|
-
|
97
|
+
assert_nil @context['nil']
|
98
|
+
assert_nil @context['nil']
|
103
99
|
end
|
104
100
|
|
105
101
|
def test_variables_not_existing
|
106
|
-
|
102
|
+
assert_nil @context['does_not_exist']
|
107
103
|
end
|
108
104
|
|
109
105
|
def test_scoping
|
@@ -185,7 +181,7 @@ class ContextUnitTest < Minitest::Test
|
|
185
181
|
@context['test'] = 'test'
|
186
182
|
assert_equal 'test', @context['test']
|
187
183
|
@context.pop
|
188
|
-
|
184
|
+
assert_nil @context['test']
|
189
185
|
end
|
190
186
|
|
191
187
|
def test_hierachical_data
|
@@ -300,7 +296,7 @@ class ContextUnitTest < Minitest::Test
|
|
300
296
|
@context['hash'] = { 'first' => 'Hello' }
|
301
297
|
|
302
298
|
assert_equal 1, @context['array.first']
|
303
|
-
|
299
|
+
assert_nil @context['array["first"]']
|
304
300
|
assert_equal 'Hello', @context['hash["first"]']
|
305
301
|
end
|
306
302
|
|
@@ -450,14 +446,10 @@ class ContextUnitTest < Minitest::Test
|
|
450
446
|
assert_equal @context, @context['category'].context
|
451
447
|
end
|
452
448
|
|
453
|
-
def
|
454
|
-
|
455
|
-
|
456
|
-
|
457
|
-
@context.interrupt?
|
458
|
-
|
459
|
-
refute mock_any.has_been_called?
|
460
|
-
assert mock_empty.has_been_called?
|
449
|
+
def test_interrupt_avoids_object_allocations
|
450
|
+
assert_no_object_allocations do
|
451
|
+
@context.interrupt?
|
452
|
+
end
|
461
453
|
end
|
462
454
|
|
463
455
|
def test_context_initialization_with_a_proc_in_environment
|
@@ -480,4 +472,18 @@ class ContextUnitTest < Minitest::Test
|
|
480
472
|
context = Context.new
|
481
473
|
assert_equal 'hi', context.apply_global_filter('hi')
|
482
474
|
end
|
475
|
+
|
476
|
+
private
|
477
|
+
|
478
|
+
def assert_no_object_allocations
|
479
|
+
unless RUBY_ENGINE == 'ruby'
|
480
|
+
skip "stackprof needed to count object allocations"
|
481
|
+
end
|
482
|
+
require 'stackprof'
|
483
|
+
|
484
|
+
profile = StackProf.run(mode: :object) do
|
485
|
+
yield
|
486
|
+
end
|
487
|
+
assert_equal 0, profile[:samples]
|
488
|
+
end
|
483
489
|
end # ContextTest
|
@@ -19,7 +19,7 @@ class LexerUnitTest < Minitest::Test
|
|
19
19
|
end
|
20
20
|
|
21
21
|
def test_comparison
|
22
|
-
tokens = Lexer.new('== <> contains').tokenize
|
22
|
+
tokens = Lexer.new('== <> contains ').tokenize
|
23
23
|
assert_equal [[:comparison, '=='], [:comparison, '<>'], [:comparison, 'contains'], [:end_of_string]], tokens
|
24
24
|
end
|
25
25
|
|
@@ -145,4 +145,20 @@ class StrainerUnitTest < Minitest::Test
|
|
145
145
|
Strainer.global_filter(LateAddedFilter)
|
146
146
|
assert_equal 'filtered', Strainer.create(nil).invoke('late_added_filter', 'input')
|
147
147
|
end
|
148
|
+
|
149
|
+
def test_add_filter_does_not_include_already_included_module
|
150
|
+
mod = Module.new do
|
151
|
+
class << self
|
152
|
+
attr_accessor :include_count
|
153
|
+
def included(mod)
|
154
|
+
self.include_count += 1
|
155
|
+
end
|
156
|
+
end
|
157
|
+
self.include_count = 0
|
158
|
+
end
|
159
|
+
strainer = Context.new.strainer
|
160
|
+
strainer.class.add_filter(mod)
|
161
|
+
strainer.class.add_filter(mod)
|
162
|
+
assert_equal 1, mod.include_count
|
163
|
+
end
|
148
164
|
end # StrainerTest
|
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: 4.0.
|
4
|
+
version: 4.0.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tobias Lütke
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2018-10-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
@@ -102,6 +102,7 @@ files:
|
|
102
102
|
- test/fixtures/en_locale.yml
|
103
103
|
- test/integration/assign_test.rb
|
104
104
|
- test/integration/blank_test.rb
|
105
|
+
- test/integration/block_test.rb
|
105
106
|
- test/integration/capture_test.rb
|
106
107
|
- test/integration/context_test.rb
|
107
108
|
- test/integration/document_test.rb
|
@@ -165,54 +166,55 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
165
166
|
version: 1.3.7
|
166
167
|
requirements: []
|
167
168
|
rubyforge_project:
|
168
|
-
rubygems_version: 2.
|
169
|
+
rubygems_version: 2.7.6
|
169
170
|
signing_key:
|
170
171
|
specification_version: 4
|
171
172
|
summary: A secure, non-evaling end user template engine with aesthetic markup.
|
172
173
|
test_files:
|
173
|
-
- test/
|
174
|
-
- test/
|
174
|
+
- test/unit/lexer_unit_test.rb
|
175
|
+
- test/unit/block_unit_test.rb
|
176
|
+
- test/unit/variable_unit_test.rb
|
177
|
+
- test/unit/parser_unit_test.rb
|
178
|
+
- test/unit/tags/if_tag_unit_test.rb
|
179
|
+
- test/unit/tags/case_tag_unit_test.rb
|
180
|
+
- test/unit/tags/for_tag_unit_test.rb
|
181
|
+
- test/unit/context_unit_test.rb
|
182
|
+
- test/unit/tokenizer_unit_test.rb
|
183
|
+
- test/unit/tag_unit_test.rb
|
184
|
+
- test/unit/i18n_unit_test.rb
|
185
|
+
- test/unit/template_unit_test.rb
|
186
|
+
- test/unit/condition_unit_test.rb
|
187
|
+
- test/unit/file_system_unit_test.rb
|
188
|
+
- test/unit/regexp_unit_test.rb
|
189
|
+
- test/unit/strainer_unit_test.rb
|
190
|
+
- test/integration/output_test.rb
|
191
|
+
- test/integration/hash_ordering_test.rb
|
192
|
+
- test/integration/variable_test.rb
|
175
193
|
- test/integration/blank_test.rb
|
176
|
-
- test/integration/
|
194
|
+
- test/integration/assign_test.rb
|
195
|
+
- test/integration/trim_mode_test.rb
|
177
196
|
- test/integration/context_test.rb
|
178
|
-
- test/integration/
|
179
|
-
- test/integration/
|
180
|
-
- test/integration/error_handling_test.rb
|
181
|
-
- test/integration/filter_test.rb
|
182
|
-
- test/integration/hash_ordering_test.rb
|
183
|
-
- test/integration/output_test.rb
|
184
|
-
- test/integration/parsing_quirks_test.rb
|
185
|
-
- test/integration/render_profiling_test.rb
|
186
|
-
- test/integration/security_test.rb
|
187
|
-
- test/integration/standard_filter_test.rb
|
188
|
-
- test/integration/tags/break_tag_test.rb
|
189
|
-
- test/integration/tags/continue_tag_test.rb
|
197
|
+
- test/integration/capture_test.rb
|
198
|
+
- test/integration/tags/increment_tag_test.rb
|
190
199
|
- test/integration/tags/for_tag_test.rb
|
191
|
-
- test/integration/tags/
|
200
|
+
- test/integration/tags/standard_tag_test.rb
|
201
|
+
- test/integration/tags/table_row_test.rb
|
192
202
|
- test/integration/tags/include_tag_test.rb
|
193
|
-
- test/integration/tags/increment_tag_test.rb
|
194
203
|
- test/integration/tags/raw_tag_test.rb
|
195
|
-
- test/integration/tags/standard_tag_test.rb
|
196
204
|
- test/integration/tags/statements_test.rb
|
197
|
-
- test/integration/tags/
|
205
|
+
- test/integration/tags/if_else_tag_test.rb
|
198
206
|
- test/integration/tags/unless_else_tag_test.rb
|
207
|
+
- test/integration/tags/continue_tag_test.rb
|
208
|
+
- test/integration/tags/break_tag_test.rb
|
209
|
+
- test/integration/block_test.rb
|
210
|
+
- test/integration/standard_filter_test.rb
|
211
|
+
- test/integration/drop_test.rb
|
212
|
+
- test/integration/error_handling_test.rb
|
199
213
|
- test/integration/template_test.rb
|
200
|
-
- test/integration/
|
201
|
-
- test/integration/
|
214
|
+
- test/integration/document_test.rb
|
215
|
+
- test/integration/security_test.rb
|
216
|
+
- test/integration/render_profiling_test.rb
|
217
|
+
- test/integration/parsing_quirks_test.rb
|
218
|
+
- test/integration/filter_test.rb
|
219
|
+
- test/fixtures/en_locale.yml
|
202
220
|
- test/test_helper.rb
|
203
|
-
- test/unit/block_unit_test.rb
|
204
|
-
- test/unit/condition_unit_test.rb
|
205
|
-
- test/unit/context_unit_test.rb
|
206
|
-
- test/unit/file_system_unit_test.rb
|
207
|
-
- test/unit/i18n_unit_test.rb
|
208
|
-
- test/unit/lexer_unit_test.rb
|
209
|
-
- test/unit/parser_unit_test.rb
|
210
|
-
- test/unit/regexp_unit_test.rb
|
211
|
-
- test/unit/strainer_unit_test.rb
|
212
|
-
- test/unit/tag_unit_test.rb
|
213
|
-
- test/unit/tags/case_tag_unit_test.rb
|
214
|
-
- test/unit/tags/for_tag_unit_test.rb
|
215
|
-
- test/unit/tags/if_tag_unit_test.rb
|
216
|
-
- test/unit/template_unit_test.rb
|
217
|
-
- test/unit/tokenizer_unit_test.rb
|
218
|
-
- test/unit/variable_unit_test.rb
|