liquid 5.0.0 → 5.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0b1c036e6dd6d55418e6364b008551f5d3ba91f6e7dbc1c0ac3be43b235bd957
4
- data.tar.gz: a6279802ed388bcffc8980c49bcb0034a0f98de7cd6730bf97f603c07bf13dcd
3
+ metadata.gz: 98bb40e18a2bb905a917743968edb79732f903b3beb1f51ab9551e1aaee3f91a
4
+ data.tar.gz: 264b8ccd158a79f2b43a0308a055d38b018b0f4132f316007f3589e778f5d9dd
5
5
  SHA512:
6
- metadata.gz: 0c5094a47d46c8de3ac8ac632dbec8b813c1e47af834c0037ed9b868f5a2dde4da8dfdd143ff34c41505c1425524f1879ca909525676028cadd9900cbd028e63
7
- data.tar.gz: 7195f154c81283e8b7d99a07b82a2d9976b41be761efc528945f79ac0d77c2ff9c7632b3455f871b6db0471979c35e633f87e1c33900e4f9898012f836fd1496
6
+ metadata.gz: 19b30524fc6b7828de10e3eecc4e28b5595436144eacedad06c36d6472b740d01e971d315f7aa911ebad80dac5c075b75649c0b506f588e50ff8c977f08ed365
7
+ data.tar.gz: 53726f629d8a76ebcc4e134bc12abe981df9526fb5baa4d9312b68bc967e691af329bfcabadad86af65b8149034bd94479a2f98a93a9056a090fd28ba2901597
data/History.md CHANGED
@@ -1,5 +1,15 @@
1
1
  # Liquid Change Log
2
2
 
3
+ ## 5.0.1 / 2021-03-24
4
+
5
+ ### Fixes
6
+ * Add ParseTreeVisitor to Echo tag (#1414) [CP Clermont]
7
+ * Test with ruby 3.0 as the latest ruby version (#1398) [Dylan Thacker-Smith]
8
+ * Handle carriage return in newlines_to_br (#1391) [Unending]
9
+
10
+ ### Performance Improvements
11
+ * Use split limit in truncatewords (#1361) [Dylan Thacker-Smith]
12
+
3
13
  ## 5.0.0 / 2021-01-06
4
14
 
5
15
  ### Features
@@ -99,7 +99,9 @@ module Liquid
99
99
  end
100
100
 
101
101
  private def parse_liquid_tag(markup, parse_context)
102
- liquid_tag_tokenizer = Tokenizer.new(markup, line_number: parse_context.line_number, for_liquid_tag: true)
102
+ liquid_tag_tokenizer = parse_context.new_tokenizer(
103
+ markup, start_line_number: parse_context.line_number, for_liquid_tag: true
104
+ )
103
105
  parse_for_liquid_tag(liquid_tag_tokenizer, parse_context) do |end_tag_name, _end_tag_markup|
104
106
  if end_tag_name
105
107
  BlockBody.unknown_tag_in_liquid_tag(end_tag_name, parse_context)
@@ -23,6 +23,10 @@ module Liquid
23
23
  Liquid::BlockBody.new
24
24
  end
25
25
 
26
+ def new_tokenizer(markup, start_line_number: nil, for_liquid_tag: false)
27
+ Tokenizer.new(markup, line_number: start_line_number, for_liquid_tag: for_liquid_tag)
28
+ end
29
+
26
30
  def parse_expression(markup)
27
31
  Expression.parse(markup)
28
32
  end
@@ -89,13 +89,15 @@ module Liquid
89
89
 
90
90
  def truncatewords(input, words = 15, truncate_string = "...")
91
91
  return if input.nil?
92
- wordlist = input.to_s.split
93
- words = Utils.to_integer(words)
92
+ input = input.to_s
93
+ words = Utils.to_integer(words)
94
+ words = 1 if words <= 0
94
95
 
95
- l = words - 1
96
- l = 0 if l < 0
96
+ wordlist = input.split(" ", words + 1)
97
+ return input if wordlist.length <= words
97
98
 
98
- wordlist.length > l ? wordlist[0..l].join(" ").concat(truncate_string.to_s) : input
99
+ wordlist.pop
100
+ wordlist.join(" ").concat(truncate_string.to_s)
99
101
  end
100
102
 
101
103
  # Split input string into an array of substrings separated by given pattern.
@@ -295,7 +297,7 @@ module Liquid
295
297
 
296
298
  # Add <br /> tags in front of all newlines in input string
297
299
  def newline_to_br(input)
298
- input.to_s.gsub(/\n/, "<br />\n")
300
+ input.to_s.gsub(/\r?\n/, "<br />\n")
299
301
  end
300
302
 
301
303
  # Reformat a date using Ruby's core Time#strftime( string ) -> string
@@ -12,6 +12,8 @@ module Liquid
12
12
  # {% echo user | link %}
13
13
  #
14
14
  class Echo < Tag
15
+ attr_reader :variable
16
+
15
17
  def initialize(tag_name, markup, parse_context)
16
18
  super
17
19
  @variable = Variable.new(markup, parse_context)
@@ -20,6 +22,12 @@ module Liquid
20
22
  def render(context)
21
23
  @variable.render_to_output_buffer(context, +'')
22
24
  end
25
+
26
+ class ParseTreeVisitor < Liquid::ParseTreeVisitor
27
+ def children
28
+ [@node.variable]
29
+ end
30
+ end
23
31
  end
24
32
 
25
33
  Template.register_tag('echo', Echo)
@@ -107,7 +107,8 @@ module Liquid
107
107
  # Returns self for easy chaining
108
108
  def parse(source, options = {})
109
109
  parse_context = configure_options(options)
110
- @root = Document.parse(tokenize(source), parse_context)
110
+ tokenizer = parse_context.new_tokenizer(source, start_line_number: @line_numbers && 1)
111
+ @root = Document.parse(tokenizer, parse_context)
111
112
  self
112
113
  end
113
114
 
@@ -223,10 +224,6 @@ module Liquid
223
224
  parse_context
224
225
  end
225
226
 
226
- def tokenize(source)
227
- Tokenizer.new(source, @line_numbers)
228
- end
229
-
230
227
  def apply_options_to_context(context, options)
231
228
  context.add_filters(options[:filters]) if options[:filters]
232
229
  context.global_filter = options[:global_filter] if options[:global_filter]
@@ -2,5 +2,5 @@
2
2
  # frozen_string_literal: true
3
3
 
4
4
  module Liquid
5
- VERSION = "5.0.0"
5
+ VERSION = "5.0.1"
6
6
  end
@@ -461,6 +461,7 @@ class ContextTest < Minitest::Test
461
461
  end
462
462
 
463
463
  def test_interrupt_avoids_object_allocations
464
+ @context.interrupt? # ruby 3.0.0 allocates on the first call
464
465
  assert_no_object_allocations do
465
466
  @context.interrupt?
466
467
  end
@@ -171,10 +171,13 @@ class StandardFiltersTest < Minitest::Test
171
171
  assert_equal('one two three', @filters.truncatewords('one two three'))
172
172
  assert_equal(
173
173
  'Two small (13&#8221; x 5.5&#8221; x 10&#8221; high) baskets fit inside one large basket (13&#8221;...',
174
- @filters.truncatewords('Two small (13&#8221; x 5.5&#8221; x 10&#8221; high) baskets fit inside one large basket (13&#8221; x 16&#8221; x 10.5&#8221; high) with cover.', 15)
174
+ @filters.truncatewords('Two small (13&#8221; x 5.5&#8221; x 10&#8221; high) baskets fit inside one large basket (13&#8221; x 16&#8221; x 10.5&#8221; high) with cover.', 15)
175
175
  )
176
176
  assert_equal("测试测试测试测试", @filters.truncatewords('测试测试测试测试', 5))
177
177
  assert_equal('one two1', @filters.truncatewords("one two three", 2, 1))
178
+ assert_equal('one two three...', @filters.truncatewords("one two\tthree\nfour", 3))
179
+ assert_equal('one two...', @filters.truncatewords("one two three four", 2))
180
+ assert_equal('one...', @filters.truncatewords("one two three four", 0))
178
181
  end
179
182
 
180
183
  def test_strip_html
@@ -539,6 +542,7 @@ class StandardFiltersTest < Minitest::Test
539
542
 
540
543
  def test_newlines_to_br
541
544
  assert_template_result("a<br />\nb<br />\nc", "{{ source | newline_to_br }}", 'source' => "a\nb\nc")
545
+ assert_template_result("a<br />\nb<br />\nc", "{{ source | newline_to_br }}", 'source' => "a\r\nb\nc")
542
546
  end
543
547
 
544
548
  def test_plus
@@ -96,12 +96,12 @@ class IncludeTagTest < Minitest::Test
96
96
 
97
97
  def test_include_tag_with_alias
98
98
  assert_template_result("Product: Draft 151cm ",
99
- "{% include 'product_alias' with products[0] as product %}", "products" => [{ 'title' => 'Draft 151cm' }, { 'title' => 'Element 155cm' }])
99
+ "{% include 'product_alias' with products[0] as product %}", "products" => [{ 'title' => 'Draft 151cm' }, { 'title' => 'Element 155cm' }])
100
100
  end
101
101
 
102
102
  def test_include_tag_for_alias
103
103
  assert_template_result("Product: Draft 151cm Product: Element 155cm ",
104
- "{% include 'product_alias' for products as product %}", "products" => [{ 'title' => 'Draft 151cm' }, { 'title' => 'Element 155cm' }])
104
+ "{% include 'product_alias' for products as product %}", "products" => [{ 'title' => 'Draft 151cm' }, { 'title' => 'Element 155cm' }])
105
105
  end
106
106
 
107
107
  def test_include_tag_with_default_name
@@ -151,7 +151,7 @@ class RenderTagTest < Minitest::Test
151
151
  )
152
152
 
153
153
  assert_template_result("Product: Draft 151cm ",
154
- "{% render 'product' with products[0] %}", "products" => [{ 'title' => 'Draft 151cm' }, { 'title' => 'Element 155cm' }])
154
+ "{% render 'product' with products[0] %}", "products" => [{ 'title' => 'Draft 151cm' }, { 'title' => 'Element 155cm' }])
155
155
  end
156
156
 
157
157
  def test_render_tag_with_alias
@@ -161,7 +161,7 @@ class RenderTagTest < Minitest::Test
161
161
  )
162
162
 
163
163
  assert_template_result("Product: Draft 151cm ",
164
- "{% render 'product_alias' with products[0] as product %}", "products" => [{ 'title' => 'Draft 151cm' }, { 'title' => 'Element 155cm' }])
164
+ "{% render 'product_alias' with products[0] as product %}", "products" => [{ 'title' => 'Draft 151cm' }, { 'title' => 'Element 155cm' }])
165
165
  end
166
166
 
167
167
  def test_render_tag_for_alias
@@ -171,7 +171,7 @@ class RenderTagTest < Minitest::Test
171
171
  )
172
172
 
173
173
  assert_template_result("Product: Draft 151cm Product: Element 155cm ",
174
- "{% render 'product_alias' for products as product %}", "products" => [{ 'title' => 'Draft 151cm' }, { 'title' => 'Element 155cm' }])
174
+ "{% render 'product_alias' for products as product %}", "products" => [{ 'title' => 'Draft 151cm' }, { 'title' => 'Element 155cm' }])
175
175
  end
176
176
 
177
177
  def test_render_tag_for
@@ -181,7 +181,7 @@ class RenderTagTest < Minitest::Test
181
181
  )
182
182
 
183
183
  assert_template_result("Product: Draft 151cm Product: Element 155cm ",
184
- "{% render 'product' for products %}", "products" => [{ 'title' => 'Draft 151cm' }, { 'title' => 'Element 155cm' }])
184
+ "{% render 'product' for products %}", "products" => [{ 'title' => 'Draft 151cm' }, { 'title' => 'Element 155cm' }])
185
185
  end
186
186
 
187
187
  def test_render_tag_forloop
@@ -190,7 +190,7 @@ class RenderTagTest < Minitest::Test
190
190
  )
191
191
 
192
192
  assert_template_result("Product: Draft 151cm first index:1 Product: Element 155cm last index:2 ",
193
- "{% render 'product' for products %}", "products" => [{ 'title' => 'Draft 151cm' }, { 'title' => 'Element 155cm' }])
193
+ "{% render 'product' for products %}", "products" => [{ 'title' => 'Draft 151cm' }, { 'title' => 'Element 155cm' }])
194
194
  end
195
195
 
196
196
  def test_render_tag_for_drop
@@ -199,7 +199,7 @@ class RenderTagTest < Minitest::Test
199
199
  )
200
200
 
201
201
  assert_template_result("123",
202
- "{% render 'loop' for loop as value %}", "loop" => TestEnumerable.new)
202
+ "{% render 'loop' for loop as value %}", "loop" => TestEnumerable.new)
203
203
  end
204
204
 
205
205
  def test_render_tag_with_drop
@@ -208,6 +208,6 @@ class RenderTagTest < Minitest::Test
208
208
  )
209
209
 
210
210
  assert_template_result("TestEnumerable",
211
- "{% render 'loop' with loop as value %}", "loop" => TestEnumerable.new)
211
+ "{% render 'loop' with loop as value %}", "loop" => TestEnumerable.new)
212
212
  end
213
213
  end
@@ -26,6 +26,13 @@ class ParseTreeVisitorTest < Minitest::Test
26
26
  )
27
27
  end
28
28
 
29
+ def test_echo
30
+ assert_equal(
31
+ ["test"],
32
+ visit(%({% echo test %}))
33
+ )
34
+ end
35
+
29
36
  def test_if_condition
30
37
  assert_equal(
31
38
  ["test"],
@@ -32,21 +32,26 @@ class TokenizerTest < Minitest::Test
32
32
 
33
33
  private
34
34
 
35
+ def new_tokenizer(source, parse_context: Liquid::ParseContext.new, start_line_number: nil)
36
+ parse_context.new_tokenizer(source, start_line_number: start_line_number)
37
+ end
38
+
35
39
  def tokenize(source)
36
- tokenizer = Liquid::Tokenizer.new(source)
40
+ tokenizer = new_tokenizer(source)
37
41
  tokens = []
38
- while (t = tokenizer.shift)
42
+ # shift is private in Liquid::C::Tokenizer, since it is only for unit testing
43
+ while (t = tokenizer.send(:shift))
39
44
  tokens << t
40
45
  end
41
46
  tokens
42
47
  end
43
48
 
44
49
  def tokenize_line_numbers(source)
45
- tokenizer = Liquid::Tokenizer.new(source, true)
50
+ tokenizer = new_tokenizer(source, start_line_number: 1)
46
51
  line_numbers = []
47
52
  loop do
48
53
  line_number = tokenizer.line_number
49
- if tokenizer.shift
54
+ if tokenizer.send(:shift)
50
55
  line_numbers << line_number
51
56
  else
52
57
  break
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: 5.0.0
4
+ version: 5.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: 2021-01-06 00:00:00.000000000 Z
11
+ date: 2021-03-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -192,60 +192,60 @@ signing_key:
192
192
  specification_version: 4
193
193
  summary: A secure, non-evaling end user template engine with aesthetic markup.
194
194
  test_files:
195
- - test/unit/lexer_unit_test.rb
195
+ - test/fixtures/en_locale.yml
196
196
  - test/unit/condition_unit_test.rb
197
- - test/unit/template_factory_unit_test.rb
198
- - test/unit/tag_unit_test.rb
199
- - test/unit/tokenizer_unit_test.rb
200
- - test/unit/regexp_unit_test.rb
201
- - test/unit/file_system_unit_test.rb
202
- - test/unit/block_unit_test.rb
203
- - test/unit/strainer_factory_unit_test.rb
204
- - test/unit/i18n_unit_test.rb
205
197
  - test/unit/variable_unit_test.rb
206
- - test/unit/static_registers_unit_test.rb
207
- - test/unit/strainer_template_unit_test.rb
208
198
  - test/unit/template_unit_test.rb
209
- - test/unit/partial_cache_unit_test.rb
210
- - test/unit/parse_tree_visitor_test.rb
199
+ - test/unit/strainer_template_unit_test.rb
200
+ - test/unit/file_system_unit_test.rb
201
+ - test/unit/static_registers_unit_test.rb
202
+ - test/unit/tags/for_tag_unit_test.rb
211
203
  - test/unit/tags/if_tag_unit_test.rb
212
204
  - test/unit/tags/case_tag_unit_test.rb
213
- - test/unit/tags/for_tag_unit_test.rb
205
+ - test/unit/strainer_factory_unit_test.rb
206
+ - test/unit/parse_tree_visitor_test.rb
207
+ - test/unit/lexer_unit_test.rb
208
+ - test/unit/block_unit_test.rb
209
+ - test/unit/regexp_unit_test.rb
210
+ - test/unit/partial_cache_unit_test.rb
214
211
  - test/unit/parser_unit_test.rb
212
+ - test/unit/tag_unit_test.rb
213
+ - test/unit/i18n_unit_test.rb
214
+ - test/unit/tokenizer_unit_test.rb
215
+ - test/unit/template_factory_unit_test.rb
215
216
  - test/test_helper.rb
216
- - test/integration/expression_test.rb
217
+ - test/integration/blank_test.rb
218
+ - test/integration/standard_filter_test.rb
217
219
  - test/integration/parsing_quirks_test.rb
220
+ - test/integration/tag/disableable_test.rb
221
+ - test/integration/context_test.rb
222
+ - test/integration/error_handling_test.rb
218
223
  - test/integration/security_test.rb
219
- - test/integration/template_test.rb
220
- - test/integration/filter_test.rb
221
- - test/integration/drop_test.rb
222
- - test/integration/blank_test.rb
223
224
  - test/integration/capture_test.rb
224
- - test/integration/context_test.rb
225
- - test/integration/document_test.rb
226
- - test/integration/block_test.rb
227
- - test/integration/tag_test.rb
228
- - test/integration/tag/disableable_test.rb
229
- - test/integration/standard_filter_test.rb
230
- - test/integration/output_test.rb
231
225
  - test/integration/assign_test.rb
232
- - test/integration/profiler_test.rb
233
- - test/integration/trim_mode_test.rb
234
- - test/integration/error_handling_test.rb
235
- - test/integration/tags/echo_test.rb
236
- - test/integration/tags/raw_tag_test.rb
237
- - test/integration/tags/statements_test.rb
238
- - test/integration/tags/for_tag_test.rb
239
- - test/integration/tags/standard_tag_test.rb
240
- - test/integration/tags/render_tag_test.rb
241
- - test/integration/tags/table_row_test.rb
226
+ - test/integration/tags/increment_tag_test.rb
242
227
  - test/integration/tags/break_tag_test.rb
243
228
  - test/integration/tags/if_else_tag_test.rb
229
+ - test/integration/tags/liquid_tag_test.rb
230
+ - test/integration/tags/for_tag_test.rb
244
231
  - test/integration/tags/unless_else_tag_test.rb
245
- - test/integration/tags/continue_tag_test.rb
246
232
  - test/integration/tags/include_tag_test.rb
247
- - test/integration/tags/liquid_tag_test.rb
248
- - test/integration/tags/increment_tag_test.rb
249
- - test/integration/hash_ordering_test.rb
233
+ - test/integration/tags/echo_test.rb
234
+ - test/integration/tags/statements_test.rb
235
+ - test/integration/tags/render_tag_test.rb
236
+ - test/integration/tags/raw_tag_test.rb
237
+ - test/integration/tags/continue_tag_test.rb
238
+ - test/integration/tags/table_row_test.rb
239
+ - test/integration/tags/standard_tag_test.rb
250
240
  - test/integration/variable_test.rb
251
- - test/fixtures/en_locale.yml
241
+ - test/integration/template_test.rb
242
+ - test/integration/block_test.rb
243
+ - test/integration/profiler_test.rb
244
+ - test/integration/drop_test.rb
245
+ - test/integration/expression_test.rb
246
+ - test/integration/filter_test.rb
247
+ - test/integration/document_test.rb
248
+ - test/integration/trim_mode_test.rb
249
+ - test/integration/output_test.rb
250
+ - test/integration/hash_ordering_test.rb
251
+ - test/integration/tag_test.rb