liquid 5.3.0 → 5.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (96) hide show
  1. checksums.yaml +4 -4
  2. data/History.md +16 -1
  3. data/README.md +2 -2
  4. data/lib/liquid/block_body.rb +4 -4
  5. data/lib/liquid/context.rb +6 -2
  6. data/lib/liquid/forloop_drop.rb +44 -1
  7. data/lib/liquid/locales/en.yml +6 -5
  8. data/lib/liquid/partial_cache.rb +3 -3
  9. data/lib/liquid/{static_registers.rb → registers.rb} +13 -10
  10. data/lib/liquid/standardfilters.rb +406 -57
  11. data/lib/liquid/strainer_factory.rb +4 -0
  12. data/lib/liquid/strainer_template.rb +4 -0
  13. data/lib/liquid/tablerowloop_drop.rb +58 -1
  14. data/lib/liquid/tags/assign.rb +12 -8
  15. data/lib/liquid/tags/break.rb +8 -0
  16. data/lib/liquid/tags/capture.rb +13 -10
  17. data/lib/liquid/tags/case.rb +21 -0
  18. data/lib/liquid/tags/comment.rb +13 -0
  19. data/lib/liquid/tags/continue.rb +8 -9
  20. data/lib/liquid/tags/cycle.rb +12 -11
  21. data/lib/liquid/tags/decrement.rb +16 -17
  22. data/lib/liquid/tags/echo.rb +16 -9
  23. data/lib/liquid/tags/for.rb +22 -43
  24. data/lib/liquid/tags/if.rb +11 -9
  25. data/lib/liquid/tags/include.rb +15 -13
  26. data/lib/liquid/tags/increment.rb +16 -14
  27. data/lib/liquid/tags/inline_comment.rb +43 -0
  28. data/lib/liquid/tags/raw.rb +11 -0
  29. data/lib/liquid/tags/render.rb +29 -4
  30. data/lib/liquid/tags/table_row.rb +22 -0
  31. data/lib/liquid/tags/unless.rb +15 -4
  32. data/lib/liquid/template.rb +2 -3
  33. data/lib/liquid/variable.rb +4 -4
  34. data/lib/liquid/variable_lookup.rb +10 -7
  35. data/lib/liquid/version.rb +1 -1
  36. data/lib/liquid.rb +2 -2
  37. metadata +7 -123
  38. data/lib/liquid/register.rb +0 -6
  39. data/test/fixtures/en_locale.yml +0 -9
  40. data/test/integration/assign_test.rb +0 -117
  41. data/test/integration/blank_test.rb +0 -109
  42. data/test/integration/block_test.rb +0 -58
  43. data/test/integration/capture_test.rb +0 -58
  44. data/test/integration/context_test.rb +0 -634
  45. data/test/integration/document_test.rb +0 -21
  46. data/test/integration/drop_test.rb +0 -257
  47. data/test/integration/error_handling_test.rb +0 -272
  48. data/test/integration/expression_test.rb +0 -46
  49. data/test/integration/filter_kwarg_test.rb +0 -24
  50. data/test/integration/filter_test.rb +0 -189
  51. data/test/integration/hash_ordering_test.rb +0 -25
  52. data/test/integration/output_test.rb +0 -125
  53. data/test/integration/parsing_quirks_test.rb +0 -134
  54. data/test/integration/profiler_test.rb +0 -240
  55. data/test/integration/security_test.rb +0 -89
  56. data/test/integration/standard_filter_test.rb +0 -925
  57. data/test/integration/tag/disableable_test.rb +0 -59
  58. data/test/integration/tag_test.rb +0 -45
  59. data/test/integration/tags/break_tag_test.rb +0 -17
  60. data/test/integration/tags/continue_tag_test.rb +0 -17
  61. data/test/integration/tags/echo_test.rb +0 -13
  62. data/test/integration/tags/for_tag_test.rb +0 -466
  63. data/test/integration/tags/if_else_tag_test.rb +0 -190
  64. data/test/integration/tags/include_tag_test.rb +0 -269
  65. data/test/integration/tags/increment_tag_test.rb +0 -25
  66. data/test/integration/tags/liquid_tag_test.rb +0 -116
  67. data/test/integration/tags/raw_tag_test.rb +0 -34
  68. data/test/integration/tags/render_tag_test.rb +0 -213
  69. data/test/integration/tags/standard_tag_test.rb +0 -303
  70. data/test/integration/tags/statements_test.rb +0 -113
  71. data/test/integration/tags/table_row_test.rb +0 -66
  72. data/test/integration/tags/unless_else_tag_test.rb +0 -28
  73. data/test/integration/template_test.rb +0 -340
  74. data/test/integration/trim_mode_test.rb +0 -563
  75. data/test/integration/variable_test.rb +0 -138
  76. data/test/test_helper.rb +0 -207
  77. data/test/unit/block_unit_test.rb +0 -53
  78. data/test/unit/condition_unit_test.rb +0 -181
  79. data/test/unit/file_system_unit_test.rb +0 -37
  80. data/test/unit/i18n_unit_test.rb +0 -39
  81. data/test/unit/lexer_unit_test.rb +0 -53
  82. data/test/unit/parse_tree_visitor_test.rb +0 -261
  83. data/test/unit/parser_unit_test.rb +0 -84
  84. data/test/unit/partial_cache_unit_test.rb +0 -128
  85. data/test/unit/regexp_unit_test.rb +0 -46
  86. data/test/unit/static_registers_unit_test.rb +0 -156
  87. data/test/unit/strainer_factory_unit_test.rb +0 -101
  88. data/test/unit/strainer_template_unit_test.rb +0 -82
  89. data/test/unit/tag_unit_test.rb +0 -23
  90. data/test/unit/tags/case_tag_unit_test.rb +0 -12
  91. data/test/unit/tags/for_tag_unit_test.rb +0 -15
  92. data/test/unit/tags/if_tag_unit_test.rb +0 -10
  93. data/test/unit/template_factory_unit_test.rb +0 -12
  94. data/test/unit/template_unit_test.rb +0 -87
  95. data/test/unit/tokenizer_unit_test.rb +0 -62
  96. data/test/unit/variable_unit_test.rb +0 -164
@@ -1,13 +1,37 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Liquid
4
+ # @liquid_public_docs
5
+ # @liquid_type tag
6
+ # @liquid_category theme
7
+ # @liquid_name render
8
+ # @liquid_summary
9
+ # Renders a [snippet](/themes/architecture#snippets) or [app block](/themes/architecture/sections/section-schema#render-app-blocks).
10
+ # @liquid_description
11
+ # Inside snippets and app blocks, you can't directly access variables that are [created](/api/liquid/tags#variable-tags) outside
12
+ # of the snippet or app block. However, you can [specify variables as parameters](/api/liquid/tags#render-passing-variables-to-snippets)
13
+ # to pass outside variables to snippets.
14
+ #
15
+ # While you can't directly access created variables, you can access global objects, as well as any objects that are
16
+ # directly accessible outside the snippet or app block. For example, a snippet or app block inside the [product template](/themes/architecture/templates/product)
17
+ # can access the [`product` object](/api/liquid/objects#product), and a snippet or app block inside a [section](/themes/architecture/sections)
18
+ # can access the [`section` object](/api/liquid/objects#section).
19
+ #
20
+ # Outside a snippet or app block, you can't access variables created inside the snippet or app block.
21
+ #
22
+ # > Note:
23
+ # > When you render a snippet using the `render` tag, you can't use the [`include` tag](/api/liquid/tags#include)
24
+ # > inside the snippet.
25
+ # @liquid_syntax
26
+ # {% render 'filename' %}
27
+ # @liquid_syntax_keyword filename The name of the snippet to render, without the `.liquid` extension.
4
28
  class Render < Tag
5
29
  FOR = 'for'
6
30
  SYNTAX = /(#{QuotedString}+)(\s+(with|#{FOR})\s+(#{QuotedFragment}+))?(\s+(?:as)\s+(#{VariableSegment}+))?/o
7
31
 
8
32
  disable_tags "include"
9
33
 
10
- attr_reader :template_name_expr, :attributes
34
+ attr_reader :template_name_expr, :variable_name_expr, :attributes
11
35
 
12
36
  def initialize(tag_name, markup, options)
13
37
  super
@@ -34,9 +58,9 @@ module Liquid
34
58
  end
35
59
 
36
60
  def render_tag(context, output)
37
- # Though we evaluate this here we will only ever parse it as a string literal.
38
- template_name = context.evaluate(@template_name_expr)
39
- raise ArgumentError, options[:locale].t("errors.argument.include") unless template_name
61
+ # The expression should be a String literal, which parses to a String object
62
+ template_name = @template_name_expr
63
+ raise ::ArgumentError unless template_name.is_a?(String)
40
64
 
41
65
  partial = PartialCache.load(
42
66
  template_name,
@@ -75,6 +99,7 @@ module Liquid
75
99
  def children
76
100
  [
77
101
  @node.template_name_expr,
102
+ @node.variable_name_expr,
78
103
  ] + @node.attributes.values
79
104
  end
80
105
  end
@@ -1,6 +1,28 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Liquid
4
+ # @liquid_public_docs
5
+ # @liquid_type tag
6
+ # @liquid_category iteration
7
+ # @liquid_name tablerow
8
+ # @liquid_summary
9
+ # Generates HTML table rows for every item in an array.
10
+ # @liquid_description
11
+ # The `tablerow` tag must be wrapped in HTML `<table>` and `</table>` tags.
12
+ #
13
+ # > Tip:
14
+ # > Every `tablerow` loop has an associated [`tablerowloop` object](/api/liquid/objects#tablerowloop) with information about the loop.
15
+ # @liquid_syntax
16
+ # {% tablerow variable in array %}
17
+ # expression
18
+ # {% endtablerow %}
19
+ # @liquid_syntax_keyword variable The current item in the array.
20
+ # @liquid_syntax_keyword array The array to iterate over.
21
+ # @liquid_syntax_keyword expression The expression to render.
22
+ # @liquid_optional_param cols [number] The number of columns that the table should have.
23
+ # @liquid_optional_param limit [number] The number of iterations to perform.
24
+ # @liquid_optional_param offset [number] The 1-based index to start iterating at.
25
+ # @liquid_optional_param range [untyped] A custom numeric range to iterate over.
4
26
  class TableRow < Block
5
27
  Syntax = /(\w+)\s+in\s+(#{QuotedFragment}+)/o
6
28
 
@@ -3,10 +3,21 @@
3
3
  require_relative 'if'
4
4
 
5
5
  module Liquid
6
- # Unless is a conditional just like 'if' but works on the inverse logic.
7
- #
8
- # {% unless x < 0 %} x is greater than zero {% endunless %}
9
- #
6
+ # @liquid_public_docs
7
+ # @liquid_type tag
8
+ # @liquid_category conditional
9
+ # @liquid_name unless
10
+ # @liquid_summary
11
+ # Renders an expression unless a specific condition is `true`.
12
+ # @liquid_description
13
+ # > Tip:
14
+ # > Similar to the [`if` tag](/api/liquid/tags#if), you can use `elsif` to add more conditions to an `unless` tag.
15
+ # @liquid_syntax
16
+ # {% unless condition %}
17
+ # expression
18
+ # {% endunless %}
19
+ # @liquid_syntax_keyword condition The condition to evaluate.
20
+ # @liquid_syntax_keyword expression The expression to render unless the condition is met.
10
21
  class Unless < If
11
22
  def render_to_output_buffer(context, output)
12
23
  # First condition is interpreted backwards ( if not )
@@ -167,15 +167,14 @@ module Liquid
167
167
 
168
168
  output = nil
169
169
 
170
- context_register = context.registers.is_a?(StaticRegisters) ? context.registers.static : context.registers
171
-
172
170
  case args.last
173
171
  when Hash
174
172
  options = args.pop
175
173
  output = options[:output] if options[:output]
174
+ static_registers = context.registers.static
176
175
 
177
176
  options[:registers]&.each do |key, register|
178
- context_register[key] = register
177
+ static_registers[key] = register
179
178
  end
180
179
 
181
180
  apply_options_to_context(context, options)
@@ -47,7 +47,7 @@ module Liquid
47
47
 
48
48
  name_markup = Regexp.last_match(1)
49
49
  filter_markup = Regexp.last_match(2)
50
- @name = Expression.parse(name_markup)
50
+ @name = parse_context.parse_expression(name_markup)
51
51
  if filter_markup =~ FilterMarkupRegex
52
52
  filters = Regexp.last_match(1).scan(FilterParser)
53
53
  filters.each do |f|
@@ -65,7 +65,7 @@ module Liquid
65
65
 
66
66
  return if p.look(:end_of_string)
67
67
 
68
- @name = Expression.parse(p.expression)
68
+ @name = parse_context.parse_expression(p.expression)
69
69
  while p.consume?(:pipe)
70
70
  filtername = p.consume(:id)
71
71
  filterargs = p.consume?(:colon) ? parse_filterargs(p) : []
@@ -122,9 +122,9 @@ module Liquid
122
122
  unparsed_args.each do |a|
123
123
  if (matches = a.match(JustTagAttributes))
124
124
  keyword_args ||= {}
125
- keyword_args[matches[1]] = Expression.parse(matches[2])
125
+ keyword_args[matches[1]] = parse_context.parse_expression(matches[2])
126
126
  else
127
- filter_args << Expression.parse(a)
127
+ filter_args << parse_context.parse_expression(a)
128
128
  end
129
129
  end
130
130
  result = [filter_name, filter_args]
@@ -2,8 +2,7 @@
2
2
 
3
3
  module Liquid
4
4
  class VariableLookup
5
- SQUARE_BRACKETED = /\A\[(.*)\]\z/m
6
- COMMAND_METHODS = ['size', 'first', 'last'].freeze
5
+ COMMAND_METHODS = ['size', 'first', 'last'].freeze
7
6
 
8
7
  attr_reader :name, :lookups
9
8
 
@@ -15,8 +14,8 @@ module Liquid
15
14
  lookups = markup.scan(VariableParser)
16
15
 
17
16
  name = lookups.shift
18
- if name =~ SQUARE_BRACKETED
19
- name = Expression.parse(Regexp.last_match(1))
17
+ if name&.start_with?('[') && name&.end_with?(']')
18
+ name = Expression.parse(name[1..-2])
20
19
  end
21
20
  @name = name
22
21
 
@@ -25,14 +24,18 @@ module Liquid
25
24
 
26
25
  @lookups.each_index do |i|
27
26
  lookup = lookups[i]
28
- if lookup =~ SQUARE_BRACKETED
29
- lookups[i] = Expression.parse(Regexp.last_match(1))
27
+ if lookup&.start_with?('[') && lookup&.end_with?(']')
28
+ lookups[i] = Expression.parse(lookup[1..-2])
30
29
  elsif COMMAND_METHODS.include?(lookup)
31
30
  @command_flags |= 1 << i
32
31
  end
33
32
  end
34
33
  end
35
34
 
35
+ def lookup_command?(lookup_index)
36
+ @command_flags & (1 << lookup_index) != 0
37
+ end
38
+
36
39
  def evaluate(context)
37
40
  name = context.evaluate(@name)
38
41
  object = context.find_variable(name)
@@ -56,7 +59,7 @@ module Liquid
56
59
  # Some special cases. If the part wasn't in square brackets and
57
60
  # no key with the same name was found we interpret following calls
58
61
  # as commands and call them on the current object
59
- elsif @command_flags & (1 << i) != 0 && object.respond_to?(key)
62
+ elsif lookup_command?(i) && object.respond_to?(key)
60
63
  object = object.send(key).to_liquid
61
64
 
62
65
  # No key was present with the desired value and it wasn't one of the directly supported
@@ -2,5 +2,5 @@
2
2
  # frozen_string_literal: true
3
3
 
4
4
  module Liquid
5
- VERSION = "5.3.0"
5
+ VERSION = "5.4.0"
6
6
  end
data/lib/liquid.rb CHANGED
@@ -29,6 +29,7 @@ module Liquid
29
29
  WhitespaceControl = '-'
30
30
  TagStart = /\{\%/
31
31
  TagEnd = /\%\}/
32
+ TagName = /#|\w+/
32
33
  VariableSignature = /\(?[\w\-\.\[\]]\)?/
33
34
  VariableSegment = /[\w\-]/
34
35
  VariableStart = /\{\{/
@@ -83,8 +84,7 @@ require 'liquid/tokenizer'
83
84
  require 'liquid/parse_context'
84
85
  require 'liquid/partial_cache'
85
86
  require 'liquid/usage'
86
- require 'liquid/register'
87
- require 'liquid/static_registers'
87
+ require 'liquid/registers'
88
88
  require 'liquid/template_factory'
89
89
 
90
90
  # Load all the tags of the standard library
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.3.0
4
+ version: 5.4.0
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: 2022-03-22 00:00:00.000000000 Z
11
+ date: 2022-07-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -74,10 +74,9 @@ files:
74
74
  - lib/liquid/profiler.rb
75
75
  - lib/liquid/profiler/hooks.rb
76
76
  - lib/liquid/range_lookup.rb
77
- - lib/liquid/register.rb
77
+ - lib/liquid/registers.rb
78
78
  - lib/liquid/resource_limits.rb
79
79
  - lib/liquid/standardfilters.rb
80
- - lib/liquid/static_registers.rb
81
80
  - lib/liquid/strainer_factory.rb
82
81
  - lib/liquid/strainer_template.rb
83
82
  - lib/liquid/tablerowloop_drop.rb
@@ -98,6 +97,7 @@ files:
98
97
  - lib/liquid/tags/ifchanged.rb
99
98
  - lib/liquid/tags/include.rb
100
99
  - lib/liquid/tags/increment.rb
100
+ - lib/liquid/tags/inline_comment.rb
101
101
  - lib/liquid/tags/raw.rb
102
102
  - lib/liquid/tags/render.rb
103
103
  - lib/liquid/tags/table_row.rb
@@ -110,64 +110,6 @@ files:
110
110
  - lib/liquid/variable.rb
111
111
  - lib/liquid/variable_lookup.rb
112
112
  - lib/liquid/version.rb
113
- - test/fixtures/en_locale.yml
114
- - test/integration/assign_test.rb
115
- - test/integration/blank_test.rb
116
- - test/integration/block_test.rb
117
- - test/integration/capture_test.rb
118
- - test/integration/context_test.rb
119
- - test/integration/document_test.rb
120
- - test/integration/drop_test.rb
121
- - test/integration/error_handling_test.rb
122
- - test/integration/expression_test.rb
123
- - test/integration/filter_kwarg_test.rb
124
- - test/integration/filter_test.rb
125
- - test/integration/hash_ordering_test.rb
126
- - test/integration/output_test.rb
127
- - test/integration/parsing_quirks_test.rb
128
- - test/integration/profiler_test.rb
129
- - test/integration/security_test.rb
130
- - test/integration/standard_filter_test.rb
131
- - test/integration/tag/disableable_test.rb
132
- - test/integration/tag_test.rb
133
- - test/integration/tags/break_tag_test.rb
134
- - test/integration/tags/continue_tag_test.rb
135
- - test/integration/tags/echo_test.rb
136
- - test/integration/tags/for_tag_test.rb
137
- - test/integration/tags/if_else_tag_test.rb
138
- - test/integration/tags/include_tag_test.rb
139
- - test/integration/tags/increment_tag_test.rb
140
- - test/integration/tags/liquid_tag_test.rb
141
- - test/integration/tags/raw_tag_test.rb
142
- - test/integration/tags/render_tag_test.rb
143
- - test/integration/tags/standard_tag_test.rb
144
- - test/integration/tags/statements_test.rb
145
- - test/integration/tags/table_row_test.rb
146
- - test/integration/tags/unless_else_tag_test.rb
147
- - test/integration/template_test.rb
148
- - test/integration/trim_mode_test.rb
149
- - test/integration/variable_test.rb
150
- - test/test_helper.rb
151
- - test/unit/block_unit_test.rb
152
- - test/unit/condition_unit_test.rb
153
- - test/unit/file_system_unit_test.rb
154
- - test/unit/i18n_unit_test.rb
155
- - test/unit/lexer_unit_test.rb
156
- - test/unit/parse_tree_visitor_test.rb
157
- - test/unit/parser_unit_test.rb
158
- - test/unit/partial_cache_unit_test.rb
159
- - test/unit/regexp_unit_test.rb
160
- - test/unit/static_registers_unit_test.rb
161
- - test/unit/strainer_factory_unit_test.rb
162
- - test/unit/strainer_template_unit_test.rb
163
- - test/unit/tag_unit_test.rb
164
- - test/unit/tags/case_tag_unit_test.rb
165
- - test/unit/tags/for_tag_unit_test.rb
166
- - test/unit/tags/if_tag_unit_test.rb
167
- - test/unit/template_factory_unit_test.rb
168
- - test/unit/template_unit_test.rb
169
- - test/unit/tokenizer_unit_test.rb
170
- - test/unit/variable_unit_test.rb
171
113
  homepage: http://www.liquidmarkup.org
172
114
  licenses:
173
115
  - MIT
@@ -181,73 +123,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
181
123
  requirements:
182
124
  - - ">="
183
125
  - !ruby/object:Gem::Version
184
- version: 2.5.0
126
+ version: 2.7.0
185
127
  required_rubygems_version: !ruby/object:Gem::Requirement
186
128
  requirements:
187
129
  - - ">="
188
130
  - !ruby/object:Gem::Version
189
131
  version: 1.3.7
190
132
  requirements: []
191
- rubygems_version: 3.2.20
133
+ rubygems_version: 3.3.3
192
134
  signing_key:
193
135
  specification_version: 4
194
136
  summary: A secure, non-evaling end user template engine with aesthetic markup.
195
- test_files:
196
- - test/unit/parser_unit_test.rb
197
- - test/unit/static_registers_unit_test.rb
198
- - test/unit/tag_unit_test.rb
199
- - test/unit/strainer_factory_unit_test.rb
200
- - test/unit/partial_cache_unit_test.rb
201
- - test/unit/strainer_template_unit_test.rb
202
- - test/unit/lexer_unit_test.rb
203
- - test/unit/parse_tree_visitor_test.rb
204
- - test/unit/i18n_unit_test.rb
205
- - test/unit/tokenizer_unit_test.rb
206
- - test/unit/template_factory_unit_test.rb
207
- - test/unit/condition_unit_test.rb
208
- - test/unit/block_unit_test.rb
209
- - test/unit/file_system_unit_test.rb
210
- - test/unit/variable_unit_test.rb
211
- - test/unit/template_unit_test.rb
212
- - test/unit/tags/if_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/regexp_unit_test.rb
216
- - test/test_helper.rb
217
- - test/integration/document_test.rb
218
- - test/integration/tag_test.rb
219
- - test/integration/filter_kwarg_test.rb
220
- - test/integration/trim_mode_test.rb
221
- - test/integration/profiler_test.rb
222
- - test/integration/security_test.rb
223
- - test/integration/capture_test.rb
224
- - test/integration/parsing_quirks_test.rb
225
- - test/integration/blank_test.rb
226
- - test/integration/template_test.rb
227
- - test/integration/tag/disableable_test.rb
228
- - test/integration/variable_test.rb
229
- - test/integration/output_test.rb
230
- - test/integration/drop_test.rb
231
- - test/integration/standard_filter_test.rb
232
- - test/integration/expression_test.rb
233
- - test/integration/block_test.rb
234
- - test/integration/hash_ordering_test.rb
235
- - test/integration/filter_test.rb
236
- - test/integration/tags/break_tag_test.rb
237
- - test/integration/tags/standard_tag_test.rb
238
- - test/integration/tags/liquid_tag_test.rb
239
- - test/integration/tags/table_row_test.rb
240
- - test/integration/tags/render_tag_test.rb
241
- - test/integration/tags/include_tag_test.rb
242
- - test/integration/tags/increment_tag_test.rb
243
- - test/integration/tags/if_else_tag_test.rb
244
- - test/integration/tags/continue_tag_test.rb
245
- - test/integration/tags/echo_test.rb
246
- - test/integration/tags/raw_tag_test.rb
247
- - test/integration/tags/for_tag_test.rb
248
- - test/integration/tags/statements_test.rb
249
- - test/integration/tags/unless_else_tag_test.rb
250
- - test/integration/context_test.rb
251
- - test/integration/error_handling_test.rb
252
- - test/integration/assign_test.rb
253
- - test/fixtures/en_locale.yml
137
+ test_files: []
@@ -1,6 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Liquid
4
- class Register
5
- end
6
- end
@@ -1,9 +0,0 @@
1
- ---
2
- simple: "less is more"
3
- whatever: "something %{something}"
4
- errors:
5
- i18n:
6
- undefined_interpolation: "undefined key %{key}"
7
- unknown_translation: "translation '%{name}' wasn't found"
8
- syntax:
9
- oops: "something wasn't right"
@@ -1,117 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'test_helper'
4
-
5
- class AssignTest < Minitest::Test
6
- include Liquid
7
-
8
- def test_assign_with_hyphen_in_variable_name
9
- template_source = <<-END_TEMPLATE
10
- {% assign this-thing = 'Print this-thing' %}
11
- {{ this-thing }}
12
- END_TEMPLATE
13
- template = Template.parse(template_source)
14
- rendered = template.render!
15
- assert_equal("Print this-thing", rendered.strip)
16
- end
17
-
18
- def test_assigned_variable
19
- assert_template_result('.foo.',
20
- '{% assign foo = values %}.{{ foo[0] }}.',
21
- 'values' => %w(foo bar baz))
22
-
23
- assert_template_result('.bar.',
24
- '{% assign foo = values %}.{{ foo[1] }}.',
25
- 'values' => %w(foo bar baz))
26
- end
27
-
28
- def test_assign_with_filter
29
- assert_template_result('.bar.',
30
- '{% assign foo = values | split: "," %}.{{ foo[1] }}.',
31
- 'values' => "foo,bar,baz")
32
- end
33
-
34
- def test_assign_syntax_error
35
- assert_match_syntax_error(/assign/,
36
- '{% assign foo not values %}.',
37
- 'values' => "foo,bar,baz")
38
- end
39
-
40
- def test_assign_uses_error_mode
41
- with_error_mode(:strict) do
42
- assert_raises(SyntaxError) do
43
- Template.parse("{% assign foo = ('X' | downcase) %}")
44
- end
45
- end
46
- with_error_mode(:lax) do
47
- assert(Template.parse("{% assign foo = ('X' | downcase) %}"))
48
- end
49
- end
50
-
51
- def test_expression_with_whitespace_in_square_brackets
52
- source = "{% assign r = a[ 'b' ] %}{{ r }}"
53
- assert_template_result('result', source, 'a' => { 'b' => 'result' })
54
- end
55
-
56
- def test_assign_score_exceeding_resource_limit
57
- t = Template.parse("{% assign foo = 42 %}{% assign bar = 23 %}")
58
- t.resource_limits.assign_score_limit = 1
59
- assert_equal("Liquid error: Memory limits exceeded", t.render)
60
- assert(t.resource_limits.reached?)
61
-
62
- t.resource_limits.assign_score_limit = 2
63
- assert_equal("", t.render!)
64
- refute_nil(t.resource_limits.assign_score)
65
- end
66
-
67
- def test_assign_score_exceeding_limit_from_composite_object
68
- t = Template.parse("{% assign foo = 'aaaa' | reverse %}")
69
-
70
- t.resource_limits.assign_score_limit = 3
71
- assert_equal("Liquid error: Memory limits exceeded", t.render)
72
- assert(t.resource_limits.reached?)
73
-
74
- t.resource_limits.assign_score_limit = 5
75
- assert_equal("", t.render!)
76
- end
77
-
78
- def test_assign_score_of_int
79
- assert_equal(1, assign_score_of(123))
80
- end
81
-
82
- def test_assign_score_of_string_counts_bytes
83
- assert_equal(3, assign_score_of('123'))
84
- assert_equal(5, assign_score_of('12345'))
85
- assert_equal(9, assign_score_of('すごい'))
86
- end
87
-
88
- def test_assign_score_of_array
89
- assert_equal(1, assign_score_of([]))
90
- assert_equal(2, assign_score_of([123]))
91
- assert_equal(6, assign_score_of([123, 'abcd']))
92
- end
93
-
94
- def test_assign_score_of_hash
95
- assert_equal(1, assign_score_of({}))
96
- assert_equal(5, assign_score_of('int' => 123))
97
- assert_equal(12, assign_score_of('int' => 123, 'str' => 'abcd'))
98
- end
99
-
100
- private
101
-
102
- class ObjectWrapperDrop < Liquid::Drop
103
- def initialize(obj)
104
- @obj = obj
105
- end
106
-
107
- def value
108
- @obj
109
- end
110
- end
111
-
112
- def assign_score_of(obj)
113
- context = Liquid::Context.new('drop' => ObjectWrapperDrop.new(obj))
114
- Liquid::Template.parse('{% assign obj = drop.value %}').render!(context)
115
- context.resource_limits.assign_score
116
- end
117
- end
@@ -1,109 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'test_helper'
4
-
5
- class FoobarTag < Liquid::Tag
6
- def render_to_output_buffer(_context, output)
7
- output << ' '
8
- output
9
- end
10
- end
11
-
12
- class BlankTestFileSystem
13
- def read_template_file(template_path)
14
- template_path
15
- end
16
- end
17
-
18
- class BlankTest < Minitest::Test
19
- include Liquid
20
- N = 10
21
-
22
- def wrap_in_for(body)
23
- "{% for i in (1..#{N}) %}#{body}{% endfor %}"
24
- end
25
-
26
- def wrap_in_if(body)
27
- "{% if true %}#{body}{% endif %}"
28
- end
29
-
30
- def wrap(body)
31
- wrap_in_for(body) + wrap_in_if(body)
32
- end
33
-
34
- def test_new_tags_are_not_blank_by_default
35
- with_custom_tag('foobar', FoobarTag) do
36
- assert_template_result(" " * N, wrap_in_for("{% foobar %}"))
37
- end
38
- end
39
-
40
- def test_loops_are_blank
41
- assert_template_result("", wrap_in_for(" "))
42
- end
43
-
44
- def test_if_else_are_blank
45
- assert_template_result("", "{% if true %} {% elsif false %} {% else %} {% endif %}")
46
- end
47
-
48
- def test_unless_is_blank
49
- assert_template_result("", wrap("{% unless true %} {% endunless %}"))
50
- end
51
-
52
- def test_mark_as_blank_only_during_parsing
53
- assert_template_result(" " * (N + 1), wrap(" {% if false %} this never happens, but still, this block is not blank {% endif %}"))
54
- end
55
-
56
- def test_comments_are_blank
57
- assert_template_result("", wrap(" {% comment %} whatever {% endcomment %} "))
58
- end
59
-
60
- def test_captures_are_blank
61
- assert_template_result("", wrap(" {% capture foo %} whatever {% endcapture %} "))
62
- end
63
-
64
- def test_nested_blocks_are_blank_but_only_if_all_children_are
65
- assert_template_result("", wrap(wrap(" ")))
66
- assert_template_result("\n but this is not " * (N + 1),
67
- wrap('{% if true %} {% comment %} this is blank {% endcomment %} {% endif %}
68
- {% if true %} but this is not {% endif %}'))
69
- end
70
-
71
- def test_assigns_are_blank
72
- assert_template_result("", wrap(' {% assign foo = "bar" %} '))
73
- end
74
-
75
- def test_whitespace_is_blank
76
- assert_template_result("", wrap(" "))
77
- assert_template_result("", wrap("\t"))
78
- end
79
-
80
- def test_whitespace_is_not_blank_if_other_stuff_is_present
81
- body = " x "
82
- assert_template_result(body * (N + 1), wrap(body))
83
- end
84
-
85
- def test_increment_is_not_blank
86
- assert_template_result(" 0" * 2 * (N + 1), wrap("{% assign foo = 0 %} {% increment foo %} {% decrement foo %}"))
87
- end
88
-
89
- def test_cycle_is_not_blank
90
- assert_template_result(" " * ((N + 1) / 2) + " ", wrap("{% cycle ' ', ' ' %}"))
91
- end
92
-
93
- def test_raw_is_not_blank
94
- assert_template_result(" " * (N + 1), wrap(" {% raw %} {% endraw %}"))
95
- end
96
-
97
- def test_include_is_blank
98
- Liquid::Template.file_system = BlankTestFileSystem.new
99
- assert_template_result("foobar" * (N + 1), wrap("{% include 'foobar' %}"))
100
- assert_template_result(" foobar " * (N + 1), wrap("{% include ' foobar ' %}"))
101
- assert_template_result(" " * (N + 1), wrap(" {% include ' ' %} "))
102
- end
103
-
104
- def test_case_is_blank
105
- assert_template_result("", wrap(" {% assign foo = 'bar' %} {% case foo %} {% when 'bar' %} {% when 'whatever' %} {% else %} {% endcase %} "))
106
- assert_template_result("", wrap(" {% assign foo = 'else' %} {% case foo %} {% when 'bar' %} {% when 'whatever' %} {% else %} {% endcase %} "))
107
- assert_template_result(" x " * (N + 1), wrap(" {% assign foo = 'else' %} {% case foo %} {% when 'bar' %} {% when 'whatever' %} {% else %} x {% endcase %} "))
108
- end
109
- end