From 2324564743f005a3366ab3cecc3e5c2532433f81 Mon Sep 17 00:00:00 2001 From: Mike Angell Date: Thu, 29 Aug 2019 08:50:36 +1000 Subject: [PATCH 01/21] Remove lazy load stacks Remove lazy load stacks and instead only create a new scope when a tag is known to need one --- lib/liquid/context.rb | 35 ++++++++++++++++++----------------- lib/liquid/tags/case.rb | 16 +++++++--------- lib/liquid/tags/cycle.rb | 28 +++++++++++++--------------- lib/liquid/tags/if.rb | 8 +++----- lib/liquid/tags/ifchanged.rb | 12 +++++------- lib/liquid/tags/unless.rb | 20 +++++++++----------- 6 files changed, 55 insertions(+), 64 deletions(-) diff --git a/lib/liquid/context.rb b/lib/liquid/context.rb index 2dcc6af8..b341a31b 100644 --- a/lib/liquid/context.rb +++ b/lib/liquid/context.rb @@ -25,8 +25,6 @@ module Liquid @resource_limits = resource_limits || ResourceLimits.new(Template.default_resource_limits) squash_instance_assigns_with_environments - @this_stack_used = false - self.exception_renderer = Template.default_exception_renderer if rethrow_errors self.exception_renderer = ->(e) { raise } @@ -111,19 +109,26 @@ module Liquid # end # # context['var] #=> nil - def stack(new_scope = nil) - old_stack_used = @this_stack_used - if new_scope - push(new_scope) - @this_stack_used = true - else - @this_stack_used = false - end - + # + # false or {} can be used to control if a new scope is needed + # + # Example: + # new_scope = false + # context.stack(new_scope) do + # # no scope created + # end + # + # Example: + # new_scope = {} + # context.stack(new_scope) do + # # scope created + # end + # + def stack(new_scope = {}) + push(new_scope) unless new_scope == false yield ensure - pop if @this_stack_used - @this_stack_used = old_stack_used + pop unless new_scope == false end def clear_instance_assigns @@ -132,10 +137,6 @@ module Liquid # Only allow String, Numeric, Hash, Array, Proc, Boolean or Liquid::Drop def []=(key, value) - unless @this_stack_used - @this_stack_used = true - push({}) - end @scopes[0][key] = value end diff --git a/lib/liquid/tags/case.rb b/lib/liquid/tags/case.rb index 92b2ed0d..e167b9df 100644 --- a/lib/liquid/tags/case.rb +++ b/lib/liquid/tags/case.rb @@ -39,16 +39,14 @@ module Liquid end def render_to_output_buffer(context, output) - context.stack do - execute_else_block = true + execute_else_block = true - @blocks.each do |block| - if block.else? - block.attachment.render_to_output_buffer(context, output) if execute_else_block - elsif block.evaluate(context) - execute_else_block = false - block.attachment.render_to_output_buffer(context, output) - end + @blocks.each do |block| + if block.else? + block.attachment.render_to_output_buffer(context, output) if execute_else_block + elsif block.evaluate(context) + execute_else_block = false + block.attachment.render_to_output_buffer(context, output) end end diff --git a/lib/liquid/tags/cycle.rb b/lib/liquid/tags/cycle.rb index e42244d4..8c11d37b 100644 --- a/lib/liquid/tags/cycle.rb +++ b/lib/liquid/tags/cycle.rb @@ -34,25 +34,23 @@ module Liquid def render_to_output_buffer(context, output) context.registers[:cycle] ||= {} - context.stack do - key = context.evaluate(@name) - iteration = context.registers[:cycle][key].to_i + key = context.evaluate(@name) + iteration = context.registers[:cycle][key].to_i - val = context.evaluate(@variables[iteration]) + val = context.evaluate(@variables[iteration]) - if val.is_a?(Array) - val = val.join - elsif !val.is_a?(String) - val = val.to_s - end - - output << val - - iteration += 1 - iteration = 0 if iteration >= @variables.size - context.registers[:cycle][key] = iteration + if val.is_a?(Array) + val = val.join + elsif !val.is_a?(String) + val = val.to_s end + output << val + + iteration += 1 + iteration = 0 if iteration >= @variables.size + context.registers[:cycle][key] = iteration + output end diff --git a/lib/liquid/tags/if.rb b/lib/liquid/tags/if.rb index 25534a98..709cf7f8 100644 --- a/lib/liquid/tags/if.rb +++ b/lib/liquid/tags/if.rb @@ -40,11 +40,9 @@ module Liquid end def render_to_output_buffer(context, output) - context.stack do - @blocks.each do |block| - if block.evaluate(context) - return block.attachment.render_to_output_buffer(context, output) - end + @blocks.each do |block| + if block.evaluate(context) + return block.attachment.render_to_output_buffer(context, output) end end diff --git a/lib/liquid/tags/ifchanged.rb b/lib/liquid/tags/ifchanged.rb index e3040cec..ddd276cf 100644 --- a/lib/liquid/tags/ifchanged.rb +++ b/lib/liquid/tags/ifchanged.rb @@ -1,14 +1,12 @@ module Liquid class Ifchanged < Block def render_to_output_buffer(context, output) - context.stack do - block_output = '' - super(context, block_output) + block_output = '' + super(context, block_output) - if block_output != context.registers[:ifchanged] - context.registers[:ifchanged] = block_output - output << block_output - end + if block_output != context.registers[:ifchanged] + context.registers[:ifchanged] = block_output + output << block_output end output diff --git a/lib/liquid/tags/unless.rb b/lib/liquid/tags/unless.rb index 18856c3b..32aa3a41 100644 --- a/lib/liquid/tags/unless.rb +++ b/lib/liquid/tags/unless.rb @@ -7,18 +7,16 @@ module Liquid # class Unless < If def render_to_output_buffer(context, output) - context.stack do - # First condition is interpreted backwards ( if not ) - first_block = @blocks.first - unless first_block.evaluate(context) - return first_block.attachment.render_to_output_buffer(context, output) - end + # First condition is interpreted backwards ( if not ) + first_block = @blocks.first + unless first_block.evaluate(context) + return first_block.attachment.render_to_output_buffer(context, output) + end - # After the first condition unless works just like if - @blocks[1..-1].each do |block| - if block.evaluate(context) - return block.attachment.render_to_output_buffer(context, output) - end + # After the first condition unless works just like if + @blocks[1..-1].each do |block| + if block.evaluate(context) + return block.attachment.render_to_output_buffer(context, output) end end From dafbb4ae904b93de93bd80a555bcf4fcc2a31f4f Mon Sep 17 00:00:00 2001 From: Mike Angell Date: Sat, 31 Aug 2019 20:03:54 +1000 Subject: [PATCH 02/21] Remove hasnling false scopes --- lib/liquid/context.rb | 19 ++----------------- 1 file changed, 2 insertions(+), 17 deletions(-) diff --git a/lib/liquid/context.rb b/lib/liquid/context.rb index b341a31b..bf12dc17 100644 --- a/lib/liquid/context.rb +++ b/lib/liquid/context.rb @@ -109,26 +109,11 @@ module Liquid # end # # context['var] #=> nil - # - # false or {} can be used to control if a new scope is needed - # - # Example: - # new_scope = false - # context.stack(new_scope) do - # # no scope created - # end - # - # Example: - # new_scope = {} - # context.stack(new_scope) do - # # scope created - # end - # def stack(new_scope = {}) - push(new_scope) unless new_scope == false + push(new_scope) yield ensure - pop unless new_scope == false + pop end def clear_instance_assigns From 799da202dfab5cf1066ce45471d1dad46287b9f8 Mon Sep 17 00:00:00 2001 From: Mike Angell Date: Sat, 31 Aug 2019 21:58:33 +1000 Subject: [PATCH 03/21] Apply simple rubocop fixes --- .rubocop_todo.yml | 347 +------------------- Rakefile | 14 +- example/server/example_servlet.rb | 2 +- example/server/liquid_servlet.rb | 4 +- example/server/server.rb | 2 +- lib/liquid/block.rb | 12 +- lib/liquid/block_body.rb | 18 +- lib/liquid/condition.rb | 14 +- lib/liquid/context.rb | 4 +- lib/liquid/document.rb | 6 +- lib/liquid/drop.rb | 2 +- lib/liquid/errors.rb | 6 +- lib/liquid/expression.rb | 10 +- lib/liquid/file_system.rb | 2 +- lib/liquid/i18n.rb | 4 +- lib/liquid/interrupts.rb | 4 +- lib/liquid/lexer.rb | 15 +- lib/liquid/parse_context.rb | 2 +- lib/liquid/parse_tree_visitor.rb | 2 +- lib/liquid/parser.rb | 2 +- lib/liquid/standardfilters.rb | 10 +- lib/liquid/strainer.rb | 4 +- lib/liquid/tags/assign.rb | 6 +- lib/liquid/tags/capture.rb | 4 +- lib/liquid/tags/case.rb | 16 +- lib/liquid/tags/cycle.rb | 8 +- lib/liquid/tags/for.rb | 21 +- lib/liquid/tags/if.rb | 10 +- lib/liquid/tags/include.rb | 10 +- lib/liquid/tags/raw.rb | 8 +- lib/liquid/tags/render.rb | 6 +- lib/liquid/tags/table_row.rb | 8 +- lib/liquid/template.rb | 2 +- lib/liquid/tokenizer.rb | 4 +- lib/liquid/utils.rb | 2 +- lib/liquid/variable.rb | 8 +- lib/liquid/variable_lookup.rb | 4 +- liquid.gemspec | 6 +- performance/shopify/comment_form.rb | 8 +- performance/shopify/database.rb | 13 +- performance/shopify/json_filter.rb | 2 +- performance/shopify/liquid.rb | 16 +- performance/shopify/money_filter.rb | 4 +- performance/shopify/paginate.rb | 22 +- performance/shopify/shop_filter.rb | 16 +- performance/shopify/tag_filter.rb | 4 +- performance/shopify/weight_filter.rb | 2 +- performance/theme_runner.rb | 2 +- test/integration/blank_test.rb | 2 +- test/integration/drop_test.rb | 10 +- test/integration/error_handling_test.rb | 29 +- test/integration/filter_test.rb | 12 +- test/integration/hash_ordering_test.rb | 4 +- test/integration/output_test.rb | 4 +- test/integration/parse_tree_visitor_test.rb | 2 +- test/integration/render_profiling_test.rb | 4 +- test/integration/standard_filter_test.rb | 50 +-- test/integration/tags/echo_test.rb | 2 +- test/integration/tags/for_tag_test.rb | 12 +- test/integration/tags/if_else_tag_test.rb | 2 +- test/integration/tags/include_tag_test.rb | 14 +- test/integration/tags/increment_tag_test.rb | 4 +- test/integration/tags/render_tag_test.rb | 2 +- test/integration/tags/standard_tag_test.rb | 42 +-- test/integration/template_test.rb | 18 +- test/integration/trim_mode_test.rb | 60 ++-- test/integration/variable_test.rb | 2 +- test/test_helper.rb | 2 +- test/unit/condition_unit_test.rb | 14 +- test/unit/context_unit_test.rb | 20 +- test/unit/partial_cache_unit_test.rb | 6 +- test/unit/strainer_unit_test.rb | 7 +- test/unit/tags/if_tag_unit_test.rb | 2 +- 73 files changed, 341 insertions(+), 683 deletions(-) diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 22330ae6..0bd77b10 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -1,92 +1,17 @@ # This configuration was generated by # `rubocop --auto-gen-config` -# on 2019-08-29 12:16:25 +1000 using RuboCop version 0.74.0. +# on 2019-08-31 21:54:20 +1000 using RuboCop version 0.74.0. # The point is for the user to remove these configuration records # one by one as the offenses are removed from the code base. # Note that changes in the inspected code, or installation of new # versions of RuboCop, may require this file to be generated again. -# Offense count: 13 -# Cop supports --auto-correct. -# Configuration parameters: AllowMultipleStyles, EnforcedHashRocketStyle, EnforcedColonStyle, EnforcedLastArgumentHashStyle. -# SupportedHashRocketStyles: key, separator, table -# SupportedColonStyles: key, separator, table -# SupportedLastArgumentHashStyles: always_inspect, always_ignore, ignore_implicit, ignore_explicit -Layout/AlignHash: - Exclude: - - 'lib/liquid/condition.rb' - - 'lib/liquid/expression.rb' - - 'performance/shopify/comment_form.rb' - - 'performance/shopify/database.rb' - - 'performance/shopify/paginate.rb' - - 'test/unit/context_unit_test.rb' - -# Offense count: 3 -# Cop supports --auto-correct. -# Configuration parameters: AllowForAlignment, AllowBeforeTrailingComments, ForceEqualSignAlignment. -Layout/ExtraSpacing: - Exclude: - - 'performance/shopify/paginate.rb' - -# Offense count: 5 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle. -# SupportedStyles: squiggly, active_support, powerpack, unindent -Layout/IndentHeredoc: - Exclude: - - 'test/integration/tags/for_tag_test.rb' - - 'test/integration/trim_mode_test.rb' - -# Offense count: 6 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle. -# SupportedStyles: symmetrical, new_line, same_line -Layout/MultilineMethodCallBraceLayout: - Exclude: - - 'test/integration/error_handling_test.rb' - - 'test/unit/strainer_unit_test.rb' - -# Offense count: 4 -# Cop supports --auto-correct. -# Configuration parameters: AllowForAlignment. -Layout/SpaceAroundOperators: - Exclude: - - 'lib/liquid/condition.rb' - - 'performance/shopify/paginate.rb' - -# Offense count: 9 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle, EnforcedStyleForEmptyBraces. -# SupportedStyles: space, no_space -# SupportedStylesForEmptyBraces: space, no_space -Layout/SpaceBeforeBlockBraces: - Exclude: - - 'example/server/server.rb' - - 'lib/liquid/variable.rb' - - 'test/integration/drop_test.rb' - - 'test/integration/standard_filter_test.rb' - - 'test/integration/tags/if_else_tag_test.rb' - -# Offense count: 19 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle, EnforcedStyleForEmptyBrackets. -# SupportedStyles: space, no_space, compact -# SupportedStylesForEmptyBrackets: space, no_space -Layout/SpaceInsideArrayLiteralBrackets: - Exclude: - - 'test/integration/drop_test.rb' - - 'test/integration/standard_filter_test.rb' - - 'test/integration/tags/for_tag_test.rb' - - 'test/integration/tags/include_tag_test.rb' - - 'test/integration/tags/standard_tag_test.rb' - - 'test/unit/context_unit_test.rb' - # Offense count: 2 Lint/AmbiguousOperator: Exclude: - 'test/unit/condition_unit_test.rb' -# Offense count: 16 +# Offense count: 21 # Configuration parameters: AllowSafeAssignment. Lint/AssignmentInCondition: Exclude: @@ -95,51 +20,12 @@ Lint/AssignmentInCondition: - 'lib/liquid/standardfilters.rb' - 'lib/liquid/tags/for.rb' - 'lib/liquid/tags/if.rb' - - 'lib/liquid/tags/include.rb' - 'lib/liquid/tags/raw.rb' - 'lib/liquid/variable.rb' - 'performance/profile.rb' - 'test/test_helper.rb' - 'test/unit/tokenizer_unit_test.rb' -# Offense count: 2 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle. -# SupportedStyles: runtime_error, standard_error -Lint/InheritException: - Exclude: - - 'lib/liquid/interrupts.rb' - -# Offense count: 10 -# Cop supports --auto-correct. -# Configuration parameters: IgnoreEmptyBlocks, AllowUnusedKeywordArguments. -Lint/UnusedBlockArgument: - Exclude: - - 'lib/liquid/condition.rb' - - 'lib/liquid/context.rb' - - 'lib/liquid/document.rb' - - 'lib/liquid/parse_context.rb' - - 'lib/liquid/template.rb' - - 'performance/shopify/json_filter.rb' - - 'test/integration/filter_test.rb' - - 'test/integration/render_profiling_test.rb' - - 'test/integration/variable_test.rb' - - 'test/unit/condition_unit_test.rb' - -# Offense count: 12 -# Cop supports --auto-correct. -# Configuration parameters: AllowUnusedKeywordArguments, IgnoreEmptyMethods. -Lint/UnusedMethodArgument: - Exclude: - - 'example/server/liquid_servlet.rb' - - 'test/integration/blank_test.rb' - - 'test/integration/error_handling_test.rb' - - 'test/integration/filter_test.rb' - - 'test/integration/output_test.rb' - - 'test/integration/standard_filter_test.rb' - - 'test/integration/tags/include_tag_test.rb' - - 'test/unit/strainer_unit_test.rb' - # Offense count: 2 Lint/UselessAssignment: Exclude: @@ -151,64 +37,16 @@ Lint/Void: Exclude: - 'lib/liquid/parse_context.rb' -# Offense count: 95 +# Offense count: 98 # Cop supports --auto-correct. # Configuration parameters: AutoCorrect, AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, IgnoredPatterns. # URISchemes: http, https Metrics/LineLength: Max: 294 -# Offense count: 44 +# Offense count: 45 Naming/ConstantName: - Exclude: - - 'lib/liquid.rb' - - 'lib/liquid/block_body.rb' - - 'lib/liquid/tags/assign.rb' - - 'lib/liquid/tags/capture.rb' - - 'lib/liquid/tags/case.rb' - - 'lib/liquid/tags/cycle.rb' - - 'lib/liquid/tags/for.rb' - - 'lib/liquid/tags/if.rb' - - 'lib/liquid/tags/include.rb' - - 'lib/liquid/tags/raw.rb' - - 'lib/liquid/tags/table_row.rb' - - 'lib/liquid/variable.rb' - - 'performance/shopify/comment_form.rb' - - 'performance/shopify/paginate.rb' - - 'test/integration/tags/include_tag_test.rb' - -# Offense count: 2 -# Configuration parameters: . -# SupportedStyles: snake_case, camelCase -Naming/MethodName: - EnforcedStyle: snake_case - -# Offense count: 3 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle. -# SupportedStyles: always, conditionals -Style/AndOr: - Exclude: - - 'lib/liquid/i18n.rb' - - 'lib/liquid/tags/table_row.rb' - - 'lib/liquid/tokenizer.rb' - -# Offense count: 40 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle. -# SupportedStyles: braces, no_braces, context_dependent -Style/BracesAroundHashParameters: - Exclude: - - 'test/integration/error_handling_test.rb' - - 'test/integration/filter_test.rb' - - 'test/integration/render_profiling_test.rb' - - 'test/integration/standard_filter_test.rb' - - 'test/integration/tags/echo_test.rb' - - 'test/integration/tags/increment_tag_test.rb' - - 'test/integration/tags/standard_tag_test.rb' - - 'test/integration/template_test.rb' - - 'test/unit/condition_unit_test.rb' - - 'test/unit/context_unit_test.rb' + Enabled: false # Offense count: 5 Style/ClassVars: @@ -217,195 +55,24 @@ Style/ClassVars: - 'lib/liquid/strainer.rb' - 'lib/liquid/template.rb' -# Offense count: 2 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle, SingleLineConditionsOnly, IncludeTernaryExpressions. -# SupportedStyles: assign_to_condition, assign_inside_condition -Style/ConditionalAssignment: - Exclude: - - 'lib/liquid/errors.rb' - - 'performance/shopify/shop_filter.rb' - # Offense count: 1 # Configuration parameters: AllowCoercion. Style/DateTime: Exclude: - 'test/unit/context_unit_test.rb' -# Offense count: 2 -# Cop supports --auto-correct. -Style/EachWithObject: - Exclude: - - 'performance/shopify/database.rb' - -# Offense count: 1 -# Cop supports --auto-correct. -Style/EmptyCaseCondition: - Exclude: - - 'lib/liquid/lexer.rb' - -# Offense count: 1 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle. -# SupportedStyles: each, for -Style/For: - Exclude: - - 'performance/shopify/shop_filter.rb' - -# Offense count: 9 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle. -# SupportedStyles: format, sprintf, percent -Style/FormatString: - Exclude: - - 'example/server/example_servlet.rb' - - 'performance/shopify/money_filter.rb' - - 'performance/shopify/weight_filter.rb' - - 'test/integration/filter_test.rb' - - 'test/integration/hash_ordering_test.rb' - -# Offense count: 115 +# Offense count: 119 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle. # SupportedStyles: always, never Style/FrozenStringLiteralComment: Enabled: false -# Offense count: 30 -# Cop supports --auto-correct. -# Configuration parameters: IgnoreMacros, IgnoredMethods, IncludedMacros, AllowParenthesesInMultilineCall, AllowParenthesesInChaining, AllowParenthesesInCamelCaseMethod, EnforcedStyle. -# SupportedStyles: require_parentheses, omit_parentheses -Style/MethodCallWithArgsParentheses: - Exclude: - - 'Gemfile' - - 'Rakefile' - - 'lib/liquid/block_body.rb' - - 'lib/liquid/parser.rb' - - 'lib/liquid/tags/for.rb' - - 'liquid.gemspec' - - 'performance/shopify/database.rb' - - 'performance/shopify/liquid.rb' - - 'test/test_helper.rb' - - 'test/unit/condition_unit_test.rb' - - 'test/unit/tags/if_tag_unit_test.rb' - -# Offense count: 1 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle, MinBodyLength. -# SupportedStyles: skip_modifier_ifs, always -Style/Next: - Exclude: - - 'lib/liquid/tags/for.rb' - -# Offense count: 52 -# Cop supports --auto-correct. -Style/PerlBackrefs: - Enabled: false - -# Offense count: 33 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle. -# SupportedStyles: compact, exploded -Style/RaiseArgs: - Enabled: false - -# Offense count: 1 -# Cop supports --auto-correct. -Style/RedundantSelf: - Exclude: - - 'lib/liquid/strainer.rb' - -# Offense count: 5 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle, AllowInnerSlashes. -# SupportedStyles: slashes, percent_r, mixed -Style/RegexpLiteral: - Exclude: - - 'lib/liquid/file_system.rb' - - 'lib/liquid/standardfilters.rb' - - 'performance/shopify/shop_filter.rb' - - 'test/unit/condition_unit_test.rb' - -# Offense count: 3 -# Cop supports --auto-correct. -# Configuration parameters: ConvertCodeThatCanStartToReturnNil, Whitelist. -# Whitelist: present?, blank?, presence, try, try! -Style/SafeNavigation: - Exclude: - - 'lib/liquid/drop.rb' - - 'lib/liquid/strainer.rb' - - 'lib/liquid/tokenizer.rb' - -# Offense count: 10 +# Offense count: 9 # Cop supports --auto-correct. # Configuration parameters: AllowAsExpressionSeparator. Style/Semicolon: Exclude: - - 'performance/shopify/database.rb' - 'test/integration/error_handling_test.rb' - 'test/integration/template_test.rb' - 'test/unit/context_unit_test.rb' - -# Offense count: 1 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle. -# SupportedStyles: use_perl_names, use_english_names -Style/SpecialGlobalVars: - Exclude: - - 'performance/shopify/liquid.rb' - -# Offense count: 2 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle. -# SupportedStyles: single_quotes, double_quotes -Style/StringLiteralsInInterpolation: - Exclude: - - 'performance/shopify/tag_filter.rb' - -# Offense count: 2 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle, AllowSafeAssignment. -# SupportedStyles: require_parentheses, require_no_parentheses, require_parentheses_when_complex -Style/TernaryParentheses: - Exclude: - - 'lib/liquid/context.rb' - - 'lib/liquid/utils.rb' - -# Offense count: 21 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyleForMultiline. -# SupportedStylesForMultiline: comma, consistent_comma, no_comma -Style/TrailingCommaInArrayLiteral: - Exclude: - - 'lib/liquid/parse_tree_visitor.rb' - - 'lib/liquid/tags/include.rb' - - 'test/integration/parse_tree_visitor_test.rb' - - 'test/integration/standard_filter_test.rb' - -# Offense count: 9 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyleForMultiline. -# SupportedStylesForMultiline: comma, consistent_comma, no_comma -Style/TrailingCommaInHashLiteral: - Exclude: - - 'lib/liquid/condition.rb' - - 'lib/liquid/lexer.rb' - - 'lib/liquid/standardfilters.rb' - - 'performance/shopify/comment_form.rb' - - 'performance/shopify/database.rb' - - 'performance/shopify/paginate.rb' - - 'performance/theme_runner.rb' - - 'test/integration/output_test.rb' - - 'test/unit/context_unit_test.rb' - -# Offense count: 2 -# Cop supports --auto-correct. -Style/UnneededPercentQ: - Exclude: - - 'test/integration/error_handling_test.rb' - -# Offense count: 1 -# Cop supports --auto-correct. -Style/WhileUntilModifier: - Exclude: - - 'lib/liquid/tags/case.rb' diff --git a/Rakefile b/Rakefile index f7186eb7..f2a0d07b 100755 --- a/Rakefile +++ b/Rakefile @@ -1,18 +1,18 @@ require 'rake' require 'rake/testtask' -$LOAD_PATH.unshift File.expand_path("../lib", __FILE__) +$LOAD_PATH.unshift(File.expand_path("../lib", __FILE__)) require "liquid/version" -task default: [:test, :rubocop] +task(default: [:test, :rubocop]) -desc 'run test suite with default parser' +desc('run test suite with default parser') Rake::TestTask.new(:base_test) do |t| t.libs << '.' << 'lib' << 'test' t.test_files = FileList['test/{integration,unit}/**/*_test.rb'] t.verbose = false end -desc 'run test suite with warn error mode' +desc('run test suite with warn error mode') task :warn_test do ENV['LIQUID_PARSER_MODE'] = 'warn' Rake::Task['base_test'].invoke @@ -25,7 +25,7 @@ task :rubocop do end end -desc 'runs test suite with both strict and lax parsers' +desc('runs test suite with both strict and lax parsers') task :test do ENV['LIQUID_PARSER_MODE'] = 'lax' Rake::Task['base_test'].invoke @@ -47,7 +47,7 @@ task :test do end end -task gem: :build +task(gem: :build) task :build do system "gem build liquid.gemspec" end @@ -94,7 +94,7 @@ namespace :memory_profile do end end -desc "Run example" +desc("Run example") task :example do ruby "-w -d -Ilib example/server/server.rb" end diff --git a/example/server/example_servlet.rb b/example/server/example_servlet.rb index dbc7a4b7..9f8c58a8 100644 --- a/example/server/example_servlet.rb +++ b/example/server/example_servlet.rb @@ -1,6 +1,6 @@ module ProductsFilter def price(integer) - sprintf("$%.2d USD", integer / 100.0) + format("$%.2d USD", integer / 100.0) end def prettyprint(text) diff --git a/example/server/liquid_servlet.rb b/example/server/liquid_servlet.rb index b2bf515f..895f274a 100644 --- a/example/server/liquid_servlet.rb +++ b/example/server/liquid_servlet.rb @@ -9,12 +9,12 @@ class LiquidServlet < WEBrick::HTTPServlet::AbstractServlet private - def handle(type, req, res) + def handle(_type, req, res) @request = req @response = res @request.path_info =~ /(\w+)\z/ - @action = $1 || 'index' + @action = Regexp.last_match(1) || 'index' @assigns = send(@action) if respond_to?(@action) @response['Content-Type'] = "text/html" diff --git a/example/server/server.rb b/example/server/server.rb index 703b361c..f2f89a40 100644 --- a/example/server/server.rb +++ b/example/server/server.rb @@ -8,5 +8,5 @@ require_relative 'example_servlet' # Setup webrick server = WEBrick::HTTPServer.new(Port: ARGV[1] || 3000) server.mount('/', Servlet) -trap("INT"){ server.shutdown } +trap("INT") { server.shutdown } server.start diff --git a/lib/liquid/block.rb b/lib/liquid/block.rb index 549a3a36..0036d7bf 100644 --- a/lib/liquid/block.rb +++ b/lib/liquid/block.rb @@ -28,15 +28,15 @@ module Liquid def unknown_tag(tag, _params, _tokens) if tag == 'else'.freeze - raise SyntaxError.new(parse_context.locale.t("errors.syntax.unexpected_else".freeze, - block_name: block_name)) + raise SyntaxError, parse_context.locale.t("errors.syntax.unexpected_else".freeze, + block_name: block_name) elsif tag.start_with?('end'.freeze) - raise SyntaxError.new(parse_context.locale.t("errors.syntax.invalid_delimiter".freeze, + raise SyntaxError, parse_context.locale.t("errors.syntax.invalid_delimiter".freeze, tag: tag, block_name: block_name, - block_delimiter: block_delimiter)) + block_delimiter: block_delimiter) else - raise SyntaxError.new(parse_context.locale.t("errors.syntax.unknown_tag".freeze, tag: tag)) + raise SyntaxError, parse_context.locale.t("errors.syntax.unknown_tag".freeze, tag: tag) end end @@ -61,7 +61,7 @@ module Liquid return false if end_tag_name == block_delimiter unless end_tag_name - raise SyntaxError.new(parse_context.locale.t("errors.syntax.tag_never_closed".freeze, block_name: block_name)) + raise SyntaxError, parse_context.locale.t("errors.syntax.tag_never_closed".freeze, block_name: block_name) end # this tag is not registered with the system diff --git a/lib/liquid/block_body.rb b/lib/liquid/block_body.rb index 27b4eef0..a52eb620 100644 --- a/lib/liquid/block_body.rb +++ b/lib/liquid/block_body.rb @@ -32,8 +32,8 @@ module Liquid # caller raise a syntax error return yield token, token end - tag_name = $1 - markup = $2 + tag_name = Regexp.last_match(1) + markup = Regexp.last_match(2) unless tag = registered_tags[tag_name] # end parsing if we reach an unknown tag and let the caller decide # determine how to proceed @@ -58,13 +58,13 @@ module Liquid unless token =~ FullToken raise_missing_tag_terminator(token, parse_context) end - tag_name = $2 - markup = $4 + tag_name = Regexp.last_match(2) + markup = Regexp.last_match(4) if parse_context.line_number # newlines inside the tag should increase the line number, # particularly important for multiline {% liquid %} tags - parse_context.line_number += $1.count("\n".freeze) + $3.count("\n".freeze) + parse_context.line_number += Regexp.last_match(1).count("\n".freeze) + Regexp.last_match(3).count("\n".freeze) end if tag_name == 'liquid'.freeze @@ -101,7 +101,7 @@ module Liquid def whitespace_handler(token, parse_context) if token[2] == WhitespaceControl previous_token = @nodelist.last - if previous_token.is_a? String + if previous_token.is_a?(String) previous_token.rstrip! end end @@ -163,7 +163,7 @@ module Liquid def raise_if_resource_limits_reached(context, length) context.resource_limits.render_length += length return unless context.resource_limits.reached? - raise MemoryError.new("Memory limits exceeded".freeze) + raise MemoryError, "Memory limits exceeded".freeze end def create_variable(token, parse_context) @@ -175,11 +175,11 @@ module Liquid end def raise_missing_tag_terminator(token, parse_context) - raise SyntaxError.new(parse_context.locale.t("errors.syntax.tag_termination".freeze, token: token, tag_end: TagEnd.inspect)) + raise SyntaxError, parse_context.locale.t("errors.syntax.tag_termination".freeze, token: token, tag_end: TagEnd.inspect) end def raise_missing_variable_terminator(token, parse_context) - raise SyntaxError.new(parse_context.locale.t("errors.syntax.variable_termination".freeze, token: token, tag_end: VariableEnd.inspect)) + raise SyntaxError, parse_context.locale.t("errors.syntax.variable_termination".freeze, token: token, tag_end: VariableEnd.inspect) end def registered_tags diff --git a/lib/liquid/condition.rb b/lib/liquid/condition.rb index 3b51682e..c6e29ae0 100644 --- a/lib/liquid/condition.rb +++ b/lib/liquid/condition.rb @@ -11,18 +11,18 @@ module Liquid '=='.freeze => ->(cond, left, right) { cond.send(:equal_variables, left, right) }, '!='.freeze => ->(cond, left, right) { !cond.send(:equal_variables, left, right) }, '<>'.freeze => ->(cond, left, right) { !cond.send(:equal_variables, left, right) }, - '<'.freeze => :<, - '>'.freeze => :>, + '<'.freeze => :<, + '>'.freeze => :>, '>='.freeze => :>=, '<='.freeze => :<=, - 'contains'.freeze => lambda do |cond, left, right| + 'contains'.freeze => lambda do |_cond, left, right| if left && right && left.respond_to?(:include?) right = right.to_s if left.is_a?(String) left.include?(right) else false end - end + end, } def self.operators @@ -36,7 +36,7 @@ module Liquid @left = left @operator = operator @right = right - @child_relation = nil + @child_relation = nil @child_condition = nil end @@ -116,7 +116,7 @@ module Liquid left = context.evaluate(left) right = context.evaluate(right) - operation = self.class.operators[op] || raise(Liquid::ArgumentError.new("Unknown operator #{op}")) + operation = self.class.operators[op] || raise(Liquid::ArgumentError, "Unknown operator #{op}") if operation.respond_to?(:call) operation.call(self, left, right) @@ -124,7 +124,7 @@ module Liquid begin left.send(operation, right) rescue ::ArgumentError => e - raise Liquid::ArgumentError.new(e.message) + raise Liquid::ArgumentError, e.message end end end diff --git a/lib/liquid/context.rb b/lib/liquid/context.rb index 90e6b789..b5d56385 100644 --- a/lib/liquid/context.rb +++ b/lib/liquid/context.rb @@ -39,7 +39,7 @@ module Liquid self.exception_renderer = Template.default_exception_renderer if rethrow_errors - self.exception_renderer = ->(e) { raise } + self.exception_renderer = ->(_e) { raise } end @interrupts = [] @@ -215,7 +215,7 @@ module Liquid value = obj[key] if value.is_a?(Proc) && obj.respond_to?(:[]=) - obj[key] = (value.arity == 0) ? value.call : value.call(self) + obj[key] = value.arity == 0 ? value.call : value.call(self) else value end diff --git a/lib/liquid/document.rb b/lib/liquid/document.rb index d035dd46..afd4e998 100644 --- a/lib/liquid/document.rb +++ b/lib/liquid/document.rb @@ -7,7 +7,7 @@ module Liquid end def parse(tokens, parse_context) - super do |end_tag_name, end_tag_params| + super do |end_tag_name, _end_tag_params| unknown_tag(end_tag_name, parse_context) if end_tag_name end rescue SyntaxError => e @@ -18,9 +18,9 @@ module Liquid def unknown_tag(tag, parse_context) case tag when 'else'.freeze, 'end'.freeze - raise SyntaxError.new(parse_context.locale.t("errors.syntax.unexpected_outer_tag".freeze, tag: tag)) + raise SyntaxError, parse_context.locale.t("errors.syntax.unexpected_outer_tag".freeze, tag: tag) else - raise SyntaxError.new(parse_context.locale.t("errors.syntax.unknown_tag".freeze, tag: tag)) + raise SyntaxError, parse_context.locale.t("errors.syntax.unknown_tag".freeze, tag: tag) end end end diff --git a/lib/liquid/drop.rb b/lib/liquid/drop.rb index 6b5aa993..14d6eac9 100644 --- a/lib/liquid/drop.rb +++ b/lib/liquid/drop.rb @@ -25,7 +25,7 @@ module Liquid # Catch all for the method def liquid_method_missing(method) - return nil unless @context && @context.strict_variables + return nil unless @context&.strict_variables raise Liquid::UndefinedDropMethod, "undefined method #{method}" end diff --git a/lib/liquid/errors.rb b/lib/liquid/errors.rb index defa5ea9..4239746f 100644 --- a/lib/liquid/errors.rb +++ b/lib/liquid/errors.rb @@ -21,10 +21,10 @@ module Liquid def message_prefix str = "" - if is_a?(SyntaxError) - str << "Liquid syntax error" + str << if is_a?(SyntaxError) + "Liquid syntax error" else - str << "Liquid error" + "Liquid error" end if line_number diff --git a/lib/liquid/expression.rb b/lib/liquid/expression.rb index 98be6db6..55681992 100644 --- a/lib/liquid/expression.rb +++ b/lib/liquid/expression.rb @@ -15,7 +15,7 @@ module Liquid LITERALS = { nil => nil, 'nil'.freeze => nil, 'null'.freeze => nil, ''.freeze => nil, - 'true'.freeze => true, + 'true'.freeze => true, 'false'.freeze => false, 'blank'.freeze => MethodLiteral.new(:blank?, '').freeze, 'empty'.freeze => MethodLiteral.new(:empty?, '').freeze @@ -33,13 +33,13 @@ module Liquid else case markup when SINGLE_QUOTED_STRING, DOUBLE_QUOTED_STRING - $1 + Regexp.last_match(1) when INTEGERS_REGEX - $1.to_i + Regexp.last_match(1).to_i when RANGES_REGEX - RangeLookup.parse($1, $2) + RangeLookup.parse(Regexp.last_match(1), Regexp.last_match(2)) when FLOATS_REGEX - $1.to_f + Regexp.last_match(1).to_f else VariableLookup.parse(markup) end diff --git a/lib/liquid/file_system.rb b/lib/liquid/file_system.rb index 13f1f460..a2aa9b75 100644 --- a/lib/liquid/file_system.rb +++ b/lib/liquid/file_system.rb @@ -57,7 +57,7 @@ module Liquid end def full_path(template_path) - raise FileSystemError, "Illegal template name '#{template_path}'" unless template_path =~ /\A[^.\/][a-zA-Z0-9_\/]+\z/ + raise FileSystemError, "Illegal template name '#{template_path}'" unless template_path =~ %r{\A[^./][a-zA-Z0-9_/]+\z} full_path = if template_path.include?('/'.freeze) File.join(root, File.dirname(template_path), @pattern % File.basename(template_path)) diff --git a/lib/liquid/i18n.rb b/lib/liquid/i18n.rb index 2671507e..b2bb51ba 100644 --- a/lib/liquid/i18n.rb +++ b/lib/liquid/i18n.rb @@ -26,13 +26,13 @@ module Liquid def interpolate(name, vars) name.gsub(/%\{(\w+)\}/) do # raise TranslationError, "Undefined key #{$1} for interpolation in translation #{name}" unless vars[$1.to_sym] - (vars[$1.to_sym]).to_s + (vars[Regexp.last_match(1).to_sym]).to_s end end def deep_fetch_translation(name) name.split('.'.freeze).reduce(locale) do |level, cur| - level[cur] or raise TranslationError, "Translation for #{name} does not exist in locale #{path}" + level[cur] || raise(TranslationError, "Translation for #{name} does not exist in locale #{path}") end end end diff --git a/lib/liquid/interrupts.rb b/lib/liquid/interrupts.rb index 41359d78..f3005e4c 100644 --- a/lib/liquid/interrupts.rb +++ b/lib/liquid/interrupts.rb @@ -9,8 +9,8 @@ module Liquid end # Interrupt that is thrown whenever a {% break %} is called. - class BreakInterrupt < Interrupt; end + class BreakInterrupt < RuntimeError; end # Interrupt that is thrown whenever a {% continue %} is called. - class ContinueInterrupt < Interrupt; end + class ContinueInterrupt < RuntimeError; end end diff --git a/lib/liquid/lexer.rb b/lib/liquid/lexer.rb index f290744d..367f99ee 100644 --- a/lib/liquid/lexer.rb +++ b/lib/liquid/lexer.rb @@ -11,7 +11,7 @@ module Liquid '('.freeze => :open_round, ')'.freeze => :close_round, '?'.freeze => :question, - '-'.freeze => :dash + '-'.freeze => :dash, }.freeze IDENTIFIER = /[a-zA-Z_][\w-]*\??/ SINGLE_STRING_LITERAL = /'[^\']*'/ @@ -31,13 +31,12 @@ module Liquid until @ss.eos? @ss.skip(WHITESPACE_OR_NOTHING) break if @ss.eos? - tok = case - when t = @ss.scan(COMPARISON_OPERATOR) then [:comparison, t] - when t = @ss.scan(SINGLE_STRING_LITERAL) then [:string, t] - when t = @ss.scan(DOUBLE_STRING_LITERAL) then [:string, t] - when t = @ss.scan(NUMBER_LITERAL) then [:number, t] - when t = @ss.scan(IDENTIFIER) then [:id, t] - when t = @ss.scan(DOTDOT) then [:dotdot, t] + tok = if t = @ss.scan(COMPARISON_OPERATOR) then [:comparison, t] + elsif t = @ss.scan(SINGLE_STRING_LITERAL) then [:string, t] + elsif t = @ss.scan(DOUBLE_STRING_LITERAL) then [:string, t] + elsif t = @ss.scan(NUMBER_LITERAL) then [:number, t] + elsif t = @ss.scan(IDENTIFIER) then [:id, t] + elsif t = @ss.scan(DOTDOT) then [:dotdot, t] else c = @ss.getch if s = SPECIALS[c] diff --git a/lib/liquid/parse_context.rb b/lib/liquid/parse_context.rb index abcdaeba..58437f4d 100644 --- a/lib/liquid/parse_context.rb +++ b/lib/liquid/parse_context.rb @@ -28,7 +28,7 @@ module Liquid if dont_pass == true { locale: locale } elsif dont_pass.is_a?(Array) - @template_options.reject { |k, v| dont_pass.include?(k) } + @template_options.reject { |k, _v| dont_pass.include?(k) } else @template_options end diff --git a/lib/liquid/parse_tree_visitor.rb b/lib/liquid/parse_tree_visitor.rb index 74f5563a..d50943f3 100644 --- a/lib/liquid/parse_tree_visitor.rb +++ b/lib/liquid/parse_tree_visitor.rb @@ -28,7 +28,7 @@ module Liquid item, new_context = @callbacks[node.class].call(node, context) [ item, - ParseTreeVisitor.for(node, @callbacks).visit(new_context || context) + ParseTreeVisitor.for(node, @callbacks).visit(new_context || context), ] end end diff --git a/lib/liquid/parser.rb b/lib/liquid/parser.rb index 16df6e93..c36de86f 100644 --- a/lib/liquid/parser.rb +++ b/lib/liquid/parser.rb @@ -51,7 +51,7 @@ module Liquid token = @tokens[@p] if token[0] == :id variable_signature - elsif SINGLE_TOKEN_EXPRESSION_TYPES.include? token[0] + elsif SINGLE_TOKEN_EXPRESSION_TYPES.include?(token[0]) consume elsif token.first == :open_round consume diff --git a/lib/liquid/standardfilters.rb b/lib/liquid/standardfilters.rb index afcf479e..b13d089c 100644 --- a/lib/liquid/standardfilters.rb +++ b/lib/liquid/standardfilters.rb @@ -8,13 +8,13 @@ module Liquid '>'.freeze => '>'.freeze, '<'.freeze => '<'.freeze, '"'.freeze => '"'.freeze, - "'".freeze => '''.freeze + "'".freeze => '''.freeze, }.freeze HTML_ESCAPE_ONCE_REGEXP = /["><']|&(?!([a-zA-Z]+|(#\d+));)/ STRIP_HTML_BLOCKS = Regexp.union( - //m, + %r{}m, //m, - //m + %r{}m ) STRIP_HTML_TAGS = /<.*?>/m @@ -276,7 +276,7 @@ module Liquid def concat(input, array) unless array.respond_to?(:to_ary) - raise ArgumentError.new("concat filter requires an array argument") + raise ArgumentError, "concat filter requires an array argument" end InputIterator.new(input).concat(array) end @@ -430,7 +430,7 @@ module Liquid private def raise_property_error(property) - raise Liquid::ArgumentError.new("cannot select the property '#{property}'") + raise Liquid::ArgumentError, "cannot select the property '#{property}'" end def apply_operation(input, operand, operation) diff --git a/lib/liquid/strainer.rb b/lib/liquid/strainer.rb index 76d56d23..d885ae41 100644 --- a/lib/liquid/strainer.rb +++ b/lib/liquid/strainer.rb @@ -27,7 +27,7 @@ module Liquid def self.add_filter(filter) raise ArgumentError, "Expected module but got: #{filter.class}" unless filter.is_a?(Module) - unless self.include?(filter) + unless include?(filter) invokable_non_public_methods = (filter.private_instance_methods + filter.protected_instance_methods).select { |m| invokable?(m) } if invokable_non_public_methods.any? raise MethodOverrideError, "Filter overrides registered public methods as non public: #{invokable_non_public_methods.join(', ')}" @@ -54,7 +54,7 @@ module Liquid def invoke(method, *args) if self.class.invokable?(method) send(method, *args) - elsif @context && @context.strict_filters + elsif @context&.strict_filters raise Liquid::UndefinedFilter, "undefined filter #{method}" else args.first diff --git a/lib/liquid/tags/assign.rb b/lib/liquid/tags/assign.rb index 50a95536..6ff65d57 100644 --- a/lib/liquid/tags/assign.rb +++ b/lib/liquid/tags/assign.rb @@ -19,10 +19,10 @@ module Liquid def initialize(tag_name, markup, options) super if markup =~ Syntax - @to = $1 - @from = Variable.new($2, options) + @to = Regexp.last_match(1) + @from = Variable.new(Regexp.last_match(2), options) else - raise SyntaxError.new(options[:locale].t(self.class.syntax_error_translation_key)) + raise SyntaxError, options[:locale].t(self.class.syntax_error_translation_key) end end diff --git a/lib/liquid/tags/capture.rb b/lib/liquid/tags/capture.rb index d717b769..a97e42a1 100644 --- a/lib/liquid/tags/capture.rb +++ b/lib/liquid/tags/capture.rb @@ -16,9 +16,9 @@ module Liquid def initialize(tag_name, markup, options) super if markup =~ Syntax - @to = $1 + @to = Regexp.last_match(1) else - raise SyntaxError.new(options[:locale].t("errors.syntax.capture")) + raise SyntaxError, options[:locale].t("errors.syntax.capture") end end diff --git a/lib/liquid/tags/case.rb b/lib/liquid/tags/case.rb index 92b2ed0d..7d430193 100644 --- a/lib/liquid/tags/case.rb +++ b/lib/liquid/tags/case.rb @@ -10,17 +10,15 @@ module Liquid @blocks = [] if markup =~ Syntax - @left = Expression.parse($1) + @left = Expression.parse(Regexp.last_match(1)) else - raise SyntaxError.new(options[:locale].t("errors.syntax.case".freeze)) + raise SyntaxError, options[:locale].t("errors.syntax.case".freeze) end end def parse(tokens) body = BlockBody.new - while parse_body(body, tokens) - body = @blocks.last.attachment - end + body = @blocks.last.attachment while parse_body(body, tokens) end def nodelist @@ -62,12 +60,12 @@ module Liquid while markup unless markup =~ WhenSyntax - raise SyntaxError.new(options[:locale].t("errors.syntax.case_invalid_when".freeze)) + raise SyntaxError, options[:locale].t("errors.syntax.case_invalid_when".freeze) end - markup = $2 + markup = Regexp.last_match(2) - block = Condition.new(@left, '=='.freeze, Expression.parse($1)) + block = Condition.new(@left, '=='.freeze, Expression.parse(Regexp.last_match(1))) block.attach(body) @blocks << block end @@ -75,7 +73,7 @@ module Liquid def record_else_condition(markup) unless markup.strip.empty? - raise SyntaxError.new(options[:locale].t("errors.syntax.case_invalid_else".freeze)) + raise SyntaxError, options[:locale].t("errors.syntax.case_invalid_else".freeze) end block = ElseCondition.new diff --git a/lib/liquid/tags/cycle.rb b/lib/liquid/tags/cycle.rb index e42244d4..33999028 100644 --- a/lib/liquid/tags/cycle.rb +++ b/lib/liquid/tags/cycle.rb @@ -21,13 +21,13 @@ module Liquid super case markup when NamedSyntax - @variables = variables_from_string($2) - @name = Expression.parse($1) + @variables = variables_from_string(Regexp.last_match(2)) + @name = Expression.parse(Regexp.last_match(1)) when SimpleSyntax @variables = variables_from_string(markup) @name = @variables.to_s else - raise SyntaxError.new(options[:locale].t("errors.syntax.cycle".freeze)) + raise SyntaxError, options[:locale].t("errors.syntax.cycle".freeze) end end @@ -61,7 +61,7 @@ module Liquid def variables_from_string(markup) markup.split(',').collect do |var| var =~ /\s*(#{QuotedFragment})\s*/o - $1 ? Expression.parse($1) : nil + Regexp.last_match(1) ? Expression.parse(Regexp.last_match(1)) : nil end.compact end diff --git a/lib/liquid/tags/for.rb b/lib/liquid/tags/for.rb index 71c2f910..f20953f8 100644 --- a/lib/liquid/tags/for.rb +++ b/lib/liquid/tags/for.rb @@ -86,23 +86,23 @@ module Liquid def lax_parse(markup) if markup =~ Syntax - @variable_name = $1 - collection_name = $2 - @reversed = !!$3 + @variable_name = Regexp.last_match(1) + collection_name = Regexp.last_match(2) + @reversed = !!Regexp.last_match(3) @name = "#{@variable_name}-#{collection_name}" @collection_name = Expression.parse(collection_name) markup.scan(TagAttributes) do |key, value| set_attribute(key, value) end else - raise SyntaxError.new(options[:locale].t("errors.syntax.for".freeze)) + raise SyntaxError, options[:locale].t("errors.syntax.for".freeze) end end def strict_parse(markup) p = Parser.new(markup) @variable_name = p.consume(:id) - raise SyntaxError.new(options[:locale].t("errors.syntax.for_invalid_in".freeze)) unless p.id?('in'.freeze) + raise SyntaxError, options[:locale].t("errors.syntax.for_invalid_in".freeze) unless p.id?('in'.freeze) collection_name = p.expression @name = "#{@variable_name}-#{collection_name}" @collection_name = Expression.parse(collection_name) @@ -110,7 +110,7 @@ module Liquid while p.look(:id) && p.look(:colon, 1) unless attribute = p.id?('limit'.freeze) || p.id?('offset'.freeze) - raise SyntaxError.new(options[:locale].t("errors.syntax.for_invalid_attribute".freeze)) + raise SyntaxError, options[:locale].t("errors.syntax.for_invalid_attribute".freeze) end p.consume set_attribute(attribute, p.expression) @@ -170,11 +170,10 @@ module Liquid loop_vars.send(:increment!) # Handle any interrupts if they exist. - if context.interrupt? - interrupt = context.pop_interrupt - break if interrupt.is_a? BreakInterrupt - next if interrupt.is_a? ContinueInterrupt - end + next unless context.interrupt? + interrupt = context.pop_interrupt + break if interrupt.is_a?(BreakInterrupt) + next if interrupt.is_a?(ContinueInterrupt) end ensure for_stack.pop diff --git a/lib/liquid/tags/if.rb b/lib/liquid/tags/if.rb index 25534a98..5c9b8bb1 100644 --- a/lib/liquid/tags/if.rb +++ b/lib/liquid/tags/if.rb @@ -66,17 +66,17 @@ module Liquid def lax_parse(markup) expressions = markup.scan(ExpressionsAndOperators) - raise(SyntaxError.new(options[:locale].t("errors.syntax.if".freeze))) unless expressions.pop =~ Syntax + raise SyntaxError, options[:locale].t("errors.syntax.if".freeze) unless expressions.pop =~ Syntax - condition = Condition.new(Expression.parse($1), $2, Expression.parse($3)) + condition = Condition.new(Expression.parse(Regexp.last_match(1)), Regexp.last_match(2), Expression.parse(Regexp.last_match(3))) until expressions.empty? operator = expressions.pop.to_s.strip - raise(SyntaxError.new(options[:locale].t("errors.syntax.if".freeze))) unless expressions.pop.to_s =~ Syntax + raise SyntaxError, options[:locale].t("errors.syntax.if".freeze) unless expressions.pop.to_s =~ Syntax - new_condition = Condition.new(Expression.parse($1), $2, Expression.parse($3)) - raise(SyntaxError.new(options[:locale].t("errors.syntax.if".freeze))) unless BOOLEAN_OPERATORS.include?(operator) + new_condition = Condition.new(Expression.parse(Regexp.last_match(1)), Regexp.last_match(2), Expression.parse(Regexp.last_match(3))) + raise SyntaxError, options[:locale].t("errors.syntax.if".freeze) unless BOOLEAN_OPERATORS.include?(operator) new_condition.send(operator, condition) condition = new_condition end diff --git a/lib/liquid/tags/include.rb b/lib/liquid/tags/include.rb index fd86ee4b..d2c6cd26 100644 --- a/lib/liquid/tags/include.rb +++ b/lib/liquid/tags/include.rb @@ -23,8 +23,8 @@ module Liquid if markup =~ Syntax - template_name = $1 - variable_name = $3 + template_name = Regexp.last_match(1) + variable_name = Regexp.last_match(3) @variable_name_expr = variable_name ? Expression.parse(variable_name) : nil @template_name_expr = Expression.parse(template_name) @@ -35,7 +35,7 @@ module Liquid end else - raise SyntaxError.new(options[:locale].t("errors.syntax.include".freeze)) + raise SyntaxError, options[:locale].t("errors.syntax.include".freeze) end end @@ -44,7 +44,7 @@ module Liquid def render_to_output_buffer(context, output) template_name = context.evaluate(@template_name_expr) - raise ArgumentError.new(options[:locale].t("errors.argument.include")) unless template_name + raise ArgumentError, options[:locale].t("errors.argument.include") unless template_name partial = PartialCache.load( template_name, @@ -95,7 +95,7 @@ module Liquid def children [ @node.template_name_expr, - @node.variable_name_expr + @node.variable_name_expr, ] + @node.attributes.values end end diff --git a/lib/liquid/tags/raw.rb b/lib/liquid/tags/raw.rb index 4fa75d99..69910021 100644 --- a/lib/liquid/tags/raw.rb +++ b/lib/liquid/tags/raw.rb @@ -13,13 +13,13 @@ module Liquid @body = '' while token = tokens.shift if token =~ FullTokenPossiblyInvalid - @body << $1 if $1 != "".freeze - return if block_delimiter == $2 + @body << Regexp.last_match(1) if Regexp.last_match(1) != "".freeze + return if block_delimiter == Regexp.last_match(2) end @body << token unless token.empty? end - raise SyntaxError.new(parse_context.locale.t("errors.syntax.tag_never_closed".freeze, block_name: block_name)) + raise SyntaxError, parse_context.locale.t("errors.syntax.tag_never_closed".freeze, block_name: block_name) end def render_to_output_buffer(_context, output) @@ -39,7 +39,7 @@ module Liquid def ensure_valid_markup(tag_name, markup, parse_context) unless markup =~ Syntax - raise SyntaxError.new(parse_context.locale.t("errors.syntax.tag_unexpected_args".freeze, tag: tag_name)) + raise SyntaxError, parse_context.locale.t("errors.syntax.tag_unexpected_args".freeze, tag: tag_name) end end end diff --git a/lib/liquid/tags/render.rb b/lib/liquid/tags/render.rb index 2e5310b4..d7288983 100644 --- a/lib/liquid/tags/render.rb +++ b/lib/liquid/tags/render.rb @@ -7,9 +7,9 @@ module Liquid def initialize(tag_name, markup, options) super - raise SyntaxError.new(options[:locale].t("errors.syntax.render".freeze)) unless markup =~ Syntax + raise SyntaxError, options[:locale].t("errors.syntax.render".freeze) unless markup =~ Syntax - template_name = $1 + template_name = Regexp.last_match(1) @template_name_expr = Expression.parse(template_name) @@ -22,7 +22,7 @@ module Liquid def render_to_output_buffer(context, output) # Though we evaluate this here we will only ever parse it as a string literal. template_name = context.evaluate(@template_name_expr) - raise ArgumentError.new(options[:locale].t("errors.argument.include")) unless template_name + raise ArgumentError, options[:locale].t("errors.argument.include") unless template_name partial = PartialCache.load( template_name, diff --git a/lib/liquid/tags/table_row.rb b/lib/liquid/tags/table_row.rb index 95321020..93935276 100644 --- a/lib/liquid/tags/table_row.rb +++ b/lib/liquid/tags/table_row.rb @@ -7,19 +7,19 @@ module Liquid def initialize(tag_name, markup, options) super if markup =~ Syntax - @variable_name = $1 - @collection_name = Expression.parse($2) + @variable_name = Regexp.last_match(1) + @collection_name = Expression.parse(Regexp.last_match(2)) @attributes = {} markup.scan(TagAttributes) do |key, value| @attributes[key] = Expression.parse(value) end else - raise SyntaxError.new(options[:locale].t("errors.syntax.table_row".freeze)) + raise SyntaxError, options[:locale].t("errors.syntax.table_row".freeze) end end def render_to_output_buffer(context, output) - collection = context.evaluate(@collection_name) or return ''.freeze + (collection = context.evaluate(@collection_name)) || (return ''.freeze) from = @attributes.key?('offset'.freeze) ? context.evaluate(@attributes['offset'.freeze]).to_i : 0 to = @attributes.key?('limit'.freeze) ? from + context.evaluate(@attributes['limit'.freeze]).to_i : nil diff --git a/lib/liquid/template.rb b/lib/liquid/template.rb index 91e30fbc..62250b28 100644 --- a/lib/liquid/template.rb +++ b/lib/liquid/template.rb @@ -172,7 +172,7 @@ module Liquid c = args.shift if @rethrow_errors - c.exception_renderer = ->(e) { raise } + c.exception_renderer = ->(_e) { raise } end c diff --git a/lib/liquid/tokenizer.rb b/lib/liquid/tokenizer.rb index d3fd6766..95114200 100644 --- a/lib/liquid/tokenizer.rb +++ b/lib/liquid/tokenizer.rb @@ -10,7 +10,7 @@ module Liquid end def shift - token = @tokens.shift or return + (token = @tokens.shift) || return if @line_number @line_number += @for_liquid_tag ? 1 : token.count("\n") @@ -29,7 +29,7 @@ module Liquid tokens = @source.split(TemplateParser) # removes the rogue empty element at the beginning of the array - tokens.shift if tokens[0] && tokens[0].empty? + tokens.shift if tokens[0]&.empty? tokens end diff --git a/lib/liquid/utils.rb b/lib/liquid/utils.rb index 516ac0cf..ada4f396 100644 --- a/lib/liquid/utils.rb +++ b/lib/liquid/utils.rb @@ -50,7 +50,7 @@ module Liquid when Numeric obj when String - (obj.strip =~ /\A-?\d+\.\d+\z/) ? BigDecimal(obj) : obj.to_i + obj.strip =~ /\A-?\d+\.\d+\z/ ? BigDecimal(obj) : obj.to_i else if obj.respond_to?(:to_number) obj.to_number diff --git a/lib/liquid/variable.rb b/lib/liquid/variable.rb index cbf99864..6efcf705 100644 --- a/lib/liquid/variable.rb +++ b/lib/liquid/variable.rb @@ -43,11 +43,11 @@ module Liquid @filters = [] return unless markup =~ MarkupWithQuotedFragment - name_markup = $1 - filter_markup = $2 + name_markup = Regexp.last_match(1) + filter_markup = Regexp.last_match(2) @name = Expression.parse(name_markup) if filter_markup =~ FilterMarkupRegex - filters = $1.scan(FilterParser) + filters = Regexp.last_match(1).scan(FilterParser) filters.each do |f| next unless f =~ /\w+/ filtername = Regexp.last_match(0) @@ -121,7 +121,7 @@ module Liquid end def evaluate_filter_expressions(context, filter_args, filter_kwargs) - parsed_args = filter_args.map{ |expr| context.evaluate(expr) } + parsed_args = filter_args.map { |expr| context.evaluate(expr) } if filter_kwargs parsed_kwargs = {} filter_kwargs.each do |key, expr| diff --git a/lib/liquid/variable_lookup.rb b/lib/liquid/variable_lookup.rb index 62f4877c..ab06bb62 100644 --- a/lib/liquid/variable_lookup.rb +++ b/lib/liquid/variable_lookup.rb @@ -14,7 +14,7 @@ module Liquid name = lookups.shift if name =~ SQUARE_BRACKETED - name = Expression.parse($1) + name = Expression.parse(Regexp.last_match(1)) end @name = name @@ -24,7 +24,7 @@ module Liquid @lookups.each_index do |i| lookup = lookups[i] if lookup =~ SQUARE_BRACKETED - lookups[i] = Expression.parse($1) + lookups[i] = Expression.parse(Regexp.last_match(1)) elsif COMMAND_METHODS.include?(lookup) @command_flags |= 1 << i end diff --git a/liquid.gemspec b/liquid.gemspec index 89df19a0..27b24aae 100644 --- a/liquid.gemspec +++ b/liquid.gemspec @@ -1,7 +1,7 @@ # encoding: utf-8 lib = File.expand_path('../lib/', __FILE__) -$LOAD_PATH.unshift lib unless $LOAD_PATH.include?(lib) +$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) require "liquid/version" @@ -26,6 +26,6 @@ Gem::Specification.new do |s| s.require_path = "lib" - s.add_development_dependency 'rake', '~> 11.3' - s.add_development_dependency 'minitest' + s.add_development_dependency('rake', '~> 11.3') + s.add_development_dependency('minitest') end diff --git a/performance/shopify/comment_form.rb b/performance/shopify/comment_form.rb index 7b5bd53b..65af1b51 100644 --- a/performance/shopify/comment_form.rb +++ b/performance/shopify/comment_form.rb @@ -5,10 +5,10 @@ class CommentForm < Liquid::Block super if markup =~ Syntax - @variable_name = $1 + @variable_name = Regexp.last_match(1) @attributes = {} else - raise SyntaxError.new("Syntax Error in 'comment_form' - Valid syntax: comment_form [article]") + raise SyntaxError, "Syntax Error in 'comment_form' - Valid syntax: comment_form [article]" end end @@ -20,8 +20,8 @@ class CommentForm < Liquid::Block 'posted_successfully?' => context.registers[:posted_successfully], 'errors' => context['comment.errors'], 'author' => context['comment.author'], - 'email' => context['comment.email'], - 'body' => context['comment.body'] + 'email' => context['comment.email'], + 'body' => context['comment.body'], } output << wrap_in_form(article, render_all(@nodelist, context, output)) diff --git a/performance/shopify/database.rb b/performance/shopify/database.rb index 2b5bca49..c9f18c30 100644 --- a/performance/shopify/database.rb +++ b/performance/shopify/database.rb @@ -16,9 +16,10 @@ module Database end # key the tables by handles, as this is how liquid expects it. - db = db.inject({}) do |assigns, (key, values)| - assigns[key] = values.inject({}) { |h, v| h[v['handle']] = v; h; } - assigns + db = db.each_with_object({}) do |(key, values), assigns| + assigns[key] = values.each_with_object({}) do |v, h| + h[v['handle']] = v + end end # Some standard direct accessors so that the specialized templates @@ -30,8 +31,8 @@ module Database db['cart'] = { 'total_price' => db['line_items'].values.inject(0) { |sum, item| sum += item['line_price'] * item['quantity'] }, - 'item_count' => db['line_items'].values.inject(0) { |sum, item| sum += item['quantity'] }, - 'items' => db['line_items'].values + 'item_count' => db['line_items'].values.inject(0) { |sum, item| sum += item['quantity'] }, + 'items' => db['line_items'].values, } db @@ -40,6 +41,6 @@ module Database end if __FILE__ == $PROGRAM_NAME - p Database.tables['collections']['frontpage'].keys + p(Database.tables['collections']['frontpage'].keys) # p Database.tables['blog']['articles'] end diff --git a/performance/shopify/json_filter.rb b/performance/shopify/json_filter.rb index 8fbb5b66..32583167 100644 --- a/performance/shopify/json_filter.rb +++ b/performance/shopify/json_filter.rb @@ -2,6 +2,6 @@ require 'json' module JsonFilter def json(object) - JSON.dump(object.reject { |k, v| k == "collections" }) + JSON.dump(object.reject { |k, _v| k == "collections" }) end end diff --git a/performance/shopify/liquid.rb b/performance/shopify/liquid.rb index 7716debc..f9d52007 100644 --- a/performance/shopify/liquid.rb +++ b/performance/shopify/liquid.rb @@ -1,4 +1,4 @@ -$:.unshift __dir__ + '/../../lib' +$LOAD_PATH.unshift(__dir__ + '/../../lib') require_relative '../../lib/liquid' require_relative 'comment_form' @@ -9,11 +9,11 @@ require_relative 'shop_filter' require_relative 'tag_filter' require_relative 'weight_filter' -Liquid::Template.register_tag 'paginate', Paginate -Liquid::Template.register_tag 'form', CommentForm +Liquid::Template.register_tag('paginate', Paginate) +Liquid::Template.register_tag('form', CommentForm) -Liquid::Template.register_filter JsonFilter -Liquid::Template.register_filter MoneyFilter -Liquid::Template.register_filter WeightFilter -Liquid::Template.register_filter ShopFilter -Liquid::Template.register_filter TagFilter +Liquid::Template.register_filter(JsonFilter) +Liquid::Template.register_filter(MoneyFilter) +Liquid::Template.register_filter(WeightFilter) +Liquid::Template.register_filter(ShopFilter) +Liquid::Template.register_filter(TagFilter) diff --git a/performance/shopify/money_filter.rb b/performance/shopify/money_filter.rb index 8dad7890..4cc7280d 100644 --- a/performance/shopify/money_filter.rb +++ b/performance/shopify/money_filter.rb @@ -1,12 +1,12 @@ module MoneyFilter def money_with_currency(money) return '' if money.nil? - sprintf("$ %.2f USD", money / 100.0) + format("$ %.2f USD", money / 100.0) end def money(money) return '' if money.nil? - sprintf("$ %.2f", money / 100.0) + format("$ %.2f", money / 100.0) end private diff --git a/performance/shopify/paginate.rb b/performance/shopify/paginate.rb index 0abd11ff..29e7c9ee 100644 --- a/performance/shopify/paginate.rb +++ b/performance/shopify/paginate.rb @@ -1,13 +1,13 @@ class Paginate < Liquid::Block - Syntax = /(#{Liquid::QuotedFragment})\s*(by\s*(\d+))?/ + Syntax = /(#{Liquid::QuotedFragment})\s*(by\s*(\d+))?/ def initialize(tag_name, markup, options) super if markup =~ Syntax - @collection_name = $1 - @page_size = if $2 - $3.to_i + @collection_name = Regexp.last_match(1) + @page_size = if Regexp.last_match(2) + Regexp.last_match(3).to_i else 20 end @@ -17,7 +17,7 @@ class Paginate < Liquid::Block @attributes[key] = value end else - raise SyntaxError.new("Syntax Error in tag 'paginate' - Valid syntax: paginate [collection] by number") + raise SyntaxError, "Syntax Error in tag 'paginate' - Valid syntax: paginate [collection] by number" end end @@ -25,19 +25,19 @@ class Paginate < Liquid::Block @context = context context.stack do - current_page = context['current_page'].to_i + current_page = context['current_page'].to_i pagination = { - 'page_size' => @page_size, - 'current_page' => 5, - 'current_offset' => @page_size * 5 + 'page_size' => @page_size, + 'current_page' => 5, + 'current_offset' => @page_size * 5, } context['paginate'] = pagination - collection_size = context[@collection_name].size + collection_size = context[@collection_name].size - raise ArgumentError.new("Cannot paginate array '#{@collection_name}'. Not found.") if collection_size.nil? + raise ArgumentError, "Cannot paginate array '#{@collection_name}'. Not found." if collection_size.nil? page_count = (collection_size.to_f / @page_size.to_f).to_f.ceil + 1 diff --git a/performance/shopify/shop_filter.rb b/performance/shopify/shop_filter.rb index 89c9083b..b2a0a9d0 100644 --- a/performance/shopify/shop_filter.rb +++ b/performance/shopify/shop_filter.rb @@ -52,7 +52,7 @@ module ShopFilter end def product_img_url(url, style = 'small') - unless url =~ /\Aproducts\/([\w\-\_]+)\.(\w{2,4})/ + unless url =~ %r{\Aproducts/([\w\-\_]+)\.(\w{2,4})} raise ArgumentError, 'filter "size" can only be called on product images' end @@ -60,7 +60,7 @@ module ShopFilter when 'original' return '/files/shops/random_number/' + url when 'grande', 'large', 'medium', 'compact', 'small', 'thumb', 'icon' - "/files/shops/random_number/products/#{$1}_#{style}.#{$2}" + "/files/shops/random_number/products/#{Regexp.last_match(1)}_#{style}.#{Regexp.last_match(2)}" else raise ArgumentError, 'valid parameters for filter "size" are: original, grande, large, medium, compact, small, thumb and icon ' end @@ -70,16 +70,14 @@ module ShopFilter html = [] html << %(#{link_to(paginate['previous']['title'], paginate['previous']['url'])}) if paginate['previous'] - for part in paginate['parts'] - - if part['is_link'] - html << %(#{link_to(part['title'], part['url'])}) + paginate['parts'].each do |part| + html << if part['is_link'] + %(#{link_to(part['title'], part['url'])}) elsif part['title'].to_i == paginate['current_page'].to_i - html << %(#{part['title']}) + %(#{part['title']}) else - html << %(#{part['title']}) + %(#{part['title']}) end - end html << %(#{link_to(paginate['next']['title'], paginate['next']['url'])}) if paginate['next'] diff --git a/performance/shopify/tag_filter.rb b/performance/shopify/tag_filter.rb index ab5aef62..34b426f2 100644 --- a/performance/shopify/tag_filter.rb +++ b/performance/shopify/tag_filter.rb @@ -13,11 +13,11 @@ module TagFilter def link_to_add_tag(label, tag) tags = (@context['current_tags'] + [tag]).uniq - "#{label}" + "#{label}" end def link_to_remove_tag(label, tag) tags = (@context['current_tags'] - [tag]).uniq - "#{label}" + "#{label}" end end diff --git a/performance/shopify/weight_filter.rb b/performance/shopify/weight_filter.rb index a0a15fca..b05bcce1 100644 --- a/performance/shopify/weight_filter.rb +++ b/performance/shopify/weight_filter.rb @@ -1,6 +1,6 @@ module WeightFilter def weight(grams) - sprintf("%.2f", grams / 1000) + format("%.2f", grams / 1000) end def weight_with_unit(grams) diff --git a/performance/theme_runner.rb b/performance/theme_runner.rb index 9f6a1fc4..9268558c 100644 --- a/performance/theme_runner.rb +++ b/performance/theme_runner.rb @@ -31,7 +31,7 @@ class ThemeRunner { liquid: File.read(test), layout: (File.file?(theme_path) ? File.read(theme_path) : nil), - template_name: test + template_name: test, } end.compact diff --git a/test/integration/blank_test.rb b/test/integration/blank_test.rb index 2b46ad71..654ee987 100644 --- a/test/integration/blank_test.rb +++ b/test/integration/blank_test.rb @@ -1,7 +1,7 @@ require 'test_helper' class FoobarTag < Liquid::Tag - def render_to_output_buffer(context, output) + def render_to_output_buffer(_context, output) output << ' ' output end diff --git a/test/integration/drop_test.rb b/test/integration/drop_test.rb index 2de4a5a1..9294b2ff 100644 --- a/test/integration/drop_test.rb +++ b/test/integration/drop_test.rb @@ -201,9 +201,9 @@ class DropsTest < Minitest::Test end def test_scope_though_proc - assert_equal '1', Liquid::Template.parse('{{ s }}').render!('context' => ContextDrop.new, 's' => proc{ |c| c['context.scopes'] }) - assert_equal '2', Liquid::Template.parse('{%for i in dummy%}{{ s }}{%endfor%}').render!('context' => ContextDrop.new, 's' => proc{ |c| c['context.scopes'] }, 'dummy' => [1]) - assert_equal '3', Liquid::Template.parse('{%for i in dummy%}{%for i in dummy%}{{ s }}{%endfor%}{%endfor%}').render!('context' => ContextDrop.new, 's' => proc{ |c| c['context.scopes'] }, 'dummy' => [1]) + assert_equal '1', Liquid::Template.parse('{{ s }}').render!('context' => ContextDrop.new, 's' => proc { |c| c['context.scopes'] }) + assert_equal '2', Liquid::Template.parse('{%for i in dummy%}{{ s }}{%endfor%}').render!('context' => ContextDrop.new, 's' => proc { |c| c['context.scopes'] }, 'dummy' => [1]) + assert_equal '3', Liquid::Template.parse('{%for i in dummy%}{%for i in dummy%}{{ s }}{%endfor%}{%endfor%}').render!('context' => ContextDrop.new, 's' => proc { |c| c['context.scopes'] }, 'dummy' => [1]) end def test_scope_with_assigns @@ -241,7 +241,7 @@ class DropsTest < Minitest::Test end def test_some_enumerable_methods_still_get_invoked - [ :count, :max ].each do |method| + [:count, :max].each do |method| assert_equal "3", Liquid::Template.parse("{{collection.#{method}}}").render!('collection' => RealEnumerableDrop.new) assert_equal "3", Liquid::Template.parse("{{collection[\"#{method}\"]}}").render!('collection' => RealEnumerableDrop.new) assert_equal "3", Liquid::Template.parse("{{collection.#{method}}}").render!('collection' => EnumerableDrop.new) @@ -250,7 +250,7 @@ class DropsTest < Minitest::Test assert_equal "yes", Liquid::Template.parse("{% if collection contains 3 %}yes{% endif %}").render!('collection' => RealEnumerableDrop.new) - [ :min, :first ].each do |method| + [:min, :first].each do |method| assert_equal "1", Liquid::Template.parse("{{collection.#{method}}}").render!('collection' => RealEnumerableDrop.new) assert_equal "1", Liquid::Template.parse("{{collection[\"#{method}\"]}}").render!('collection' => RealEnumerableDrop.new) assert_equal "1", Liquid::Template.parse("{{collection.#{method}}}").render!('collection' => EnumerableDrop.new) diff --git a/test/integration/error_handling_test.rb b/test/integration/error_handling_test.rb index b2d186cf..875f4267 100644 --- a/test/integration/error_handling_test.rb +++ b/test/integration/error_handling_test.rb @@ -83,15 +83,14 @@ class ErrorHandlingTest < Minitest::Test def test_with_line_numbers_adds_numbers_to_parser_errors err = assert_raises(SyntaxError) do - Liquid::Template.parse(%q( + Liquid::Template.parse(' foobar {% "cat" | foobar %} bla - ), - line_numbers: true - ) + ', + line_numbers: true) end assert_match(/Liquid syntax error \(line 4\)/, err.message) @@ -99,15 +98,14 @@ class ErrorHandlingTest < Minitest::Test def test_with_line_numbers_adds_numbers_to_parser_errors_with_whitespace_trim err = assert_raises(SyntaxError) do - Liquid::Template.parse(%q( + Liquid::Template.parse(' foobar {%- "cat" | foobar -%} bla - ), - line_numbers: true - ) + ', + line_numbers: true) end assert_match(/Liquid syntax error \(line 4\)/, err.message) @@ -122,8 +120,7 @@ class ErrorHandlingTest < Minitest::Test bla ', error_mode: :warn, - line_numbers: true - ) + line_numbers: true) assert_equal ['Liquid syntax error (line 4): Unexpected character = in "1 =! 2"'], template.warnings.map(&:message) @@ -139,8 +136,7 @@ class ErrorHandlingTest < Minitest::Test bla ', error_mode: :strict, - line_numbers: true - ) + line_numbers: true) end assert_equal 'Liquid syntax error (line 4): Unexpected character = in "1 =! 2"', err.message @@ -157,8 +153,7 @@ class ErrorHandlingTest < Minitest::Test bla ', - line_numbers: true - ) + line_numbers: true) end assert_equal "Liquid syntax error (line 5): Unknown tag 'foo'", err.message @@ -205,7 +200,7 @@ class ErrorHandlingTest < Minitest::Test def test_default_exception_renderer_with_internal_error template = Liquid::Template.parse('This is a runtime error: {{ errors.runtime_error }}', line_numbers: true) - output = template.render({ 'errors' => ErrorDrop.new }) + output = template.render('errors' => ErrorDrop.new) assert_equal 'This is a runtime error: Liquid error (line 1): internal', output assert_equal [Liquid::InternalError], template.errors.map(&:class) @@ -217,7 +212,7 @@ class ErrorHandlingTest < Minitest::Test Liquid::Template.default_exception_renderer = ->(e) { exceptions << e; '' } template = Liquid::Template.parse('This is a runtime error: {{ errors.argument_error }}') - output = template.render({ 'errors' => ErrorDrop.new }) + output = template.render('errors' => ErrorDrop.new) assert_equal 'This is a runtime error: ', output assert_equal [Liquid::ArgumentError], template.errors.map(&:class) @@ -239,7 +234,7 @@ class ErrorHandlingTest < Minitest::Test end class TestFileSystem - def read_template_file(template_path) + def read_template_file(_template_path) "{{ errors.argument_error }}" end end diff --git a/test/integration/filter_test.rb b/test/integration/filter_test.rb index d3c880e8..0af29efb 100644 --- a/test/integration/filter_test.rb +++ b/test/integration/filter_test.rb @@ -2,23 +2,23 @@ require 'test_helper' module MoneyFilter def money(input) - sprintf(' %d$ ', input) + format(' %d$ ', input) end def money_with_underscore(input) - sprintf(' %d$ ', input) + format(' %d$ ', input) end end module CanadianMoneyFilter def money(input) - sprintf(' %d$ CAD ', input) + format(' %d$ CAD ', input) end end module SubstituteFilter def substitute(input, params = {}) - input.gsub(/%\{(\w+)\}/) { |match| params[$1] } + input.gsub(/%\{(\w+)\}/) { |_match| params[Regexp.last_match(1)] } end end @@ -26,7 +26,7 @@ class FiltersTest < Minitest::Test include Liquid module OverrideObjectMethodFilter - def tap(input) + def tap(_input) "tap overridden" end end @@ -149,7 +149,7 @@ class FiltersTest < Minitest::Test assert_equal "tap overridden", Template.parse("{{var | tap}}").render!({ 'var' => 1000 }, filters: [OverrideObjectMethodFilter]) # tap still treated as a non-existent filter - assert_equal "1000", Template.parse("{{var | tap}}").render!({ 'var' => 1000 }) + assert_equal "1000", Template.parse("{{var | tap}}").render!('var' => 1000) end end diff --git a/test/integration/hash_ordering_test.rb b/test/integration/hash_ordering_test.rb index dfc1c29f..8592395a 100644 --- a/test/integration/hash_ordering_test.rb +++ b/test/integration/hash_ordering_test.rb @@ -3,13 +3,13 @@ require 'test_helper' class HashOrderingTest < Minitest::Test module MoneyFilter def money(input) - sprintf(' %d$ ', input) + format(' %d$ ', input) end end module CanadianMoneyFilter def money(input) - sprintf(' %d$ CAD ', input) + format(' %d$ CAD ', input) end end diff --git a/test/integration/output_test.rb b/test/integration/output_test.rb index b4cf9d70..d94b0f89 100644 --- a/test/integration/output_test.rb +++ b/test/integration/output_test.rb @@ -1,7 +1,7 @@ require 'test_helper' module FunnyFilter - def make_funny(input) + def make_funny(_input) 'LOL' end @@ -32,7 +32,7 @@ class OutputTest < Minitest::Test def setup @assigns = { 'best_cars' => 'bmw', - 'car' => { 'bmw' => 'good', 'gm' => 'bad' } + 'car' => { 'bmw' => 'good', 'gm' => 'bad' }, } end diff --git a/test/integration/parse_tree_visitor_test.rb b/test/integration/parse_tree_visitor_test.rb index 6ad6a2d0..d1af123d 100644 --- a/test/integration/parse_tree_visitor_test.rb +++ b/test/integration/parse_tree_visitor_test.rb @@ -227,7 +227,7 @@ class ParseTreeVisitorTest < Minitest::Test [[nil, [ [nil, [[nil, [["other", []]]]]], ["test", []], - ["xs", []] + ["xs", []], ]]], traversal(%({% for x in xs offset: test %}{{ other }}{% endfor %})).visit ) diff --git a/test/integration/render_profiling_test.rb b/test/integration/render_profiling_test.rb index d0111e77..283b8bdd 100644 --- a/test/integration/render_profiling_test.rb +++ b/test/integration/render_profiling_test.rb @@ -128,7 +128,7 @@ class RenderProfilingTest < Minitest::Test t.render! timing_count = 0 - t.profiler.each do |timing| + t.profiler.each do |_timing| timing_count += 1 end @@ -145,7 +145,7 @@ class RenderProfilingTest < Minitest::Test def test_profiling_marks_children_of_for_blocks t = Template.parse("{% for item in collection %} {{ item }} {% endfor %}", profile: true) - t.render!({ "collection" => ["one", "two"] }) + t.render!("collection" => ["one", "two"]) assert_equal 1, t.profiler.length # Will profile each invocation of the for block diff --git a/test/integration/standard_filter_test.rb b/test/integration/standard_filter_test.rb index 60909510..7863cfeb 100644 --- a/test/integration/standard_filter_test.rb +++ b/test/integration/standard_filter_test.rb @@ -17,7 +17,7 @@ class TestThing "woot: #{@foo}" end - def [](whatever) + def [](_whatever) to_s end @@ -37,7 +37,7 @@ class TestEnumerable < Liquid::Drop include Enumerable def each(&block) - [ { "foo" => 1, "bar" => 2 }, { "foo" => 2, "bar" => 1 }, { "foo" => 3, "bar" => 3 } ].each(&block) + [{ "foo" => 1, "bar" => 2 }, { "foo" => 2, "bar" => 1 }, { "foo" => 3, "bar" => 3 }].each(&block) end end @@ -208,14 +208,14 @@ class StandardFiltersTest < Minitest::Test { "handle" => "beta" }, { "price" => 1, "handle" => "gamma" }, { "handle" => "delta" }, - { "price" => 2, "handle" => "epsilon" } + { "price" => 2, "handle" => "epsilon" }, ] expectation = [ { "price" => 1, "handle" => "gamma" }, { "price" => 2, "handle" => "epsilon" }, { "price" => 4, "handle" => "alpha" }, { "handle" => "delta" }, - { "handle" => "beta" } + { "handle" => "beta" }, ] assert_equal expectation, @filters.sort(input, "price") end @@ -236,14 +236,14 @@ class StandardFiltersTest < Minitest::Test { "handle" => "beta" }, { "price" => "1", "handle" => "gamma" }, { "handle" => "delta" }, - { "price" => 2, "handle" => "epsilon" } + { "price" => 2, "handle" => "epsilon" }, ] expectation = [ { "price" => "1", "handle" => "gamma" }, { "price" => 2, "handle" => "epsilon" }, { "price" => "4", "handle" => "alpha" }, { "handle" => "delta" }, - { "handle" => "beta" } + { "handle" => "beta" }, ] assert_equal expectation, @filters.sort_natural(input, "price") end @@ -256,7 +256,7 @@ class StandardFiltersTest < Minitest::Test { "fake" => "t" }, { "key" => "a" }, { "key" => "b" }, - { "key" => "c" } + { "key" => "c" }, ] expectation = [ { "key" => "a" }, @@ -265,7 +265,7 @@ class StandardFiltersTest < Minitest::Test { "key" => "X" }, { "key" => "Y" }, { "key" => "Z" }, - { "fake" => "t" } + { "fake" => "t" }, ] assert_equal expectation, @filters.sort_natural(input, "key") assert_equal ["a", "b", "c", "X", "Y", "Z"], @filters.sort_natural(["X", "Y", "Z", "a", "b", "c"]) @@ -279,7 +279,7 @@ class StandardFiltersTest < Minitest::Test foo = [ [1], [2], - [3] + [3], ] assert_raises Liquid::ArgumentError do @@ -295,7 +295,7 @@ class StandardFiltersTest < Minitest::Test foo = [ [1], [2], - [3] + [3], ] assert_raises Liquid::ArgumentError do @@ -304,7 +304,7 @@ class StandardFiltersTest < Minitest::Test end def test_legacy_sort_hash - assert_equal [{ a: 1, b: 2 }], @filters.sort({ a: 1, b: 2 }) + assert_equal [{ a: 1, b: 2 }], @filters.sort(a: 1, b: 2) end def test_numerical_vs_lexicographical_sort @@ -330,7 +330,7 @@ class StandardFiltersTest < Minitest::Test foo = [ [1], [2], - [3] + [3], ] assert_raises Liquid::ArgumentError do @@ -346,7 +346,7 @@ class StandardFiltersTest < Minitest::Test foo = [ [1], [2], - [3] + [3], ] assert_raises Liquid::ArgumentError do @@ -380,7 +380,7 @@ class StandardFiltersTest < Minitest::Test def test_map_on_hashes assert_template_result "4217", '{{ thing | map: "foo" | map: "bar" }}', - "thing" => { "foo" => [ { "bar" => 42 }, { "bar" => 17 } ] } + "thing" => { "foo" => [{ "bar" => 42 }, { "bar" => 17 }] } end def test_legacy_map_on_hashes_with_dynamic_key @@ -397,7 +397,7 @@ class StandardFiltersTest < Minitest::Test def test_map_over_proc drop = TestDrop.new - p = proc{ drop } + p = proc { drop } templ = '{{ procs | map: "test" }}' assert_template_result "testfoo", templ, "procs" => [p] end @@ -405,10 +405,10 @@ class StandardFiltersTest < Minitest::Test def test_map_over_drops_returning_procs drops = [ { - "proc" => ->{ "foo" }, + "proc" => -> { "foo" }, }, { - "proc" => ->{ "bar" }, + "proc" => -> { "bar" }, }, ] templ = '{{ drops | map: "proc" }}' @@ -423,7 +423,7 @@ class StandardFiltersTest < Minitest::Test foo = [ [1], [2], - [3] + [3], ] assert_raises Liquid::ArgumentError do @@ -435,7 +435,7 @@ class StandardFiltersTest < Minitest::Test foo = [ [1], [2], - [3] + [3], ] assert_raises Liquid::ArgumentError do @filters.map(foo, nil) @@ -697,12 +697,12 @@ class StandardFiltersTest < Minitest::Test { "handle" => "alpha", "ok" => true }, { "handle" => "beta", "ok" => false }, { "handle" => "gamma", "ok" => false }, - { "handle" => "delta", "ok" => true } + { "handle" => "delta", "ok" => true }, ] expectation = [ { "handle" => "alpha", "ok" => true }, - { "handle" => "delta", "ok" => true } + { "handle" => "delta", "ok" => true }, ] assert_equal expectation, @filters.where(input, "ok", true) @@ -714,12 +714,12 @@ class StandardFiltersTest < Minitest::Test { "handle" => "alpha", "ok" => true }, { "handle" => "beta" }, { "handle" => "gamma" }, - { "handle" => "delta", "ok" => true } + { "handle" => "delta", "ok" => true }, ] expectation = [ { "handle" => "alpha", "ok" => true }, - { "handle" => "delta", "ok" => true } + { "handle" => "delta", "ok" => true }, ] assert_equal expectation, @filters.where(input, "ok", true) @@ -740,7 +740,7 @@ class StandardFiltersTest < Minitest::Test input = [ { "message" => "Bonjour!", "language" => "French" }, { "message" => "Hello!", "language" => "English" }, - { "message" => "Hallo!", "language" => "German" } + { "message" => "Hallo!", "language" => "German" }, ] assert_equal [{ "message" => "Bonjour!", "language" => "French" }], @filters.where(input, "language", "French") @@ -758,7 +758,7 @@ class StandardFiltersTest < Minitest::Test { "foo" => false }, { "foo" => true }, { "foo" => "for sure" }, - { "bar" => true } + { "bar" => true }, ] assert_equal [{ "foo" => true }, { "foo" => "for sure" }], @filters.where(input, "foo") diff --git a/test/integration/tags/echo_test.rb b/test/integration/tags/echo_test.rb index ed5b821d..eab329db 100644 --- a/test/integration/tags/echo_test.rb +++ b/test/integration/tags/echo_test.rb @@ -4,7 +4,7 @@ class EchoTest < Minitest::Test include Liquid def test_echo_outputs_its_input - assert_template_result('BAR', <<~LIQUID, { 'variable-name' => 'bar' }) + assert_template_result('BAR', <<~LIQUID, 'variable-name' => 'bar') {%- echo variable-name | upcase -%} LIQUID end diff --git a/test/integration/tags/for_tag_test.rb b/test/integration/tags/for_tag_test.rb index 9980e258..47e3e5f7 100644 --- a/test/integration/tags/for_tag_test.rb +++ b/test/integration/tags/for_tag_test.rb @@ -23,16 +23,16 @@ class ForTagTest < Minitest::Test yo HERE - template = < [1, 2, 3]) end def test_for_reversed - assigns = { 'array' => [ 1, 2, 3] } + assigns = { 'array' => [1, 2, 3] } assert_template_result('321', '{%for item in array reversed %}{{item}}{%endfor%}', assigns) end diff --git a/test/integration/tags/if_else_tag_test.rb b/test/integration/tags/if_else_tag_test.rb index 45a5d3ac..276b15b7 100644 --- a/test/integration/tags/if_else_tag_test.rb +++ b/test/integration/tags/if_else_tag_test.rb @@ -132,7 +132,7 @@ class IfElseTagTest < Minitest::Test end def test_syntax_error_no_variable - assert_raises(SyntaxError){ assert_template_result('', '{% if jerry == 1 %}') } + assert_raises(SyntaxError) { assert_template_result('', '{% if jerry == 1 %}') } end def test_syntax_error_no_expression diff --git a/test/integration/tags/include_tag_test.rb b/test/integration/tags/include_tag_test.rb index 14bb8c3a..dea932a0 100644 --- a/test/integration/tags/include_tag_test.rb +++ b/test/integration/tags/include_tag_test.rb @@ -40,14 +40,14 @@ class TestFileSystem end class OtherFileSystem - def read_template_file(template_path) + def read_template_file(_template_path) 'from OtherFileSystem' end end class CountingFileSystem attr_reader :count - def read_template_file(template_path) + def read_template_file(_template_path) @count ||= 0 @count += 1 'from CountingFileSystem' @@ -59,14 +59,14 @@ class CustomInclude < Liquid::Tag def initialize(tag_name, markup, tokens) markup =~ Syntax - @template_name = $1 + @template_name = Regexp.last_match(1) super end def parse(tokens) end - def render_to_output_buffer(context, output) + def render_to_output_buffer(_context, output) output << @template_name[1..-2] output end @@ -86,7 +86,7 @@ class IncludeTagTest < Minitest::Test def test_include_tag_with assert_template_result "Product: Draft 151cm ", - "{% include 'product' with products[0] %}", "products" => [ { 'title' => 'Draft 151cm' }, { 'title' => 'Element 155cm' } ] + "{% include 'product' with products[0] %}", "products" => [{ 'title' => 'Draft 151cm' }, { 'title' => 'Element 155cm' }] end def test_include_tag_with_default_name @@ -96,7 +96,7 @@ class IncludeTagTest < Minitest::Test def test_include_tag_for assert_template_result "Product: Draft 151cm Product: Element 155cm ", - "{% include 'product' for products %}", "products" => [ { 'title' => 'Draft 151cm' }, { 'title' => 'Element 155cm' } ] + "{% include 'product' for products %}", "products" => [{ 'title' => 'Draft 151cm' }, { 'title' => 'Element 155cm' }] end def test_include_tag_with_local_variables @@ -134,7 +134,7 @@ class IncludeTagTest < Minitest::Test def test_recursively_included_template_does_not_produce_endless_loop infinite_file_system = Class.new do - def read_template_file(template_path) + def read_template_file(_template_path) "-{% include 'loop' %}" end end diff --git a/test/integration/tags/increment_tag_test.rb b/test/integration/tags/increment_tag_test.rb index 97c51ac5..a793b6d2 100644 --- a/test/integration/tags/increment_tag_test.rb +++ b/test/integration/tags/increment_tag_test.rb @@ -13,11 +13,11 @@ class IncrementTagTest < Minitest::Test end def test_dec - assert_template_result('9', '{%decrement port %}', { 'port' => 10 }) + assert_template_result('9', '{%decrement port %}', 'port' => 10) assert_template_result('-1 -2', '{%decrement port %} {%decrement port%}', {}) assert_template_result('1 5 2 2 5', '{%increment port %} {%increment starboard%} ' \ '{%increment port %} {%decrement port%} ' \ - '{%decrement starboard %}', { 'port' => 1, 'starboard' => 5 }) + '{%decrement starboard %}', 'port' => 1, 'starboard' => 5) end end diff --git a/test/integration/tags/render_tag_test.rb b/test/integration/tags/render_tag_test.rb index a31d0182..ea144771 100644 --- a/test/integration/tags/render_tag_test.rb +++ b/test/integration/tags/render_tag_test.rb @@ -110,7 +110,7 @@ class RenderTagTest < Minitest::Test file_system = StubFileSystem.new('snippet' => 'echo') assert_equal 'echoecho', Template.parse('{% render "snippet" %}{% render "snippet" %}') - .render!({}, registers: { file_system: file_system }) + .render!({}, registers: { file_system: file_system }) assert_equal 1, file_system.file_read_count end diff --git a/test/integration/tags/standard_tag_test.rb b/test/integration/tags/standard_tag_test.rb index 4b4703a6..cee4caca 100644 --- a/test/integration/tags/standard_tag_test.rb +++ b/test/integration/tags/standard_tag_test.rb @@ -69,7 +69,7 @@ class StandardTagTest < Minitest::Test assert_raises(SyntaxError) do assert_template_result('content foo content foo ', '{{ var2 }}{% capture %}{{ var }} foo {% endcapture %}{{ var2 }}{{ var2 }}', - { 'var' => 'content' }) + 'var' => 'content') end end @@ -183,32 +183,32 @@ class StandardTagTest < Minitest::Test def test_case_when_or code = '{% case condition %}{% when 1 or 2 or 3 %} its 1 or 2 or 3 {% when 4 %} its 4 {% endcase %}' - assert_template_result(' its 1 or 2 or 3 ', code, { 'condition' => 1 }) - assert_template_result(' its 1 or 2 or 3 ', code, { 'condition' => 2 }) - assert_template_result(' its 1 or 2 or 3 ', code, { 'condition' => 3 }) - assert_template_result(' its 4 ', code, { 'condition' => 4 }) - assert_template_result('', code, { 'condition' => 5 }) + assert_template_result(' its 1 or 2 or 3 ', code, 'condition' => 1) + assert_template_result(' its 1 or 2 or 3 ', code, 'condition' => 2) + assert_template_result(' its 1 or 2 or 3 ', code, 'condition' => 3) + assert_template_result(' its 4 ', code, 'condition' => 4) + assert_template_result('', code, 'condition' => 5) code = '{% case condition %}{% when 1 or "string" or null %} its 1 or 2 or 3 {% when 4 %} its 4 {% endcase %}' - assert_template_result(' its 1 or 2 or 3 ', code, { 'condition' => 1 }) - assert_template_result(' its 1 or 2 or 3 ', code, { 'condition' => 'string' }) - assert_template_result(' its 1 or 2 or 3 ', code, { 'condition' => nil }) - assert_template_result('', code, { 'condition' => 'something else' }) + assert_template_result(' its 1 or 2 or 3 ', code, 'condition' => 1) + assert_template_result(' its 1 or 2 or 3 ', code, 'condition' => 'string') + assert_template_result(' its 1 or 2 or 3 ', code, 'condition' => nil) + assert_template_result('', code, 'condition' => 'something else') end def test_case_when_comma code = '{% case condition %}{% when 1, 2, 3 %} its 1 or 2 or 3 {% when 4 %} its 4 {% endcase %}' - assert_template_result(' its 1 or 2 or 3 ', code, { 'condition' => 1 }) - assert_template_result(' its 1 or 2 or 3 ', code, { 'condition' => 2 }) - assert_template_result(' its 1 or 2 or 3 ', code, { 'condition' => 3 }) - assert_template_result(' its 4 ', code, { 'condition' => 4 }) - assert_template_result('', code, { 'condition' => 5 }) + assert_template_result(' its 1 or 2 or 3 ', code, 'condition' => 1) + assert_template_result(' its 1 or 2 or 3 ', code, 'condition' => 2) + assert_template_result(' its 1 or 2 or 3 ', code, 'condition' => 3) + assert_template_result(' its 4 ', code, 'condition' => 4) + assert_template_result('', code, 'condition' => 5) code = '{% case condition %}{% when 1, "string", null %} its 1 or 2 or 3 {% when 4 %} its 4 {% endcase %}' - assert_template_result(' its 1 or 2 or 3 ', code, { 'condition' => 1 }) - assert_template_result(' its 1 or 2 or 3 ', code, { 'condition' => 'string' }) - assert_template_result(' its 1 or 2 or 3 ', code, { 'condition' => nil }) - assert_template_result('', code, { 'condition' => 'something else' }) + assert_template_result(' its 1 or 2 or 3 ', code, 'condition' => 1) + assert_template_result(' its 1 or 2 or 3 ', code, 'condition' => 'string') + assert_template_result(' its 1 or 2 or 3 ', code, 'condition' => nil) + assert_template_result('', code, 'condition' => 'something else') end def test_assign @@ -283,10 +283,10 @@ class StandardTagTest < Minitest::Test end def test_ifchanged - assigns = { 'array' => [ 1, 1, 2, 2, 3, 3] } + assigns = { 'array' => [1, 1, 2, 2, 3, 3] } assert_template_result('123', '{%for item in array%}{%ifchanged%}{{item}}{% endifchanged %}{%endfor%}', assigns) - assigns = { 'array' => [ 1, 1, 1, 1] } + assigns = { 'array' => [1, 1, 1, 1] } assert_template_result('1', '{%for item in array%}{%ifchanged%}{{item}}{% endifchanged %}{%endfor%}', assigns) end diff --git a/test/integration/template_test.rb b/test/integration/template_test.rb index 0dc0ae5f..e2b54c79 100644 --- a/test/integration/template_test.rb +++ b/test/integration/template_test.rb @@ -224,7 +224,7 @@ class TemplateTest < Minitest::Test end def test_render_bang_force_rethrow_errors_on_passed_context - context = Context.new({ 'drop' => ErroneousDrop.new }) + context = Context.new('drop' => ErroneousDrop.new) t = Template.new.parse('{{ drop.bad_method }}') e = assert_raises RuntimeError do @@ -267,7 +267,7 @@ class TemplateTest < Minitest::Test def test_undefined_variables t = Template.parse("{{x}} {{y}} {{z.a}} {{z.b}} {{z.c.d}}") - result = t.render({ 'x' => 33, 'z' => { 'a' => 32, 'c' => { 'e' => 31 } } }, { strict_variables: true }) + result = t.render({ 'x' => 33, 'z' => { 'a' => 32, 'c' => { 'e' => 31 } } }, strict_variables: true) assert_equal '33 32 ', result assert_equal 3, t.errors.count @@ -292,14 +292,14 @@ class TemplateTest < Minitest::Test t = Template.parse("{{x}} {{y}} {{z.a}} {{z.b}} {{z.c.d}}") assert_raises UndefinedVariable do - t.render!({ 'x' => 33, 'z' => { 'a' => 32, 'c' => { 'e' => 31 } } }, { strict_variables: true }) + t.render!({ 'x' => 33, 'z' => { 'a' => 32, 'c' => { 'e' => 31 } } }, strict_variables: true) end end def test_undefined_drop_methods d = DropWithUndefinedMethod.new t = Template.new.parse('{{ foo }} {{ woot }}') - result = t.render(d, { strict_variables: true }) + result = t.render(d, strict_variables: true) assert_equal 'foo ', result assert_equal 1, t.errors.count @@ -311,7 +311,7 @@ class TemplateTest < Minitest::Test t = Template.new.parse('{{ foo }} {{ woot }}') assert_raises UndefinedDropMethod do - t.render!(d, { strict_variables: true }) + t.render!(d, strict_variables: true) end end @@ -322,7 +322,7 @@ class TemplateTest < Minitest::Test "-#{v}-" end end - result = t.render({ 'a' => 123, 'x' => 'foo' }, { filters: [filters], strict_filters: true }) + result = t.render({ 'a' => 123, 'x' => 'foo' }, filters: [filters], strict_filters: true) assert_equal '123 ', result assert_equal 1, t.errors.count @@ -334,17 +334,17 @@ class TemplateTest < Minitest::Test t = Template.parse("{{x | somefilter1 | upcase | somefilter2}}") assert_raises UndefinedFilter do - t.render!({ 'x' => 'foo' }, { strict_filters: true }) + t.render!({ 'x' => 'foo' }, strict_filters: true) end end def test_using_range_literal_works_as_expected t = Template.parse("{% assign foo = (x..y) %}{{ foo }}") - result = t.render({ 'x' => 1, 'y' => 5 }) + result = t.render('x' => 1, 'y' => 5) assert_equal '1..5', result t = Template.parse("{% assign nums = (x..y) %}{% for num in nums %}{{ num }}{% endfor %}") - result = t.render({ 'x' => 1, 'y' => 5 }) + result = t.render('x' => 1, 'y' => 5) assert_equal '12345', result end end diff --git a/test/integration/trim_mode_test.rb b/test/integration/trim_mode_test.rb index 52248cff..4e35deee 100644 --- a/test/integration/trim_mode_test.rb +++ b/test/integration/trim_mode_test.rb @@ -76,14 +76,14 @@ class TrimModeTest < Minitest::Test

END_TEMPLATE - expected = <<-END_EXPECTED -
-

-#{whitespace} - yes -#{whitespace} -

-
+ expected = <<~END_EXPECTED +
+

+ #{whitespace} + yes + #{whitespace} +

+
END_EXPECTED assert_template_result(expected, text) @@ -96,12 +96,12 @@ class TrimModeTest < Minitest::Test

END_TEMPLATE - expected = <<-END_EXPECTED -
-

-#{whitespace} -

-
+ expected = <<~END_EXPECTED +
+

+ #{whitespace} +

+
END_EXPECTED assert_template_result(expected, text) end @@ -337,12 +337,12 @@ class TrimModeTest < Minitest::Test

END_TEMPLATE - expected = <<-END_EXPECTED -
-

-#{whitespace} -

-
+ expected = <<~END_EXPECTED +
+

+ #{whitespace} +

+
END_EXPECTED assert_template_result(expected, text) end @@ -513,16 +513,16 @@ class TrimModeTest < Minitest::Test {% endraw %} END_TEMPLATE - expected = <<-END_EXPECTED -
-#{whitespace} - {%- if true -%} -

- {{- 'John' -}} -

- {%- endif -%} -#{whitespace} -
+ expected = <<~END_EXPECTED +
+ #{whitespace} + {%- if true -%} +

+ {{- 'John' -}} +

+ {%- endif -%} + #{whitespace} +
END_EXPECTED assert_template_result(expected, text) end diff --git a/test/integration/variable_test.rb b/test/integration/variable_test.rb index abd6e70c..244ba95e 100644 --- a/test/integration/variable_test.rb +++ b/test/integration/variable_test.rb @@ -76,7 +76,7 @@ class VariableTest < Minitest::Test def test_hash_with_default_proc template = Template.parse(%(Hello {{ test }})) - assigns = Hash.new { |h, k| raise "Unknown variable '#{k}'" } + assigns = Hash.new { |_h, k| raise "Unknown variable '#{k}'" } assigns['test'] = 'Tobi' assert_equal 'Hello Tobi', template.render!(assigns) assigns.delete('test') diff --git a/test/test_helper.rb b/test/test_helper.rb index 27a24342..defc67ec 100755 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -41,7 +41,7 @@ module Minitest end def assert_template_result_matches(expected, template, assigns = {}, message = nil) - return assert_template_result(expected, template, assigns, message) unless expected.is_a? Regexp + return assert_template_result(expected, template, assigns, message) unless expected.is_a?(Regexp) assert_match expected, Template.parse(template, line_numbers: true).render!(assigns), message end diff --git a/test/unit/condition_unit_test.rb b/test/unit/condition_unit_test.rb index b3b90e88..165a7cf9 100644 --- a/test/unit/condition_unit_test.rb +++ b/test/unit/condition_unit_test.rb @@ -68,7 +68,7 @@ class ConditionUnitTest < Minitest::Test assert_nil Condition.new({}, '>', 2).evaluate assert_nil Condition.new(2, '>', {}).evaluate assert_equal false, Condition.new({}, '==', 2).evaluate - assert_equal true, Condition.new({ 'a' => 1 }, '==', { 'a' => 1 }).evaluate + assert_equal true, Condition.new({ 'a' => 1 }, '==', 'a' => 1).evaluate assert_equal true, Condition.new({ 'a' => 2 }, 'contains', 'a').evaluate end @@ -107,11 +107,11 @@ class ConditionUnitTest < Minitest::Test assert_equal false, condition.evaluate - condition.or Condition.new(2, '==', 1) + condition.or(Condition.new(2, '==', 1)) assert_equal false, condition.evaluate - condition.or Condition.new(1, '==', 1) + condition.or(Condition.new(1, '==', 1)) assert_equal true, condition.evaluate end @@ -121,22 +121,22 @@ class ConditionUnitTest < Minitest::Test assert_equal true, condition.evaluate - condition.and Condition.new(2, '==', 2) + condition.and(Condition.new(2, '==', 2)) assert_equal true, condition.evaluate - condition.and Condition.new(2, '==', 1) + condition.and(Condition.new(2, '==', 1)) assert_equal false, condition.evaluate end def test_should_allow_custom_proc_operator - Condition.operators['starts_with'] = proc { |cond, left, right| left =~ %r{^#{right}} } + Condition.operators['starts_with'] = proc { |_cond, left, right| left =~ /^#{right}/ } assert_evaluates_true 'bob', 'starts_with', 'b' assert_evaluates_false 'bob', 'starts_with', 'o' ensure - Condition.operators.delete 'starts_with' + Condition.operators.delete('starts_with') end def test_left_or_right_may_contain_operators diff --git a/test/unit/context_unit_test.rb b/test/unit/context_unit_test.rb index 9252eb52..6d7042c8 100644 --- a/test/unit/context_unit_test.rb +++ b/test/unit/context_unit_test.rb @@ -206,9 +206,9 @@ class ContextUnitTest < Minitest::Test end def test_merge - @context.merge({ "test" => "test" }) + @context.merge("test" => "test") assert_equal 'test', @context['test'] - @context.merge({ "test" => "newvalue", "foo" => "bar" }) + @context.merge("test" => "newvalue", "foo" => "bar") assert_equal 'newvalue', @context['test'] assert_equal 'bar', @context['foo'] end @@ -235,10 +235,10 @@ class ContextUnitTest < Minitest::Test def test_hash_to_array_transition @context['colors'] = { - 'Blue' => ['003366', '336699', '6699CC', '99CCFF'], - 'Green' => ['003300', '336633', '669966', '99CC99'], - 'Yellow' => ['CC9900', 'FFCC00', 'FFFF99', 'FFFFCC'], - 'Red' => ['660000', '993333', 'CC6666', 'FF9999'] + 'Blue' => ['003366', '336699', '6699CC', '99CCFF'], + 'Green' => ['003300', '336633', '669966', '99CC99'], + 'Yellow' => ['CC9900', 'FFCC00', 'FFFF99', 'FFFFCC'], + 'Red' => ['660000', '993333', 'CC6666', 'FF9999'], } assert_equal '003366', @context['colors.Blue[0]'] @@ -263,7 +263,7 @@ class ContextUnitTest < Minitest::Test def test_access_hashes_with_hash_notation @context['products'] = { 'count' => 5, 'tags' => ['deepsnow', 'freestyle'] } - @context['product'] = { 'variants' => [ { 'title' => 'draft151cm' }, { 'title' => 'element151cm' } ] } + @context['product'] = { 'variants' => [{ 'title' => 'draft151cm' }, { 'title' => 'element151cm' }] } assert_equal 5, @context['products["count"]'] assert_equal 'deepsnow', @context['products["tags"][0]'] @@ -301,7 +301,7 @@ class ContextUnitTest < Minitest::Test end def test_first_can_appear_in_middle_of_callchain - @context['product'] = { 'variants' => [ { 'title' => 'draft151cm' }, { 'title' => 'element151cm' } ] } + @context['product'] = { 'variants' => [{ 'title' => 'draft151cm' }, { 'title' => 'element151cm' }] } assert_equal 'draft151cm', @context['product.variants[0].title'] assert_equal 'element151cm', @context['product.variants[1].title'] @@ -453,7 +453,7 @@ class ContextUnitTest < Minitest::Test end def test_context_initialization_with_a_proc_in_environment - contx = Context.new([test: ->(c) { c['poutine'] }], { test: :foo }) + contx = Context.new([test: ->(c) { c['poutine'] }], test: :foo) assert contx assert_nil contx['poutine'] @@ -514,7 +514,7 @@ class ContextUnitTest < Minitest::Test def test_new_isolated_subcontext_does_not_inherit_non_static_registers registers = { - my_register: :my_value + my_register: :my_value, } super_context = Context.new({}, {}, registers) subcontext = super_context.new_isolated_subcontext diff --git a/test/unit/partial_cache_unit_test.rb b/test/unit/partial_cache_unit_test.rb index 29f11449..5778efb5 100644 --- a/test/unit/partial_cache_unit_test.rb +++ b/test/unit/partial_cache_unit_test.rb @@ -4,7 +4,7 @@ class PartialCacheUnitTest < Minitest::Test def test_uses_the_file_system_register_if_present context = Liquid::Context.build( registers: { - file_system: StubFileSystem.new('my_partial' => 'my partial body') + file_system: StubFileSystem.new('my_partial' => 'my partial body'), } ) @@ -41,12 +41,12 @@ class PartialCacheUnitTest < Minitest::Test ) context_one = Liquid::Context.build( registers: { - file_system: shared_file_system + file_system: shared_file_system, } ) context_two = Liquid::Context.build( registers: { - file_system: shared_file_system + file_system: shared_file_system, } ) diff --git a/test/unit/strainer_unit_test.rb b/test/unit/strainer_unit_test.rb index 5ce21004..5ae2660f 100644 --- a/test/unit/strainer_unit_test.rb +++ b/test/unit/strainer_unit_test.rb @@ -36,7 +36,8 @@ class StrainerUnitTest < Minitest::Test rescue Liquid::ArgumentError => e assert_match( /\ALiquid error: wrong number of arguments \((1 for 0|given 1, expected 0)\)\z/, - e.message) + e.message + ) assert_equal e.backtrace[0].split(':')[0], __FILE__ end end @@ -135,7 +136,7 @@ class StrainerUnitTest < Minitest::Test end module LateAddedFilter - def late_added_filter(input) + def late_added_filter(_input) "filtered" end end @@ -150,7 +151,7 @@ class StrainerUnitTest < Minitest::Test mod = Module.new do class << self attr_accessor :include_count - def included(mod) + def included(_mod) self.include_count += 1 end end diff --git a/test/unit/tags/if_tag_unit_test.rb b/test/unit/tags/if_tag_unit_test.rb index 7ecfc409..71408b3e 100644 --- a/test/unit/tags/if_tag_unit_test.rb +++ b/test/unit/tags/if_tag_unit_test.rb @@ -3,6 +3,6 @@ require 'test_helper' class IfTagUnitTest < Minitest::Test def test_if_nodelist template = Liquid::Template.parse('{% if true %}IF{% else %}ELSE{% endif %}') - assert_equal ['IF', 'ELSE'], template.root.nodelist[0].nodelist.map(&:nodelist).flatten + assert_equal(['IF', 'ELSE'], template.root.nodelist[0].nodelist.map(&:nodelist).flatten) end end From 604d899496a0c11ebf54465c68ef64ad5f2ac874 Mon Sep 17 00:00:00 2001 From: Mike Angell Date: Sat, 31 Aug 2019 22:48:25 +1000 Subject: [PATCH 04/21] Render tag styling fixes --- lib/liquid/tags/render.rb | 4 ++-- test/integration/tags/render_tag_test.rb | 2 +- test/unit/partial_cache_unit_test.rb | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/liquid/tags/render.rb b/lib/liquid/tags/render.rb index 2e5310b4..8f9a91c7 100644 --- a/lib/liquid/tags/render.rb +++ b/lib/liquid/tags/render.rb @@ -1,13 +1,13 @@ module Liquid class Render < Tag - Syntax = /(#{QuotedString})#{QuotedFragment}*/o + SYNTAX = /(#{QuotedString})#{QuotedFragment}*/o attr_reader :template_name_expr, :attributes def initialize(tag_name, markup, options) super - raise SyntaxError.new(options[:locale].t("errors.syntax.render".freeze)) unless markup =~ Syntax + raise SyntaxError.new(options[:locale].t("errors.syntax.render".freeze)) unless markup =~ SYNTAX template_name = $1 diff --git a/test/integration/tags/render_tag_test.rb b/test/integration/tags/render_tag_test.rb index a31d0182..ea144771 100644 --- a/test/integration/tags/render_tag_test.rb +++ b/test/integration/tags/render_tag_test.rb @@ -110,7 +110,7 @@ class RenderTagTest < Minitest::Test file_system = StubFileSystem.new('snippet' => 'echo') assert_equal 'echoecho', Template.parse('{% render "snippet" %}{% render "snippet" %}') - .render!({}, registers: { file_system: file_system }) + .render!({}, registers: { file_system: file_system }) assert_equal 1, file_system.file_read_count end diff --git a/test/unit/partial_cache_unit_test.rb b/test/unit/partial_cache_unit_test.rb index 29f11449..5778efb5 100644 --- a/test/unit/partial_cache_unit_test.rb +++ b/test/unit/partial_cache_unit_test.rb @@ -4,7 +4,7 @@ class PartialCacheUnitTest < Minitest::Test def test_uses_the_file_system_register_if_present context = Liquid::Context.build( registers: { - file_system: StubFileSystem.new('my_partial' => 'my partial body') + file_system: StubFileSystem.new('my_partial' => 'my partial body'), } ) @@ -41,12 +41,12 @@ class PartialCacheUnitTest < Minitest::Test ) context_one = Liquid::Context.build( registers: { - file_system: shared_file_system + file_system: shared_file_system, } ) context_two = Liquid::Context.build( registers: { - file_system: shared_file_system + file_system: shared_file_system, } ) From 806b2622da6acdfd236478a2e90bedf999868f8d Mon Sep 17 00:00:00 2001 From: Justin Li Date: Wed, 4 Sep 2019 15:12:51 -0400 Subject: [PATCH 05/21] Switch back to Liquid-C master, since https://github.com/Shopify/liquid-c/pull/50 is merged --- Gemfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile b/Gemfile index d77a7387..00c13263 100644 --- a/Gemfile +++ b/Gemfile @@ -20,6 +20,6 @@ group :test do gem 'rubocop-performance', require: false platform :mri, :truffleruby do - gem 'liquid-c', github: 'Shopify/liquid-c', ref: 'liquid-tag' + gem 'liquid-c', github: 'Shopify/liquid-c', ref: 'master' end end From b316ff8413a4d69b8a9443aa7430478e6b4c165f Mon Sep 17 00:00:00 2001 From: Mike Angell Date: Wed, 11 Sep 2019 04:20:34 +1000 Subject: [PATCH 06/21] Add usage tracking --- README.md | 6 ++++++ lib/liquid/standardfilters.rb | 1 + lib/liquid/usage.rb | 6 ++++++ 3 files changed, 13 insertions(+) create mode 100644 lib/liquid/usage.rb diff --git a/README.md b/README.md index 77e9ff43..75b1d5f6 100644 --- a/README.md +++ b/README.md @@ -106,3 +106,9 @@ template = Liquid::Template.parse("{{x}} {{y}}") template.render!({ 'x' => 1}, { strict_variables: true }) #=> Liquid::UndefinedVariable: Liquid error: undefined variable y ``` + +### Usage tracking + +To help determine if a feature or code path is used in production we have included opt-in usage tracking. To achieve this we provide an empty `Liquid::Usage.increment` method that can be implemented. This was designed to be paired with https://github.com/Shopify/statsd-instrument , however it's implementation is up to you. + +Once you have enabled usage tracking we recommend reporting any logged events through Github Issues that your system may be reporting. It is highly likely this event has been added to consider deprecating or improving code specific to this event, so please raise any concerns. diff --git a/lib/liquid/standardfilters.rb b/lib/liquid/standardfilters.rb index afcf479e..f0c98686 100644 --- a/lib/liquid/standardfilters.rb +++ b/lib/liquid/standardfilters.rb @@ -421,6 +421,7 @@ module Liquid def default(input, default_value = ''.freeze) if !input || input.respond_to?(:empty?) && input.empty? + Usage.increment("liquid.default_filter_received_false_value") if input == false # See https://github.com/Shopify/liquid/issues/1127 default_value else input diff --git a/lib/liquid/usage.rb b/lib/liquid/usage.rb new file mode 100644 index 00000000..4876ce93 --- /dev/null +++ b/lib/liquid/usage.rb @@ -0,0 +1,6 @@ +module Liquid + module Usage + def self.increment(name, sample_rate: 0.1, tags: {}) + end + end +end From b6547f322eb9d3b83908bc463dc3dd79e37cb3e4 Mon Sep 17 00:00:00 2001 From: Mike Angell Date: Wed, 11 Sep 2019 04:56:25 +1000 Subject: [PATCH 07/21] Simplify usage --- lib/liquid.rb | 1 + lib/liquid/standardfilters.rb | 2 +- lib/liquid/usage.rb | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/liquid.rb b/lib/liquid.rb index 0e198bb4..b98d4d96 100644 --- a/lib/liquid.rb +++ b/lib/liquid.rb @@ -75,6 +75,7 @@ require 'liquid/utils' require 'liquid/tokenizer' require 'liquid/parse_context' require 'liquid/partial_cache' +require 'liquid/usage' # Load all the tags of the standard library # diff --git a/lib/liquid/standardfilters.rb b/lib/liquid/standardfilters.rb index f0c98686..cf72dba2 100644 --- a/lib/liquid/standardfilters.rb +++ b/lib/liquid/standardfilters.rb @@ -421,7 +421,7 @@ module Liquid def default(input, default_value = ''.freeze) if !input || input.respond_to?(:empty?) && input.empty? - Usage.increment("liquid.default_filter_received_false_value") if input == false # See https://github.com/Shopify/liquid/issues/1127 + Usage.increment("default_filter_received_false_value") if input == false # See https://github.com/Shopify/liquid/issues/1127 default_value else input diff --git a/lib/liquid/usage.rb b/lib/liquid/usage.rb index 4876ce93..e3267ebe 100644 --- a/lib/liquid/usage.rb +++ b/lib/liquid/usage.rb @@ -1,6 +1,6 @@ module Liquid module Usage - def self.increment(name, sample_rate: 0.1, tags: {}) + def self.increment(name) end end end From 8318be2edc0c4a2aaf1a47085a7aa65950eb6c81 Mon Sep 17 00:00:00 2001 From: Mike Angell Date: Wed, 11 Sep 2019 05:20:05 +1000 Subject: [PATCH 08/21] Update readme --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 75b1d5f6..6802a717 100644 --- a/README.md +++ b/README.md @@ -109,6 +109,6 @@ template.render!({ 'x' => 1}, { strict_variables: true }) ### Usage tracking -To help determine if a feature or code path is used in production we have included opt-in usage tracking. To achieve this we provide an empty `Liquid::Usage.increment` method that can be implemented. This was designed to be paired with https://github.com/Shopify/statsd-instrument , however it's implementation is up to you. +To help track usages of a feature or code path in production, we have released opt-in usage tracking. To enable this, we provide an empty `Liquid:: Usage.increment` method which you can customize to your needs. The feature is well suited to https://github.com/Shopify/statsd-instrument. However, the choice of implementation is up to you. -Once you have enabled usage tracking we recommend reporting any logged events through Github Issues that your system may be reporting. It is highly likely this event has been added to consider deprecating or improving code specific to this event, so please raise any concerns. +Once you have enabled usage tracking, we recommend reporting any events through Github Issues that your system may be logging. It is highly likely this event has been added to consider deprecating or improving code specific to this event, so please raise any concerns. \ No newline at end of file From a5b387cdd4baaa04d205da4a218d1ce8ec637d34 Mon Sep 17 00:00:00 2001 From: Mike Angell Date: Wed, 11 Sep 2019 06:32:31 +1000 Subject: [PATCH 09/21] Remove reserved word Interrupt to avoid confusion Also resolves rubocop conflicts --- lib/liquid/interrupts.rb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/liquid/interrupts.rb b/lib/liquid/interrupts.rb index f3005e4c..48a820c7 100644 --- a/lib/liquid/interrupts.rb +++ b/lib/liquid/interrupts.rb @@ -1,6 +1,6 @@ module Liquid - # An interrupt is any command that breaks processing of a block (ex: a for loop). - class Interrupt + # A block interrupt is any command that breaks processing of a block (ex: a for loop). + class BlockInterrupt attr_reader :message def initialize(message = nil) @@ -9,8 +9,8 @@ module Liquid end # Interrupt that is thrown whenever a {% break %} is called. - class BreakInterrupt < RuntimeError; end + class BreakInterrupt < BlockInterrupt; end # Interrupt that is thrown whenever a {% continue %} is called. - class ContinueInterrupt < RuntimeError; end + class ContinueInterrupt < BlockInterrupt; end end From 724d02e9b3f94169252094cad962e56012329726 Mon Sep 17 00:00:00 2001 From: Mike Angell Date: Wed, 11 Sep 2019 06:35:08 +1000 Subject: [PATCH 10/21] Disable interrupt fix in this round --- .rubocop_todo.yml | 29 ++++++++++++++++++++++++++--- lib/liquid/interrupts.rb | 8 ++++---- 2 files changed, 30 insertions(+), 7 deletions(-) diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 0bd77b10..83ced97a 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -1,6 +1,6 @@ # This configuration was generated by # `rubocop --auto-gen-config` -# on 2019-08-31 21:54:20 +1000 using RuboCop version 0.74.0. +# on 2019-09-11 06:34:25 +1000 using RuboCop version 0.74.0. # The point is for the user to remove these configuration records # one by one as the offenses are removed from the code base. # Note that changes in the inspected code, or installation of new @@ -26,6 +26,14 @@ Lint/AssignmentInCondition: - 'test/test_helper.rb' - 'test/unit/tokenizer_unit_test.rb' +# Offense count: 2 +# Cop supports --auto-correct. +# Configuration parameters: EnforcedStyle. +# SupportedStyles: runtime_error, standard_error +Lint/InheritException: + Exclude: + - 'lib/liquid/interrupts.rb' + # Offense count: 2 Lint/UselessAssignment: Exclude: @@ -44,9 +52,24 @@ Lint/Void: Metrics/LineLength: Max: 294 -# Offense count: 45 +# Offense count: 44 Naming/ConstantName: - Enabled: false + Exclude: + - 'lib/liquid.rb' + - 'lib/liquid/block_body.rb' + - 'lib/liquid/tags/assign.rb' + - 'lib/liquid/tags/capture.rb' + - 'lib/liquid/tags/case.rb' + - 'lib/liquid/tags/cycle.rb' + - 'lib/liquid/tags/for.rb' + - 'lib/liquid/tags/if.rb' + - 'lib/liquid/tags/include.rb' + - 'lib/liquid/tags/raw.rb' + - 'lib/liquid/tags/table_row.rb' + - 'lib/liquid/variable.rb' + - 'performance/shopify/comment_form.rb' + - 'performance/shopify/paginate.rb' + - 'test/integration/tags/include_tag_test.rb' # Offense count: 5 Style/ClassVars: diff --git a/lib/liquid/interrupts.rb b/lib/liquid/interrupts.rb index 48a820c7..41359d78 100644 --- a/lib/liquid/interrupts.rb +++ b/lib/liquid/interrupts.rb @@ -1,6 +1,6 @@ module Liquid - # A block interrupt is any command that breaks processing of a block (ex: a for loop). - class BlockInterrupt + # An interrupt is any command that breaks processing of a block (ex: a for loop). + class Interrupt attr_reader :message def initialize(message = nil) @@ -9,8 +9,8 @@ module Liquid end # Interrupt that is thrown whenever a {% break %} is called. - class BreakInterrupt < BlockInterrupt; end + class BreakInterrupt < Interrupt; end # Interrupt that is thrown whenever a {% continue %} is called. - class ContinueInterrupt < BlockInterrupt; end + class ContinueInterrupt < Interrupt; end end From c0ffee59197cb3ab1609cbe61f6758269b6ad6ca Mon Sep 17 00:00:00 2001 From: Thierry Joyal Date: Thu, 12 Sep 2019 12:29:56 +0000 Subject: [PATCH 11/21] Invokable methods for enumerable reject include? --- lib/liquid/drop.rb | 2 +- test/integration/drop_test.rb | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/lib/liquid/drop.rb b/lib/liquid/drop.rb index 6b5aa993..1586c93e 100644 --- a/lib/liquid/drop.rb +++ b/lib/liquid/drop.rb @@ -67,7 +67,7 @@ module Liquid if include?(Enumerable) blacklist += Enumerable.public_instance_methods - blacklist -= [:sort, :count, :first, :min, :max, :include?] + blacklist -= [:sort, :count, :first, :min, :max] end whitelist = [:to_liquid] + (public_instance_methods - blacklist) diff --git a/test/integration/drop_test.rb b/test/integration/drop_test.rb index 2de4a5a1..5a2253b2 100644 --- a/test/integration/drop_test.rb +++ b/test/integration/drop_test.rb @@ -270,4 +270,11 @@ class DropsTest < Minitest::Test assert_equal 'ProductDrop', Liquid::Template.parse("{{ product }}").render!('product' => ProductDrop.new) assert_equal 'EnumerableDrop', Liquid::Template.parse('{{ collection }}').render!('collection' => EnumerableDrop.new) end + + def test_invokable_methods + assert_equal %w(to_liquid catchall user_input context texts).to_set, ProductDrop.invokable_methods + assert_equal %w(to_liquid scopes_as_array loop_pos scopes).to_set, ContextDrop.invokable_methods + assert_equal %w(to_liquid size max min first count).to_set, EnumerableDrop.invokable_methods + assert_equal %w(to_liquid max min sort count first).to_set, RealEnumerableDrop.invokable_methods + end end # DropsTest From 0d26f05bb83a72e9b737ebbd81008e5631c4e85f Mon Sep 17 00:00:00 2001 From: Mike Angell <53470248+shopmike@users.noreply.github.com> Date: Wed, 18 Sep 2019 13:19:45 +1000 Subject: [PATCH 12/21] Enabled frozen string literals (#1154) * Enabled frozen string literals * Update rubocop config * Prefer string interpolation in simple cases Co-Authored-By: Dylan Thacker-Smith --- .rubocop_todo.yml | 7 ---- Gemfile | 2 + Rakefile | 2 + example/server/example_servlet.rb | 2 + example/server/liquid_servlet.rb | 2 + example/server/server.rb | 2 + lib/liquid.rb | 10 +++-- lib/liquid/block.rb | 16 ++++---- lib/liquid/block_body.rb | 20 +++++----- lib/liquid/condition.rb | 20 +++++----- lib/liquid/context.rb | 4 +- lib/liquid/document.rb | 8 ++-- lib/liquid/drop.rb | 2 + lib/liquid/errors.rb | 6 ++- lib/liquid/expression.rb | 12 +++--- lib/liquid/extensions.rb | 2 + lib/liquid/file_system.rb | 6 ++- lib/liquid/forloop_drop.rb | 2 + lib/liquid/i18n.rb | 4 +- lib/liquid/interrupts.rb | 4 +- lib/liquid/lexer.rb | 22 ++++++----- lib/liquid/parse_context.rb | 2 + lib/liquid/parser.rb | 6 ++- lib/liquid/parser_switching.rb | 2 + lib/liquid/partial_cache.rb | 2 + lib/liquid/profiler.rb | 2 + lib/liquid/profiler/hooks.rb | 2 + lib/liquid/range_lookup.rb | 2 + lib/liquid/resource_limits.rb | 2 + lib/liquid/standardfilters.rb | 38 ++++++++++--------- lib/liquid/strainer.rb | 2 + lib/liquid/tablerowloop_drop.rb | 2 + lib/liquid/tag.rb | 4 +- lib/liquid/tags/assign.rb | 6 ++- lib/liquid/tags/break.rb | 4 +- lib/liquid/tags/capture.rb | 4 +- lib/liquid/tags/case.rb | 16 ++++---- lib/liquid/tags/comment.rb | 4 +- lib/liquid/tags/continue.rb | 4 +- lib/liquid/tags/cycle.rb | 4 +- lib/liquid/tags/decrement.rb | 4 +- lib/liquid/tags/echo.rb | 6 ++- lib/liquid/tags/for.rb | 24 ++++++------ lib/liquid/tags/if.rb | 18 +++++---- lib/liquid/tags/ifchanged.rb | 6 ++- lib/liquid/tags/include.rb | 8 ++-- lib/liquid/tags/increment.rb | 4 +- lib/liquid/tags/raw.rb | 12 +++--- lib/liquid/tags/render.rb | 6 ++- lib/liquid/tags/table_row.rb | 16 ++++---- lib/liquid/tags/unless.rb | 4 +- lib/liquid/template.rb | 6 ++- lib/liquid/tokenizer.rb | 2 + lib/liquid/usage.rb | 2 + lib/liquid/utils.rb | 4 +- lib/liquid/variable.rb | 2 + lib/liquid/variable_lookup.rb | 4 +- lib/liquid/version.rb | 3 +- liquid.gemspec | 1 + performance/benchmark.rb | 2 + performance/profile.rb | 2 + performance/shopify/comment_form.rb | 2 + performance/shopify/database.rb | 2 + performance/shopify/json_filter.rb | 2 + performance/shopify/liquid.rb | 2 + performance/shopify/money_filter.rb | 2 + performance/shopify/paginate.rb | 2 + performance/shopify/shop_filter.rb | 2 + performance/shopify/tag_filter.rb | 2 + performance/shopify/weight_filter.rb | 2 + performance/theme_runner.rb | 2 + test/integration/assign_test.rb | 2 + test/integration/blank_test.rb | 2 + test/integration/block_test.rb | 2 + test/integration/capture_test.rb | 2 + test/integration/context_test.rb | 2 + test/integration/document_test.rb | 2 + test/integration/drop_test.rb | 6 ++- test/integration/error_handling_test.rb | 2 + test/integration/filter_test.rb | 2 + test/integration/hash_ordering_test.rb | 2 + test/integration/output_test.rb | 2 + test/integration/parsing_quirks_test.rb | 2 + test/integration/render_profiling_test.rb | 2 + test/integration/security_test.rb | 2 + test/integration/standard_filter_test.rb | 1 + test/integration/tags/break_tag_test.rb | 2 + test/integration/tags/continue_tag_test.rb | 2 + test/integration/tags/echo_test.rb | 2 + test/integration/tags/for_tag_test.rb | 2 + test/integration/tags/if_else_tag_test.rb | 2 + test/integration/tags/include_tag_test.rb | 2 + test/integration/tags/increment_tag_test.rb | 2 + test/integration/tags/liquid_tag_test.rb | 2 + test/integration/tags/raw_tag_test.rb | 2 + test/integration/tags/render_tag_test.rb | 2 + test/integration/tags/standard_tag_test.rb | 2 + test/integration/tags/statements_test.rb | 2 + test/integration/tags/table_row_test.rb | 2 + test/integration/tags/unless_else_tag_test.rb | 2 + test/integration/template_test.rb | 2 + test/integration/trim_mode_test.rb | 2 + test/integration/variable_test.rb | 2 + test/test_helper.rb | 1 + test/unit/block_unit_test.rb | 6 ++- test/unit/condition_unit_test.rb | 2 + test/unit/context_unit_test.rb | 2 + test/unit/file_system_unit_test.rb | 2 + test/unit/i18n_unit_test.rb | 2 + test/unit/lexer_unit_test.rb | 2 + test/unit/parser_unit_test.rb | 2 + test/unit/partial_cache_unit_test.rb | 2 + test/unit/regexp_unit_test.rb | 2 + test/unit/strainer_unit_test.rb | 2 + test/unit/tag_unit_test.rb | 6 ++- test/unit/tags/case_tag_unit_test.rb | 2 + test/unit/tags/for_tag_unit_test.rb | 2 + test/unit/tags/if_tag_unit_test.rb | 2 + test/unit/template_unit_test.rb | 2 + test/unit/tokenizer_unit_test.rb | 2 + test/unit/variable_unit_test.rb | 2 + 121 files changed, 379 insertions(+), 150 deletions(-) diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 83ced97a..12716289 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -84,13 +84,6 @@ Style/DateTime: Exclude: - 'test/unit/context_unit_test.rb' -# Offense count: 119 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle. -# SupportedStyles: always, never -Style/FrozenStringLiteralComment: - Enabled: false - # Offense count: 9 # Cop supports --auto-correct. # Configuration parameters: AllowAsExpressionSeparator. diff --git a/Gemfile b/Gemfile index 00c13263..f5209346 100644 --- a/Gemfile +++ b/Gemfile @@ -1,3 +1,5 @@ +# frozen_string_literal: true + source 'https://rubygems.org' git_source(:github) do |repo_name| "https://github.com/#{repo_name}.git" diff --git a/Rakefile b/Rakefile index f2a0d07b..66ae0fae 100755 --- a/Rakefile +++ b/Rakefile @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'rake' require 'rake/testtask' $LOAD_PATH.unshift(File.expand_path("../lib", __FILE__)) diff --git a/example/server/example_servlet.rb b/example/server/example_servlet.rb index 9f8c58a8..b09e3bb7 100644 --- a/example/server/example_servlet.rb +++ b/example/server/example_servlet.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module ProductsFilter def price(integer) format("$%.2d USD", integer / 100.0) diff --git a/example/server/liquid_servlet.rb b/example/server/liquid_servlet.rb index 895f274a..55e21d21 100644 --- a/example/server/liquid_servlet.rb +++ b/example/server/liquid_servlet.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class LiquidServlet < WEBrick::HTTPServlet::AbstractServlet def do_GET(req, res) handle(:get, req, res) diff --git a/example/server/server.rb b/example/server/server.rb index f2f89a40..bb7a4bc9 100644 --- a/example/server/server.rb +++ b/example/server/server.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'webrick' require 'rexml/document' diff --git a/lib/liquid.rb b/lib/liquid.rb index b98d4d96..66895663 100644 --- a/lib/liquid.rb +++ b/lib/liquid.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Copyright (c) 2005 Tobias Luetke # # Permission is hereby granted, free of charge, to any person obtaining @@ -21,10 +23,10 @@ module Liquid FilterSeparator = /\|/ - ArgumentSeparator = ','.freeze - FilterArgumentSeparator = ':'.freeze - VariableAttributeSeparator = '.'.freeze - WhitespaceControl = '-'.freeze + ArgumentSeparator = ',' + FilterArgumentSeparator = ':' + VariableAttributeSeparator = '.' + WhitespaceControl = '-' TagStart = /\{\%/ TagEnd = /\%\}/ VariableSignature = /\(?[\w\-\.\[\]]\)?/ diff --git a/lib/liquid/block.rb b/lib/liquid/block.rb index 0036d7bf..f6698442 100644 --- a/lib/liquid/block.rb +++ b/lib/liquid/block.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Liquid class Block < Tag MAX_DEPTH = 100 @@ -27,16 +29,16 @@ module Liquid end def unknown_tag(tag, _params, _tokens) - if tag == 'else'.freeze - raise SyntaxError, parse_context.locale.t("errors.syntax.unexpected_else".freeze, + if tag == 'else' + raise SyntaxError, parse_context.locale.t("errors.syntax.unexpected_else", block_name: block_name) - elsif tag.start_with?('end'.freeze) - raise SyntaxError, parse_context.locale.t("errors.syntax.invalid_delimiter".freeze, + elsif tag.start_with?('end') + raise SyntaxError, parse_context.locale.t("errors.syntax.invalid_delimiter", tag: tag, block_name: block_name, block_delimiter: block_delimiter) else - raise SyntaxError, parse_context.locale.t("errors.syntax.unknown_tag".freeze, tag: tag) + raise SyntaxError, parse_context.locale.t("errors.syntax.unknown_tag", tag: tag) end end @@ -52,7 +54,7 @@ module Liquid def parse_body(body, tokens) if parse_context.depth >= MAX_DEPTH - raise StackLevelError, "Nesting too deep".freeze + raise StackLevelError, "Nesting too deep" end parse_context.depth += 1 begin @@ -61,7 +63,7 @@ module Liquid return false if end_tag_name == block_delimiter unless end_tag_name - raise SyntaxError, parse_context.locale.t("errors.syntax.tag_never_closed".freeze, block_name: block_name) + raise SyntaxError, parse_context.locale.t("errors.syntax.tag_never_closed", block_name: block_name) end # this tag is not registered with the system diff --git a/lib/liquid/block_body.rb b/lib/liquid/block_body.rb index a52eb620..c4ce2671 100644 --- a/lib/liquid/block_body.rb +++ b/lib/liquid/block_body.rb @@ -1,11 +1,13 @@ +# frozen_string_literal: true + module Liquid class BlockBody LiquidTagToken = /\A\s*(\w+)\s*(.*?)\z/o FullToken = /\A#{TagStart}#{WhitespaceControl}?(\s*)(\w+)(\s*)(.*?)#{WhitespaceControl}?#{TagEnd}\z/om ContentOfVariable = /\A#{VariableStart}#{WhitespaceControl}?(.*?)#{WhitespaceControl}?#{VariableEnd}\z/om WhitespaceOrNothing = /\A\s*\z/ - TAGSTART = "{%".freeze - VARSTART = "{{".freeze + TAGSTART = "{%" + VARSTART = "{{" attr_reader :nodelist @@ -64,10 +66,10 @@ module Liquid if parse_context.line_number # newlines inside the tag should increase the line number, # particularly important for multiline {% liquid %} tags - parse_context.line_number += Regexp.last_match(1).count("\n".freeze) + Regexp.last_match(3).count("\n".freeze) + parse_context.line_number += Regexp.last_match(1).count("\n") + Regexp.last_match(3).count("\n") end - if tag_name == 'liquid'.freeze + if tag_name == 'liquid' liquid_tag_tokenizer = Tokenizer.new(markup, line_number: parse_context.line_number, for_liquid_tag: true) next parse_for_liquid_tag(liquid_tag_tokenizer, parse_context, &block) end @@ -113,7 +115,7 @@ module Liquid end def render(context) - render_to_output_buffer(context, '') + render_to_output_buffer(context, +'') end def render_to_output_buffer(context, output) @@ -129,7 +131,7 @@ module Liquid when Variable render_node(context, output, node) when Block - render_node(context, node.blank? ? '' : output, node) + render_node(context, node.blank? ? +'' : output, node) break if context.interrupt? # might have happened in a for-block when Continue, Break # If we get an Interrupt that means the block must stop processing. An @@ -163,7 +165,7 @@ module Liquid def raise_if_resource_limits_reached(context, length) context.resource_limits.render_length += length return unless context.resource_limits.reached? - raise MemoryError, "Memory limits exceeded".freeze + raise MemoryError, "Memory limits exceeded" end def create_variable(token, parse_context) @@ -175,11 +177,11 @@ module Liquid end def raise_missing_tag_terminator(token, parse_context) - raise SyntaxError, parse_context.locale.t("errors.syntax.tag_termination".freeze, token: token, tag_end: TagEnd.inspect) + raise SyntaxError, parse_context.locale.t("errors.syntax.tag_termination", token: token, tag_end: TagEnd.inspect) end def raise_missing_variable_terminator(token, parse_context) - raise SyntaxError, parse_context.locale.t("errors.syntax.variable_termination".freeze, token: token, tag_end: VariableEnd.inspect) + raise SyntaxError, parse_context.locale.t("errors.syntax.variable_termination", token: token, tag_end: VariableEnd.inspect) end def registered_tags diff --git a/lib/liquid/condition.rb b/lib/liquid/condition.rb index c6e29ae0..93ec68b7 100644 --- a/lib/liquid/condition.rb +++ b/lib/liquid/condition.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Liquid # Container for liquid nodes which conveniently wraps decision making logic # @@ -8,14 +10,14 @@ module Liquid # class Condition #:nodoc: @@operators = { - '=='.freeze => ->(cond, left, right) { cond.send(:equal_variables, left, right) }, - '!='.freeze => ->(cond, left, right) { !cond.send(:equal_variables, left, right) }, - '<>'.freeze => ->(cond, left, right) { !cond.send(:equal_variables, left, right) }, - '<'.freeze => :<, - '>'.freeze => :>, - '>='.freeze => :>=, - '<='.freeze => :<=, - 'contains'.freeze => lambda do |_cond, left, right| + '==' => ->(cond, left, right) { cond.send(:equal_variables, left, right) }, + '!=' => ->(cond, left, right) { !cond.send(:equal_variables, left, right) }, + '<>' => ->(cond, left, right) { !cond.send(:equal_variables, left, right) }, + '<' => :<, + '>' => :>, + '>=' => :>=, + '<=' => :<=, + 'contains' => lambda do |_cond, left, right| if left && right && left.respond_to?(:include?) right = right.to_s if left.is_a?(String) left.include?(right) @@ -78,7 +80,7 @@ module Liquid end def inspect - "#" + "#" end protected diff --git a/lib/liquid/context.rb b/lib/liquid/context.rb index daae5deb..7e4350aa 100644 --- a/lib/liquid/context.rb +++ b/lib/liquid/context.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Liquid # Context keeps the variable stack and resolves variables, as well as keywords # @@ -232,7 +234,7 @@ module Liquid end def check_overflow - raise StackLevelError, "Nesting too deep".freeze if overflow? + raise StackLevelError, "Nesting too deep" if overflow? end def overflow? diff --git a/lib/liquid/document.rb b/lib/liquid/document.rb index afd4e998..e160886d 100644 --- a/lib/liquid/document.rb +++ b/lib/liquid/document.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Liquid class Document < BlockBody def self.parse(tokens, parse_context) @@ -17,10 +19,10 @@ module Liquid def unknown_tag(tag, parse_context) case tag - when 'else'.freeze, 'end'.freeze - raise SyntaxError, parse_context.locale.t("errors.syntax.unexpected_outer_tag".freeze, tag: tag) + when 'else', 'end' + raise SyntaxError, parse_context.locale.t("errors.syntax.unexpected_outer_tag", tag: tag) else - raise SyntaxError, parse_context.locale.t("errors.syntax.unknown_tag".freeze, tag: tag) + raise SyntaxError, parse_context.locale.t("errors.syntax.unknown_tag", tag: tag) end end end diff --git a/lib/liquid/drop.rb b/lib/liquid/drop.rb index 669eae6a..d4d8950f 100644 --- a/lib/liquid/drop.rb +++ b/lib/liquid/drop.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'set' module Liquid diff --git a/lib/liquid/errors.rb b/lib/liquid/errors.rb index 4239746f..eda0bd2a 100644 --- a/lib/liquid/errors.rb +++ b/lib/liquid/errors.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Liquid class Error < ::StandardError attr_accessor :line_number @@ -5,7 +7,7 @@ module Liquid attr_accessor :markup_context def to_s(with_prefix = true) - str = "" + str = +"" str << message_prefix if with_prefix str << super() @@ -20,7 +22,7 @@ module Liquid private def message_prefix - str = "" + str = +"" str << if is_a?(SyntaxError) "Liquid syntax error" else diff --git a/lib/liquid/expression.rb b/lib/liquid/expression.rb index 55681992..9670906b 100644 --- a/lib/liquid/expression.rb +++ b/lib/liquid/expression.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Liquid class Expression class MethodLiteral @@ -14,11 +16,11 @@ module Liquid end LITERALS = { - nil => nil, 'nil'.freeze => nil, 'null'.freeze => nil, ''.freeze => nil, - 'true'.freeze => true, - 'false'.freeze => false, - 'blank'.freeze => MethodLiteral.new(:blank?, '').freeze, - 'empty'.freeze => MethodLiteral.new(:empty?, '').freeze + nil => nil, 'nil' => nil, 'null' => nil, '' => nil, + 'true' => true, + 'false' => false, + 'blank' => MethodLiteral.new(:blank?, '').freeze, + 'empty' => MethodLiteral.new(:empty?, '').freeze }.freeze SINGLE_QUOTED_STRING = /\A'(.*)'\z/m diff --git a/lib/liquid/extensions.rb b/lib/liquid/extensions.rb index 09078193..d1854983 100644 --- a/lib/liquid/extensions.rb +++ b/lib/liquid/extensions.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'time' require 'date' diff --git a/lib/liquid/file_system.rb b/lib/liquid/file_system.rb index a2aa9b75..b2093aee 100644 --- a/lib/liquid/file_system.rb +++ b/lib/liquid/file_system.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Liquid # A Liquid file system is a way to let your templates retrieve other templates for use with the include tag. # @@ -44,7 +46,7 @@ module Liquid class LocalFileSystem attr_accessor :root - def initialize(root, pattern = "_%s.liquid".freeze) + def initialize(root, pattern = "_%s.liquid") @root = root @pattern = pattern end @@ -59,7 +61,7 @@ module Liquid def full_path(template_path) raise FileSystemError, "Illegal template name '#{template_path}'" unless template_path =~ %r{\A[^./][a-zA-Z0-9_/]+\z} - full_path = if template_path.include?('/'.freeze) + full_path = if template_path.include?('/') File.join(root, File.dirname(template_path), @pattern % File.basename(template_path)) else File.join(root, @pattern % template_path) diff --git a/lib/liquid/forloop_drop.rb b/lib/liquid/forloop_drop.rb index 81b2d1a2..0ffa2559 100644 --- a/lib/liquid/forloop_drop.rb +++ b/lib/liquid/forloop_drop.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Liquid class ForloopDrop < Drop def initialize(name, length, parentloop) diff --git a/lib/liquid/i18n.rb b/lib/liquid/i18n.rb index b2bb51ba..4a2885e8 100644 --- a/lib/liquid/i18n.rb +++ b/lib/liquid/i18n.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'yaml' module Liquid @@ -31,7 +33,7 @@ module Liquid end def deep_fetch_translation(name) - name.split('.'.freeze).reduce(locale) do |level, cur| + name.split('.').reduce(locale) do |level, cur| level[cur] || raise(TranslationError, "Translation for #{name} does not exist in locale #{path}") end end diff --git a/lib/liquid/interrupts.rb b/lib/liquid/interrupts.rb index 41359d78..28355b84 100644 --- a/lib/liquid/interrupts.rb +++ b/lib/liquid/interrupts.rb @@ -1,10 +1,12 @@ +# frozen_string_literal: true + module Liquid # An interrupt is any command that breaks processing of a block (ex: a for loop). class Interrupt attr_reader :message def initialize(message = nil) - @message = message || "interrupt".freeze + @message = message || "interrupt" end end diff --git a/lib/liquid/lexer.rb b/lib/liquid/lexer.rb index 367f99ee..04e0c116 100644 --- a/lib/liquid/lexer.rb +++ b/lib/liquid/lexer.rb @@ -1,17 +1,19 @@ +# frozen_string_literal: true + require "strscan" module Liquid class Lexer SPECIALS = { - '|'.freeze => :pipe, - '.'.freeze => :dot, - ':'.freeze => :colon, - ','.freeze => :comma, - '['.freeze => :open_square, - ']'.freeze => :close_square, - '('.freeze => :open_round, - ')'.freeze => :close_round, - '?'.freeze => :question, - '-'.freeze => :dash, + '|' => :pipe, + '.' => :dot, + ':' => :colon, + ',' => :comma, + '[' => :open_square, + ']' => :close_square, + '(' => :open_round, + ')' => :close_round, + '?' => :question, + '-' => :dash, }.freeze IDENTIFIER = /[a-zA-Z_][\w-]*\??/ SINGLE_STRING_LITERAL = /'[^\']*'/ diff --git a/lib/liquid/parse_context.rb b/lib/liquid/parse_context.rb index 58437f4d..2da3ad75 100644 --- a/lib/liquid/parse_context.rb +++ b/lib/liquid/parse_context.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Liquid class ParseContext attr_accessor :locale, :line_number, :trim_whitespace, :depth diff --git a/lib/liquid/parser.rb b/lib/liquid/parser.rb index c36de86f..6b9e8374 100644 --- a/lib/liquid/parser.rb +++ b/lib/liquid/parser.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Liquid class Parser def initialize(input) @@ -66,10 +68,10 @@ module Liquid end def argument - str = "" + str = +"" # might be a keyword argument (identifier: expression) if look(:id) && look(:colon, 1) - str << consume << consume << ' '.freeze + str << consume << consume << ' ' end str << expression diff --git a/lib/liquid/parser_switching.rb b/lib/liquid/parser_switching.rb index 3aa664ab..402b0566 100644 --- a/lib/liquid/parser_switching.rb +++ b/lib/liquid/parser_switching.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Liquid module ParserSwitching def parse_with_selected_parser(markup) diff --git a/lib/liquid/partial_cache.rb b/lib/liquid/partial_cache.rb index d0b88457..43c2e39b 100644 --- a/lib/liquid/partial_cache.rb +++ b/lib/liquid/partial_cache.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Liquid class PartialCache def self.load(template_name, context:, parse_context:) diff --git a/lib/liquid/profiler.rb b/lib/liquid/profiler.rb index dc9db60a..dc3f1db6 100644 --- a/lib/liquid/profiler.rb +++ b/lib/liquid/profiler.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'liquid/profiler/hooks' module Liquid diff --git a/lib/liquid/profiler/hooks.rb b/lib/liquid/profiler/hooks.rb index cda166b7..e7086533 100644 --- a/lib/liquid/profiler/hooks.rb +++ b/lib/liquid/profiler/hooks.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Liquid class BlockBody def render_node_with_profiling(context, output, node) diff --git a/lib/liquid/range_lookup.rb b/lib/liquid/range_lookup.rb index 93bb420c..8e4d7652 100644 --- a/lib/liquid/range_lookup.rb +++ b/lib/liquid/range_lookup.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Liquid class RangeLookup def self.parse(start_markup, end_markup) diff --git a/lib/liquid/resource_limits.rb b/lib/liquid/resource_limits.rb index 08b359ba..5b7e8e46 100644 --- a/lib/liquid/resource_limits.rb +++ b/lib/liquid/resource_limits.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Liquid class ResourceLimits attr_accessor :render_length, :render_score, :assign_score, diff --git a/lib/liquid/standardfilters.rb b/lib/liquid/standardfilters.rb index 45cf3a05..517857ac 100644 --- a/lib/liquid/standardfilters.rb +++ b/lib/liquid/standardfilters.rb @@ -1,14 +1,16 @@ +# frozen_string_literal: true + require 'cgi' require 'bigdecimal' module Liquid module StandardFilters HTML_ESCAPE = { - '&'.freeze => '&'.freeze, - '>'.freeze => '>'.freeze, - '<'.freeze => '<'.freeze, - '"'.freeze => '"'.freeze, - "'".freeze => '''.freeze, + '&' => '&', + '>' => '>', + '<' => '<', + '"' => '"', + "'" => ''', }.freeze HTML_ESCAPE_ONCE_REGEXP = /["><']|&(?!([a-zA-Z]+|(#\d+));)/ STRIP_HTML_BLOCKS = Regexp.union( @@ -72,7 +74,7 @@ module Liquid end # Truncate a string down to x characters - def truncate(input, length = 50, truncate_string = "...".freeze) + def truncate(input, length = 50, truncate_string = "...") return if input.nil? input_str = input.to_s length = Utils.to_integer(length) @@ -82,13 +84,13 @@ module Liquid input_str.length > length ? input_str[0...l].concat(truncate_string_str) : input_str end - def truncatewords(input, words = 15, truncate_string = "...".freeze) + def truncatewords(input, words = 15, truncate_string = "...") return if input.nil? wordlist = input.to_s.split words = Utils.to_integer(words) l = words - 1 l = 0 if l < 0 - wordlist.length > l ? wordlist[0..l].join(" ".freeze).concat(truncate_string.to_s) : input + wordlist.length > l ? wordlist[0..l].join(" ").concat(truncate_string.to_s) : input end # Split input string into an array of substrings separated by given pattern. @@ -113,7 +115,7 @@ module Liquid end def strip_html(input) - empty = ''.freeze + empty = '' result = input.to_s.gsub(STRIP_HTML_BLOCKS, empty) result.gsub!(STRIP_HTML_TAGS, empty) result @@ -121,11 +123,11 @@ module Liquid # Remove all newlines from the string def strip_newlines(input) - input.to_s.gsub(/\r?\n/, ''.freeze) + input.to_s.gsub(/\r?\n/, '') end # Join elements of the array with certain character between them - def join(input, glue = ' '.freeze) + def join(input, glue = ' ') InputIterator.new(input).join(glue) end @@ -220,7 +222,7 @@ module Liquid InputIterator.new(input).map do |e| e = e.call if e.is_a?(Proc) - if property == "to_liquid".freeze + if property == "to_liquid" e elsif e.respond_to?(:[]) r = e[property] @@ -250,23 +252,23 @@ module Liquid end # Replace occurrences of a string with another - def replace(input, string, replacement = ''.freeze) + def replace(input, string, replacement = '') input.to_s.gsub(string.to_s, replacement.to_s) end # Replace the first occurrences of a string with another - def replace_first(input, string, replacement = ''.freeze) + def replace_first(input, string, replacement = '') input.to_s.sub(string.to_s, replacement.to_s) end # remove a substring def remove(input, string) - input.to_s.gsub(string.to_s, ''.freeze) + input.to_s.gsub(string.to_s, '') end # remove the first occurrences of a substring def remove_first(input, string) - input.to_s.sub(string.to_s, ''.freeze) + input.to_s.sub(string.to_s, '') end # add one string to another @@ -288,7 +290,7 @@ module Liquid # Add
tags in front of all newlines in input string def newline_to_br(input) - input.to_s.gsub(/\n/, "
\n".freeze) + input.to_s.gsub(/\n/, "
\n") end # Reformat a date using Ruby's core Time#strftime( string ) -> string @@ -419,7 +421,7 @@ module Liquid result.is_a?(BigDecimal) ? result.to_f : result end - def default(input, default_value = ''.freeze) + def default(input, default_value = '') if !input || input.respond_to?(:empty?) && input.empty? Usage.increment("default_filter_received_false_value") if input == false # See https://github.com/Shopify/liquid/issues/1127 default_value diff --git a/lib/liquid/strainer.rb b/lib/liquid/strainer.rb index d885ae41..3f3417e3 100644 --- a/lib/liquid/strainer.rb +++ b/lib/liquid/strainer.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'set' module Liquid diff --git a/lib/liquid/tablerowloop_drop.rb b/lib/liquid/tablerowloop_drop.rb index cda4a1ed..0d00b6f1 100644 --- a/lib/liquid/tablerowloop_drop.rb +++ b/lib/liquid/tablerowloop_drop.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Liquid class TablerowloopDrop < Drop def initialize(length, cols) diff --git a/lib/liquid/tag.rb b/lib/liquid/tag.rb index 13b7e4bb..14606391 100644 --- a/lib/liquid/tag.rb +++ b/lib/liquid/tag.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Liquid class Tag attr_reader :nodelist, :tag_name, :line_number, :parse_context @@ -33,7 +35,7 @@ module Liquid end def render(_context) - ''.freeze + '' end # For backwards compatibility with custom tags. In a future release, the semantics diff --git a/lib/liquid/tags/assign.rb b/lib/liquid/tags/assign.rb index 6ff65d57..aaad14cf 100644 --- a/lib/liquid/tags/assign.rb +++ b/lib/liquid/tags/assign.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Liquid # Assign sets a variable in your template. # @@ -11,7 +13,7 @@ module Liquid Syntax = /(#{VariableSignature}+)\s*=\s*(.*)\s*/om def self.syntax_error_translation_key - "errors.syntax.assign".freeze + "errors.syntax.assign" end attr_reader :to, :from @@ -59,5 +61,5 @@ module Liquid end end - Template.register_tag('assign'.freeze, Assign) + Template.register_tag('assign', Assign) end diff --git a/lib/liquid/tags/break.rb b/lib/liquid/tags/break.rb index 6fe0969b..80f46278 100644 --- a/lib/liquid/tags/break.rb +++ b/lib/liquid/tags/break.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Liquid # Break tag to be used to break out of a for loop. # @@ -14,5 +16,5 @@ module Liquid end end - Template.register_tag('break'.freeze, Break) + Template.register_tag('break', Break) end diff --git a/lib/liquid/tags/capture.rb b/lib/liquid/tags/capture.rb index a97e42a1..1cace9c1 100644 --- a/lib/liquid/tags/capture.rb +++ b/lib/liquid/tags/capture.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Liquid # Capture stores the result of a block into a variable without rendering it inplace. # @@ -35,5 +37,5 @@ module Liquid end end - Template.register_tag('capture'.freeze, Capture) + Template.register_tag('capture', Capture) end diff --git a/lib/liquid/tags/case.rb b/lib/liquid/tags/case.rb index 2a72a185..30484c6d 100644 --- a/lib/liquid/tags/case.rb +++ b/lib/liquid/tags/case.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Liquid class Case < Block Syntax = /(#{QuotedFragment})/o @@ -12,7 +14,7 @@ module Liquid if markup =~ Syntax @left = Expression.parse(Regexp.last_match(1)) else - raise SyntaxError, options[:locale].t("errors.syntax.case".freeze) + raise SyntaxError, options[:locale].t("errors.syntax.case") end end @@ -27,9 +29,9 @@ module Liquid def unknown_tag(tag, markup, tokens) case tag - when 'when'.freeze + when 'when' record_when_condition(markup) - when 'else'.freeze + when 'else' record_else_condition(markup) else super @@ -58,12 +60,12 @@ module Liquid while markup unless markup =~ WhenSyntax - raise SyntaxError, options[:locale].t("errors.syntax.case_invalid_when".freeze) + raise SyntaxError, options[:locale].t("errors.syntax.case_invalid_when") end markup = Regexp.last_match(2) - block = Condition.new(@left, '=='.freeze, Expression.parse(Regexp.last_match(1))) + block = Condition.new(@left, '==', Expression.parse(Regexp.last_match(1))) block.attach(body) @blocks << block end @@ -71,7 +73,7 @@ module Liquid def record_else_condition(markup) unless markup.strip.empty? - raise SyntaxError, options[:locale].t("errors.syntax.case_invalid_else".freeze) + raise SyntaxError, options[:locale].t("errors.syntax.case_invalid_else") end block = ElseCondition.new @@ -86,5 +88,5 @@ module Liquid end end - Template.register_tag('case'.freeze, Case) + Template.register_tag('case', Case) end diff --git a/lib/liquid/tags/comment.rb b/lib/liquid/tags/comment.rb index cad3931e..a5460f99 100644 --- a/lib/liquid/tags/comment.rb +++ b/lib/liquid/tags/comment.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Liquid class Comment < Block def render_to_output_buffer(_context, output) @@ -12,5 +14,5 @@ module Liquid end end - Template.register_tag('comment'.freeze, Comment) + Template.register_tag('comment', Comment) end diff --git a/lib/liquid/tags/continue.rb b/lib/liquid/tags/continue.rb index 9c81ec2c..fb1f371e 100644 --- a/lib/liquid/tags/continue.rb +++ b/lib/liquid/tags/continue.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Liquid # Continue tag to be used to break out of a for loop. # @@ -14,5 +16,5 @@ module Liquid end end - Template.register_tag('continue'.freeze, Continue) + Template.register_tag('continue', Continue) end diff --git a/lib/liquid/tags/cycle.rb b/lib/liquid/tags/cycle.rb index adc6e3de..b203c785 100644 --- a/lib/liquid/tags/cycle.rb +++ b/lib/liquid/tags/cycle.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Liquid # Cycle is usually used within a loop to alternate between values, like colors or DOM classes. # @@ -27,7 +29,7 @@ module Liquid @variables = variables_from_string(markup) @name = @variables.to_s else - raise SyntaxError, options[:locale].t("errors.syntax.cycle".freeze) + raise SyntaxError, options[:locale].t("errors.syntax.cycle") end end diff --git a/lib/liquid/tags/decrement.rb b/lib/liquid/tags/decrement.rb index 08ddd4d6..d761a0c3 100644 --- a/lib/liquid/tags/decrement.rb +++ b/lib/liquid/tags/decrement.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Liquid # decrement is used in a place where one needs to insert a counter # into a template, and needs the counter to survive across @@ -32,5 +34,5 @@ module Liquid end end - Template.register_tag('decrement'.freeze, Decrement) + Template.register_tag('decrement', Decrement) end diff --git a/lib/liquid/tags/echo.rb b/lib/liquid/tags/echo.rb index d3d30e3b..1f789376 100644 --- a/lib/liquid/tags/echo.rb +++ b/lib/liquid/tags/echo.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Liquid # Echo outputs an expression # @@ -16,9 +18,9 @@ module Liquid end def render(context) - @variable.render_to_output_buffer(context, '') + @variable.render_to_output_buffer(context, +'') end end - Template.register_tag('echo'.freeze, Echo) + Template.register_tag('echo', Echo) end diff --git a/lib/liquid/tags/for.rb b/lib/liquid/tags/for.rb index f20953f8..d9613697 100644 --- a/lib/liquid/tags/for.rb +++ b/lib/liquid/tags/for.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Liquid # "For" iterates over an array or collection. # Several useful variables are available to you within the loop. @@ -66,7 +68,7 @@ module Liquid end def unknown_tag(tag, markup, tokens) - return super unless tag == 'else'.freeze + return super unless tag == 'else' @else_block = BlockBody.new end @@ -95,22 +97,22 @@ module Liquid set_attribute(key, value) end else - raise SyntaxError, options[:locale].t("errors.syntax.for".freeze) + raise SyntaxError, options[:locale].t("errors.syntax.for") end end def strict_parse(markup) p = Parser.new(markup) @variable_name = p.consume(:id) - raise SyntaxError, options[:locale].t("errors.syntax.for_invalid_in".freeze) unless p.id?('in'.freeze) + raise SyntaxError, options[:locale].t("errors.syntax.for_invalid_in") unless p.id?('in') collection_name = p.expression @name = "#{@variable_name}-#{collection_name}" @collection_name = Expression.parse(collection_name) - @reversed = p.id?('reversed'.freeze) + @reversed = p.id?('reversed') while p.look(:id) && p.look(:colon, 1) - unless attribute = p.id?('limit'.freeze) || p.id?('offset'.freeze) - raise SyntaxError, options[:locale].t("errors.syntax.for_invalid_attribute".freeze) + unless attribute = p.id?('limit') || p.id?('offset') + raise SyntaxError, options[:locale].t("errors.syntax.for_invalid_attribute") end p.consume set_attribute(attribute, p.expression) @@ -162,7 +164,7 @@ module Liquid for_stack.push(loop_vars) begin - context['forloop'.freeze] = loop_vars + context['forloop'] = loop_vars segment.each do |item| context[@variable_name] = item @@ -185,13 +187,13 @@ module Liquid def set_attribute(key, expr) case key - when 'offset'.freeze - @from = if expr == 'continue'.freeze + when 'offset' + @from = if expr == 'continue' :continue else Expression.parse(expr) end - when 'limit'.freeze + when 'limit' @limit = Expression.parse(expr) end end @@ -211,5 +213,5 @@ module Liquid end end - Template.register_tag('for'.freeze, For) + Template.register_tag('for', For) end diff --git a/lib/liquid/tags/if.rb b/lib/liquid/tags/if.rb index 1a313952..c3d1a777 100644 --- a/lib/liquid/tags/if.rb +++ b/lib/liquid/tags/if.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Liquid # If is the conditional block # @@ -19,7 +21,7 @@ module Liquid def initialize(tag_name, markup, options) super @blocks = [] - push_block('if'.freeze, markup) + push_block('if', markup) end def nodelist @@ -32,7 +34,7 @@ module Liquid end def unknown_tag(tag, markup, tokens) - if ['elsif'.freeze, 'else'.freeze].include?(tag) + if ['elsif', 'else'].include?(tag) push_block(tag, markup) else super @@ -52,7 +54,7 @@ module Liquid private def push_block(tag, markup) - block = if tag == 'else'.freeze + block = if tag == 'else' ElseCondition.new else parse_with_selected_parser(markup) @@ -64,17 +66,17 @@ module Liquid def lax_parse(markup) expressions = markup.scan(ExpressionsAndOperators) - raise SyntaxError, options[:locale].t("errors.syntax.if".freeze) unless expressions.pop =~ Syntax + raise SyntaxError, options[:locale].t("errors.syntax.if") unless expressions.pop =~ Syntax condition = Condition.new(Expression.parse(Regexp.last_match(1)), Regexp.last_match(2), Expression.parse(Regexp.last_match(3))) until expressions.empty? operator = expressions.pop.to_s.strip - raise SyntaxError, options[:locale].t("errors.syntax.if".freeze) unless expressions.pop.to_s =~ Syntax + raise SyntaxError, options[:locale].t("errors.syntax.if") unless expressions.pop.to_s =~ Syntax new_condition = Condition.new(Expression.parse(Regexp.last_match(1)), Regexp.last_match(2), Expression.parse(Regexp.last_match(3))) - raise SyntaxError, options[:locale].t("errors.syntax.if".freeze) unless BOOLEAN_OPERATORS.include?(operator) + raise SyntaxError, options[:locale].t("errors.syntax.if") unless BOOLEAN_OPERATORS.include?(operator) new_condition.send(operator, condition) condition = new_condition end @@ -92,7 +94,7 @@ module Liquid def parse_binary_comparisons(p) condition = parse_comparison(p) first_condition = condition - while op = (p.id?('and'.freeze) || p.id?('or'.freeze)) + while op = (p.id?('and') || p.id?('or')) child_condition = parse_comparison(p) condition.send(op, child_condition) condition = child_condition @@ -117,5 +119,5 @@ module Liquid end end - Template.register_tag('if'.freeze, If) + Template.register_tag('if', If) end diff --git a/lib/liquid/tags/ifchanged.rb b/lib/liquid/tags/ifchanged.rb index ddd276cf..dd3be532 100644 --- a/lib/liquid/tags/ifchanged.rb +++ b/lib/liquid/tags/ifchanged.rb @@ -1,7 +1,9 @@ +# frozen_string_literal: true + module Liquid class Ifchanged < Block def render_to_output_buffer(context, output) - block_output = '' + block_output = +'' super(context, block_output) if block_output != context.registers[:ifchanged] @@ -13,5 +15,5 @@ module Liquid end end - Template.register_tag('ifchanged'.freeze, Ifchanged) + Template.register_tag('ifchanged', Ifchanged) end diff --git a/lib/liquid/tags/include.rb b/lib/liquid/tags/include.rb index d2c6cd26..bbcfb1cc 100644 --- a/lib/liquid/tags/include.rb +++ b/lib/liquid/tags/include.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Liquid # Include allows templates to relate with other templates # @@ -35,7 +37,7 @@ module Liquid end else - raise SyntaxError, options[:locale].t("errors.syntax.include".freeze) + raise SyntaxError, options[:locale].t("errors.syntax.include") end end @@ -52,7 +54,7 @@ module Liquid parse_context: parse_context ) - context_variable_name = template_name.split('/'.freeze).last + context_variable_name = template_name.split('/').last variable = if @variable_name_expr context.evaluate(@variable_name_expr) @@ -101,5 +103,5 @@ module Liquid end end - Template.register_tag('include'.freeze, Include) + Template.register_tag('include', Include) end diff --git a/lib/liquid/tags/increment.rb b/lib/liquid/tags/increment.rb index 95875aa6..241b316b 100644 --- a/lib/liquid/tags/increment.rb +++ b/lib/liquid/tags/increment.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Liquid # increment is used in a place where one needs to insert a counter # into a template, and needs the counter to survive across @@ -29,5 +31,5 @@ module Liquid end end - Template.register_tag('increment'.freeze, Increment) + Template.register_tag('increment', Increment) end diff --git a/lib/liquid/tags/raw.rb b/lib/liquid/tags/raw.rb index 69910021..093a37e1 100644 --- a/lib/liquid/tags/raw.rb +++ b/lib/liquid/tags/raw.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Liquid class Raw < Block Syntax = /\A\s*\z/ @@ -10,16 +12,16 @@ module Liquid end def parse(tokens) - @body = '' + @body = +'' while token = tokens.shift if token =~ FullTokenPossiblyInvalid - @body << Regexp.last_match(1) if Regexp.last_match(1) != "".freeze + @body << Regexp.last_match(1) if Regexp.last_match(1) != "" return if block_delimiter == Regexp.last_match(2) end @body << token unless token.empty? end - raise SyntaxError, parse_context.locale.t("errors.syntax.tag_never_closed".freeze, block_name: block_name) + raise SyntaxError, parse_context.locale.t("errors.syntax.tag_never_closed", block_name: block_name) end def render_to_output_buffer(_context, output) @@ -39,10 +41,10 @@ module Liquid def ensure_valid_markup(tag_name, markup, parse_context) unless markup =~ Syntax - raise SyntaxError, parse_context.locale.t("errors.syntax.tag_unexpected_args".freeze, tag: tag_name) + raise SyntaxError, parse_context.locale.t("errors.syntax.tag_unexpected_args", tag: tag_name) end end end - Template.register_tag('raw'.freeze, Raw) + Template.register_tag('raw', Raw) end diff --git a/lib/liquid/tags/render.rb b/lib/liquid/tags/render.rb index d9b80028..e6c62232 100644 --- a/lib/liquid/tags/render.rb +++ b/lib/liquid/tags/render.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Liquid class Render < Tag SYNTAX = /(#{QuotedString})#{QuotedFragment}*/o @@ -7,7 +9,7 @@ module Liquid def initialize(tag_name, markup, options) super - raise SyntaxError, options[:locale].t("errors.syntax.render".freeze) unless markup =~ SYNTAX + raise SyntaxError, options[:locale].t("errors.syntax.render") unless markup =~ SYNTAX template_name = Regexp.last_match(1) @@ -50,5 +52,5 @@ module Liquid end end - Template.register_tag('render'.freeze, Render) + Template.register_tag('render', Render) end diff --git a/lib/liquid/tags/table_row.rb b/lib/liquid/tags/table_row.rb index 93935276..7c59bd32 100644 --- a/lib/liquid/tags/table_row.rb +++ b/lib/liquid/tags/table_row.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Liquid class TableRow < Block Syntax = /(\w+)\s+in\s+(#{QuotedFragment}+)/o @@ -14,26 +16,26 @@ module Liquid @attributes[key] = Expression.parse(value) end else - raise SyntaxError, options[:locale].t("errors.syntax.table_row".freeze) + raise SyntaxError, options[:locale].t("errors.syntax.table_row") end end def render_to_output_buffer(context, output) - (collection = context.evaluate(@collection_name)) || (return ''.freeze) + (collection = context.evaluate(@collection_name)) || (return '') - from = @attributes.key?('offset'.freeze) ? context.evaluate(@attributes['offset'.freeze]).to_i : 0 - to = @attributes.key?('limit'.freeze) ? from + context.evaluate(@attributes['limit'.freeze]).to_i : nil + from = @attributes.key?('offset') ? context.evaluate(@attributes['offset']).to_i : 0 + to = @attributes.key?('limit') ? from + context.evaluate(@attributes['limit']).to_i : nil collection = Utils.slice_collection(collection, from, to) length = collection.length - cols = context.evaluate(@attributes['cols'.freeze]).to_i + cols = context.evaluate(@attributes['cols']).to_i output << "\n" context.stack do tablerowloop = Liquid::TablerowloopDrop.new(length, cols) - context['tablerowloop'.freeze] = tablerowloop + context['tablerowloop'] = tablerowloop collection.each do |item| context[@variable_name] = item @@ -61,5 +63,5 @@ module Liquid end end - Template.register_tag('tablerow'.freeze, TableRow) + Template.register_tag('tablerow', TableRow) end diff --git a/lib/liquid/tags/unless.rb b/lib/liquid/tags/unless.rb index 32aa3a41..f67f57a9 100644 --- a/lib/liquid/tags/unless.rb +++ b/lib/liquid/tags/unless.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require_relative 'if' module Liquid @@ -24,5 +26,5 @@ module Liquid end end - Template.register_tag('unless'.freeze, Unless) + Template.register_tag('unless', Unless) end diff --git a/lib/liquid/template.rb b/lib/liquid/template.rb index 62250b28..e77ba8aa 100644 --- a/lib/liquid/template.rb +++ b/lib/liquid/template.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Liquid # Templates are central to liquid. # Interpretating templates is a two step process. First you compile the @@ -165,7 +167,7 @@ module Liquid # filters and tags and might be useful to integrate liquid more with its host application # def render(*args) - return ''.freeze if @root.nil? + return '' if @root.nil? context = case args.first when Liquid::Context @@ -208,7 +210,7 @@ module Liquid # render the nodelist. # for performance reasons we get an array back here. join will make a string out of it. with_profiling(context) do - @root.render_to_output_buffer(context, output || '') + @root.render_to_output_buffer(context, output || +'') end rescue Liquid::MemoryError => e context.handle_error(e) diff --git a/lib/liquid/tokenizer.rb b/lib/liquid/tokenizer.rb index 95114200..a89c7899 100644 --- a/lib/liquid/tokenizer.rb +++ b/lib/liquid/tokenizer.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Liquid class Tokenizer attr_reader :line_number, :for_liquid_tag diff --git a/lib/liquid/usage.rb b/lib/liquid/usage.rb index e3267ebe..141eccb9 100644 --- a/lib/liquid/usage.rb +++ b/lib/liquid/usage.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Liquid module Usage def self.increment(name) diff --git a/lib/liquid/utils.rb b/lib/liquid/utils.rb index ada4f396..406d667b 100644 --- a/lib/liquid/utils.rb +++ b/lib/liquid/utils.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Liquid module Utils def self.slice_collection(collection, from, to) @@ -69,7 +71,7 @@ module Liquid end case obj - when 'now'.freeze, 'today'.freeze + when 'now', 'today' Time.now when /\A\d+\z/, Integer Time.at(obj.to_i) diff --git a/lib/liquid/variable.rb b/lib/liquid/variable.rb index 6efcf705..2fc2ea85 100644 --- a/lib/liquid/variable.rb +++ b/lib/liquid/variable.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Liquid # Holds variables. Variables are only loaded "just in time" # and are not evaluated as part of the render stage diff --git a/lib/liquid/variable_lookup.rb b/lib/liquid/variable_lookup.rb index ab06bb62..112373d5 100644 --- a/lib/liquid/variable_lookup.rb +++ b/lib/liquid/variable_lookup.rb @@ -1,7 +1,9 @@ +# frozen_string_literal: true + module Liquid class VariableLookup SQUARE_BRACKETED = /\A\[(.*)\]\z/m - COMMAND_METHODS = ['size'.freeze, 'first'.freeze, 'last'.freeze].freeze + COMMAND_METHODS = ['size', 'first', 'last'].freeze attr_reader :name, :lookups diff --git a/lib/liquid/version.rb b/lib/liquid/version.rb index da01c476..9af29732 100644 --- a/lib/liquid/version.rb +++ b/lib/liquid/version.rb @@ -1,5 +1,6 @@ # encoding: utf-8 +# frozen_string_literal: true module Liquid - VERSION = "4.0.3".freeze + VERSION = "4.0.3" end diff --git a/liquid.gemspec b/liquid.gemspec index 27b24aae..54a11fb9 100644 --- a/liquid.gemspec +++ b/liquid.gemspec @@ -1,4 +1,5 @@ # encoding: utf-8 +# frozen_string_literal: true lib = File.expand_path('../lib/', __FILE__) $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) diff --git a/performance/benchmark.rb b/performance/benchmark.rb index 68c568c1..4d28b9ac 100644 --- a/performance/benchmark.rb +++ b/performance/benchmark.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'benchmark/ips' require_relative 'theme_runner' diff --git a/performance/profile.rb b/performance/profile.rb index c6fb1932..101f6e5d 100644 --- a/performance/profile.rb +++ b/performance/profile.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'stackprof' require_relative 'theme_runner' diff --git a/performance/shopify/comment_form.rb b/performance/shopify/comment_form.rb index 65af1b51..7648e1a4 100644 --- a/performance/shopify/comment_form.rb +++ b/performance/shopify/comment_form.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class CommentForm < Liquid::Block Syntax = /(#{Liquid::VariableSignature}+)/ diff --git a/performance/shopify/database.rb b/performance/shopify/database.rb index c9f18c30..9836cd46 100644 --- a/performance/shopify/database.rb +++ b/performance/shopify/database.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'yaml' module Database diff --git a/performance/shopify/json_filter.rb b/performance/shopify/json_filter.rb index 32583167..c7c25d8a 100644 --- a/performance/shopify/json_filter.rb +++ b/performance/shopify/json_filter.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'json' module JsonFilter diff --git a/performance/shopify/liquid.rb b/performance/shopify/liquid.rb index f9d52007..40444c3c 100644 --- a/performance/shopify/liquid.rb +++ b/performance/shopify/liquid.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + $LOAD_PATH.unshift(__dir__ + '/../../lib') require_relative '../../lib/liquid' diff --git a/performance/shopify/money_filter.rb b/performance/shopify/money_filter.rb index 4cc7280d..b0135e3e 100644 --- a/performance/shopify/money_filter.rb +++ b/performance/shopify/money_filter.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module MoneyFilter def money_with_currency(money) return '' if money.nil? diff --git a/performance/shopify/paginate.rb b/performance/shopify/paginate.rb index 29e7c9ee..f7238238 100644 --- a/performance/shopify/paginate.rb +++ b/performance/shopify/paginate.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Paginate < Liquid::Block Syntax = /(#{Liquid::QuotedFragment})\s*(by\s*(\d+))?/ diff --git a/performance/shopify/shop_filter.rb b/performance/shopify/shop_filter.rb index b2a0a9d0..9f0cdc2f 100644 --- a/performance/shopify/shop_filter.rb +++ b/performance/shopify/shop_filter.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module ShopFilter def asset_url(input) "/files/1/[shop_id]/[shop_id]/assets/#{input}" diff --git a/performance/shopify/tag_filter.rb b/performance/shopify/tag_filter.rb index 34b426f2..58f066be 100644 --- a/performance/shopify/tag_filter.rb +++ b/performance/shopify/tag_filter.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module TagFilter def link_to_tag(label, tag) "#{label}" diff --git a/performance/shopify/weight_filter.rb b/performance/shopify/weight_filter.rb index b05bcce1..6ba95f37 100644 --- a/performance/shopify/weight_filter.rb +++ b/performance/shopify/weight_filter.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module WeightFilter def weight(grams) format("%.2f", grams / 1000) diff --git a/performance/theme_runner.rb b/performance/theme_runner.rb index 9268558c..5ad01c55 100644 --- a/performance/theme_runner.rb +++ b/performance/theme_runner.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # This profiler run simulates Shopify. # We are looking in the tests directory for liquid files and render them within the designated layout file. # We will also export a substantial database to liquid which the templates can render values of. diff --git a/test/integration/assign_test.rb b/test/integration/assign_test.rb index 55022899..ffcb8a3f 100644 --- a/test/integration/assign_test.rb +++ b/test/integration/assign_test.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'test_helper' class AssignTest < Minitest::Test diff --git a/test/integration/blank_test.rb b/test/integration/blank_test.rb index 654ee987..f92490b2 100644 --- a/test/integration/blank_test.rb +++ b/test/integration/blank_test.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'test_helper' class FoobarTag < Liquid::Tag diff --git a/test/integration/block_test.rb b/test/integration/block_test.rb index 08245301..5603b53f 100644 --- a/test/integration/block_test.rb +++ b/test/integration/block_test.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'test_helper' class BlockTest < Minitest::Test diff --git a/test/integration/capture_test.rb b/test/integration/capture_test.rb index 8d965b35..f28e1b1b 100644 --- a/test/integration/capture_test.rb +++ b/test/integration/capture_test.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'test_helper' class CaptureTest < Minitest::Test diff --git a/test/integration/context_test.rb b/test/integration/context_test.rb index 2d109bb7..cd6d7a88 100644 --- a/test/integration/context_test.rb +++ b/test/integration/context_test.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'test_helper' class ContextTest < Minitest::Test diff --git a/test/integration/document_test.rb b/test/integration/document_test.rb index bcc4a21c..375ccfa7 100644 --- a/test/integration/document_test.rb +++ b/test/integration/document_test.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'test_helper' class DocumentTest < Minitest::Test diff --git a/test/integration/drop_test.rb b/test/integration/drop_test.rb index e5405599..3fe61750 100644 --- a/test/integration/drop_test.rb +++ b/test/integration/drop_test.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'test_helper' class ContextDrop < Liquid::Drop @@ -31,7 +33,7 @@ class ProductDrop < Liquid::Drop class CatchallDrop < Liquid::Drop def liquid_method_missing(method) - 'catchall_method: ' << method.to_s + "catchall_method: #{method}" end end @@ -48,7 +50,7 @@ class ProductDrop < Liquid::Drop end def user_input - "foo".taint + (+"foo").taint end protected diff --git a/test/integration/error_handling_test.rb b/test/integration/error_handling_test.rb index 875f4267..265632cb 100644 --- a/test/integration/error_handling_test.rb +++ b/test/integration/error_handling_test.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'test_helper' class ErrorHandlingTest < Minitest::Test diff --git a/test/integration/filter_test.rb b/test/integration/filter_test.rb index 0af29efb..270477e6 100644 --- a/test/integration/filter_test.rb +++ b/test/integration/filter_test.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'test_helper' module MoneyFilter diff --git a/test/integration/hash_ordering_test.rb b/test/integration/hash_ordering_test.rb index 8592395a..27d0b9b9 100644 --- a/test/integration/hash_ordering_test.rb +++ b/test/integration/hash_ordering_test.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'test_helper' class HashOrderingTest < Minitest::Test diff --git a/test/integration/output_test.rb b/test/integration/output_test.rb index d94b0f89..687cad87 100644 --- a/test/integration/output_test.rb +++ b/test/integration/output_test.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'test_helper' module FunnyFilter diff --git a/test/integration/parsing_quirks_test.rb b/test/integration/parsing_quirks_test.rb index 29cb6d6d..c210b486 100644 --- a/test/integration/parsing_quirks_test.rb +++ b/test/integration/parsing_quirks_test.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'test_helper' class ParsingQuirksTest < Minitest::Test diff --git a/test/integration/render_profiling_test.rb b/test/integration/render_profiling_test.rb index 283b8bdd..753b2be2 100644 --- a/test/integration/render_profiling_test.rb +++ b/test/integration/render_profiling_test.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'test_helper' class RenderProfilingTest < Minitest::Test diff --git a/test/integration/security_test.rb b/test/integration/security_test.rb index f603ff08..28e9d392 100644 --- a/test/integration/security_test.rb +++ b/test/integration/security_test.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'test_helper' module SecurityFilter diff --git a/test/integration/standard_filter_test.rb b/test/integration/standard_filter_test.rb index 7863cfeb..bf285399 100644 --- a/test/integration/standard_filter_test.rb +++ b/test/integration/standard_filter_test.rb @@ -1,4 +1,5 @@ # encoding: utf-8 +# frozen_string_literal: true require 'test_helper' diff --git a/test/integration/tags/break_tag_test.rb b/test/integration/tags/break_tag_test.rb index 0fbde837..c3a46791 100644 --- a/test/integration/tags/break_tag_test.rb +++ b/test/integration/tags/break_tag_test.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'test_helper' class BreakTagTest < Minitest::Test diff --git a/test/integration/tags/continue_tag_test.rb b/test/integration/tags/continue_tag_test.rb index ce4c158b..00cca17c 100644 --- a/test/integration/tags/continue_tag_test.rb +++ b/test/integration/tags/continue_tag_test.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'test_helper' class ContinueTagTest < Minitest::Test diff --git a/test/integration/tags/echo_test.rb b/test/integration/tags/echo_test.rb index eab329db..c64932e3 100644 --- a/test/integration/tags/echo_test.rb +++ b/test/integration/tags/echo_test.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'test_helper' class EchoTest < Minitest::Test diff --git a/test/integration/tags/for_tag_test.rb b/test/integration/tags/for_tag_test.rb index 47e3e5f7..667efac0 100644 --- a/test/integration/tags/for_tag_test.rb +++ b/test/integration/tags/for_tag_test.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'test_helper' class ThingWithValue < Liquid::Drop diff --git a/test/integration/tags/if_else_tag_test.rb b/test/integration/tags/if_else_tag_test.rb index 276b15b7..d54b2fb8 100644 --- a/test/integration/tags/if_else_tag_test.rb +++ b/test/integration/tags/if_else_tag_test.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'test_helper' class IfElseTagTest < Minitest::Test diff --git a/test/integration/tags/include_tag_test.rb b/test/integration/tags/include_tag_test.rb index dea932a0..45410a7a 100644 --- a/test/integration/tags/include_tag_test.rb +++ b/test/integration/tags/include_tag_test.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'test_helper' class TestFileSystem diff --git a/test/integration/tags/increment_tag_test.rb b/test/integration/tags/increment_tag_test.rb index a793b6d2..d561a1b5 100644 --- a/test/integration/tags/increment_tag_test.rb +++ b/test/integration/tags/increment_tag_test.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'test_helper' class IncrementTagTest < Minitest::Test diff --git a/test/integration/tags/liquid_tag_test.rb b/test/integration/tags/liquid_tag_test.rb index 628eb85e..b5f6b492 100644 --- a/test/integration/tags/liquid_tag_test.rb +++ b/test/integration/tags/liquid_tag_test.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'test_helper' class LiquidTagTest < Minitest::Test diff --git a/test/integration/tags/raw_tag_test.rb b/test/integration/tags/raw_tag_test.rb index 634d052d..461e5bfc 100644 --- a/test/integration/tags/raw_tag_test.rb +++ b/test/integration/tags/raw_tag_test.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'test_helper' class RawTagTest < Minitest::Test diff --git a/test/integration/tags/render_tag_test.rb b/test/integration/tags/render_tag_test.rb index ea144771..154783ad 100644 --- a/test/integration/tags/render_tag_test.rb +++ b/test/integration/tags/render_tag_test.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'test_helper' class RenderTagTest < Minitest::Test diff --git a/test/integration/tags/standard_tag_test.rb b/test/integration/tags/standard_tag_test.rb index cee4caca..7939cd36 100644 --- a/test/integration/tags/standard_tag_test.rb +++ b/test/integration/tags/standard_tag_test.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'test_helper' class StandardTagTest < Minitest::Test diff --git a/test/integration/tags/statements_test.rb b/test/integration/tags/statements_test.rb index eeff166f..0d024d0f 100644 --- a/test/integration/tags/statements_test.rb +++ b/test/integration/tags/statements_test.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'test_helper' class StatementsTest < Minitest::Test diff --git a/test/integration/tags/table_row_test.rb b/test/integration/tags/table_row_test.rb index d7bc14cf..71df4f38 100644 --- a/test/integration/tags/table_row_test.rb +++ b/test/integration/tags/table_row_test.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'test_helper' class TableRowTest < Minitest::Test diff --git a/test/integration/tags/unless_else_tag_test.rb b/test/integration/tags/unless_else_tag_test.rb index c414a715..469d1c0b 100644 --- a/test/integration/tags/unless_else_tag_test.rb +++ b/test/integration/tags/unless_else_tag_test.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'test_helper' class UnlessElseTagTest < Minitest::Test diff --git a/test/integration/template_test.rb b/test/integration/template_test.rb index e2b54c79..75dd95b4 100644 --- a/test/integration/template_test.rb +++ b/test/integration/template_test.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'test_helper' require 'timeout' diff --git a/test/integration/trim_mode_test.rb b/test/integration/trim_mode_test.rb index 4e35deee..438f86b5 100644 --- a/test/integration/trim_mode_test.rb +++ b/test/integration/trim_mode_test.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'test_helper' class TrimModeTest < Minitest::Test diff --git a/test/integration/variable_test.rb b/test/integration/variable_test.rb index 244ba95e..94ed1eca 100644 --- a/test/integration/variable_test.rb +++ b/test/integration/variable_test.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'test_helper' class VariableTest < Minitest::Test diff --git a/test/test_helper.rb b/test/test_helper.rb index defc67ec..d7a66413 100755 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -1,4 +1,5 @@ #!/usr/bin/env ruby +# frozen_string_literal: true ENV["MT_NO_EXPECTATIONS"] = "1" require 'minitest/autorun' diff --git a/test/unit/block_unit_test.rb b/test/unit/block_unit_test.rb index 9f7b94f8..fa06a877 100644 --- a/test/unit/block_unit_test.rb +++ b/test/unit/block_unit_test.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'test_helper' class BlockUnitTest < Minitest::Test @@ -61,7 +63,7 @@ class BlockUnitTest < Minitest::Test assert_equal 'hello', template.render - buf = '' + buf = +'' output = template.render({}, output: buf) assert_equal 'hello', output assert_equal 'hello', buf @@ -79,7 +81,7 @@ class BlockUnitTest < Minitest::Test assert_equal 'foohellobar', template.render - buf = '' + buf = +'' output = template.render({}, output: buf) assert_equal 'foohellobar', output assert_equal 'foohellobar', buf diff --git a/test/unit/condition_unit_test.rb b/test/unit/condition_unit_test.rb index 165a7cf9..69f6b902 100644 --- a/test/unit/condition_unit_test.rb +++ b/test/unit/condition_unit_test.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'test_helper' class ConditionUnitTest < Minitest::Test diff --git a/test/unit/context_unit_test.rb b/test/unit/context_unit_test.rb index 6d7042c8..67a8c916 100644 --- a/test/unit/context_unit_test.rb +++ b/test/unit/context_unit_test.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'test_helper' class HundredCentes diff --git a/test/unit/file_system_unit_test.rb b/test/unit/file_system_unit_test.rb index 2c7250ba..c76a7edd 100644 --- a/test/unit/file_system_unit_test.rb +++ b/test/unit/file_system_unit_test.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'test_helper' class FileSystemUnitTest < Minitest::Test diff --git a/test/unit/i18n_unit_test.rb b/test/unit/i18n_unit_test.rb index b57500e3..338787e3 100644 --- a/test/unit/i18n_unit_test.rb +++ b/test/unit/i18n_unit_test.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'test_helper' class I18nUnitTest < Minitest::Test diff --git a/test/unit/lexer_unit_test.rb b/test/unit/lexer_unit_test.rb index 5adcf2bd..7a2a4a56 100644 --- a/test/unit/lexer_unit_test.rb +++ b/test/unit/lexer_unit_test.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'test_helper' class LexerUnitTest < Minitest::Test diff --git a/test/unit/parser_unit_test.rb b/test/unit/parser_unit_test.rb index 9f23337a..7456bf30 100644 --- a/test/unit/parser_unit_test.rb +++ b/test/unit/parser_unit_test.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'test_helper' class ParserUnitTest < Minitest::Test diff --git a/test/unit/partial_cache_unit_test.rb b/test/unit/partial_cache_unit_test.rb index 5778efb5..dd431853 100644 --- a/test/unit/partial_cache_unit_test.rb +++ b/test/unit/partial_cache_unit_test.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'test_helper' class PartialCacheUnitTest < Minitest::Test diff --git a/test/unit/regexp_unit_test.rb b/test/unit/regexp_unit_test.rb index 0821229f..666bc664 100644 --- a/test/unit/regexp_unit_test.rb +++ b/test/unit/regexp_unit_test.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'test_helper' class RegexpUnitTest < Minitest::Test diff --git a/test/unit/strainer_unit_test.rb b/test/unit/strainer_unit_test.rb index 5ae2660f..2fb9ad44 100644 --- a/test/unit/strainer_unit_test.rb +++ b/test/unit/strainer_unit_test.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'test_helper' class StrainerUnitTest < Minitest::Test diff --git a/test/unit/tag_unit_test.rb b/test/unit/tag_unit_test.rb index a3fb40e3..c9543e92 100644 --- a/test/unit/tag_unit_test.rb +++ b/test/unit/tag_unit_test.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'test_helper' class TagUnitTest < Minitest::Test @@ -31,7 +33,7 @@ class TagUnitTest < Minitest::Test assert_equal 'hello', template.render - buf = '' + buf = +'' output = template.render({}, output: buf) assert_equal 'hello', output assert_equal 'hello', buf @@ -49,7 +51,7 @@ class TagUnitTest < Minitest::Test assert_equal 'foohellobar', template.render - buf = '' + buf = +'' output = template.render({}, output: buf) assert_equal 'foohellobar', output assert_equal 'foohellobar', buf diff --git a/test/unit/tags/case_tag_unit_test.rb b/test/unit/tags/case_tag_unit_test.rb index 71103081..0f3a61f7 100644 --- a/test/unit/tags/case_tag_unit_test.rb +++ b/test/unit/tags/case_tag_unit_test.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'test_helper' class CaseTagUnitTest < Minitest::Test diff --git a/test/unit/tags/for_tag_unit_test.rb b/test/unit/tags/for_tag_unit_test.rb index b8fc5206..e6306c3a 100644 --- a/test/unit/tags/for_tag_unit_test.rb +++ b/test/unit/tags/for_tag_unit_test.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'test_helper' class ForTagUnitTest < Minitest::Test diff --git a/test/unit/tags/if_tag_unit_test.rb b/test/unit/tags/if_tag_unit_test.rb index 71408b3e..32243b73 100644 --- a/test/unit/tags/if_tag_unit_test.rb +++ b/test/unit/tags/if_tag_unit_test.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'test_helper' class IfTagUnitTest < Minitest::Test diff --git a/test/unit/template_unit_test.rb b/test/unit/template_unit_test.rb index 6328be53..bc02896d 100644 --- a/test/unit/template_unit_test.rb +++ b/test/unit/template_unit_test.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'test_helper' class TemplateUnitTest < Minitest::Test diff --git a/test/unit/tokenizer_unit_test.rb b/test/unit/tokenizer_unit_test.rb index de84c1fb..d094aa1f 100644 --- a/test/unit/tokenizer_unit_test.rb +++ b/test/unit/tokenizer_unit_test.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'test_helper' class TokenizerTest < Minitest::Test diff --git a/test/unit/variable_unit_test.rb b/test/unit/variable_unit_test.rb index 5a21ace8..da1d4ea3 100644 --- a/test/unit/variable_unit_test.rb +++ b/test/unit/variable_unit_test.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'test_helper' class VariableUnitTest < Minitest::Test From d8403af515bfe929d616044f87e0e48a4fae6c2b Mon Sep 17 00:00:00 2001 From: Mike Angell <53470248+shopmike@users.noreply.github.com> Date: Wed, 18 Sep 2019 13:25:55 +1000 Subject: [PATCH 13/21] Reimplementation of Static Registers (#1157) --- lib/liquid.rb | 1 + lib/liquid/context.rb | 9 +- lib/liquid/static_registers.rb | 34 ++++ test/unit/context_unit_test.rb | 16 +- test/unit/static_registers_unit_test.rb | 209 ++++++++++++++++++++++++ 5 files changed, 260 insertions(+), 9 deletions(-) create mode 100644 lib/liquid/static_registers.rb create mode 100644 test/unit/static_registers_unit_test.rb diff --git a/lib/liquid.rb b/lib/liquid.rb index 66895663..d102530c 100644 --- a/lib/liquid.rb +++ b/lib/liquid.rb @@ -78,6 +78,7 @@ require 'liquid/tokenizer' require 'liquid/parse_context' require 'liquid/partial_cache' require 'liquid/usage' +require 'liquid/static_registers' # Load all the tags of the standard library # diff --git a/lib/liquid/context.rb b/lib/liquid/context.rb index 7e4350aa..88e46713 100644 --- a/lib/liquid/context.rb +++ b/lib/liquid/context.rb @@ -18,18 +18,17 @@ module Liquid attr_accessor :exception_renderer, :template_name, :partial, :global_filter, :strict_variables, :strict_filters # rubocop:disable Metrics/ParameterLists - def self.build(environments: {}, outer_scope: {}, registers: {}, rethrow_errors: false, resource_limits: nil, static_registers: {}, static_environments: {}) - new(environments, outer_scope, registers, rethrow_errors, resource_limits, static_registers, static_environments) + def self.build(environments: {}, outer_scope: {}, registers: {}, rethrow_errors: false, resource_limits: nil, static_environments: {}) + new(environments, outer_scope, registers, rethrow_errors, resource_limits, static_environments) end - def initialize(environments = {}, outer_scope = {}, registers = {}, rethrow_errors = false, resource_limits = nil, static_registers = {}, static_environments = {}) + def initialize(environments = {}, outer_scope = {}, registers = {}, rethrow_errors = false, resource_limits = nil, static_environments = {}) @environments = [environments] @environments.flatten! @static_environments = [static_environments].flat_map(&:freeze).freeze @scopes = [(outer_scope || {})] @registers = registers - @static_registers = static_registers.freeze @errors = [] @partial = false @strict_variables = false @@ -137,7 +136,7 @@ module Liquid Context.build( resource_limits: resource_limits, static_environments: static_environments, - static_registers: static_registers + registers: StaticRegisters.new(registers) ).tap do |subcontext| subcontext.base_scope_depth = base_scope_depth + 1 subcontext.exception_renderer = exception_renderer diff --git a/lib/liquid/static_registers.rb b/lib/liquid/static_registers.rb new file mode 100644 index 00000000..b05056d7 --- /dev/null +++ b/lib/liquid/static_registers.rb @@ -0,0 +1,34 @@ +module Liquid + class StaticRegisters + attr_reader :static_registers, :registers + + def initialize(registers = {}) + @static_registers = registers.is_a?(StaticRegisters) ? registers.static_registers : registers.freeze + @registers = {} + end + + def []=(key, value) + @registers[key] = value + end + + def [](key) + if @registers.key?(key) + @registers[key] + else + @static_registers[key] + end + end + + def delete(key) + @registers.delete(key) + end + + def fetch(key, default = nil) + key?(key) ? self[key] : default + end + + def key?(key) + @registers.key?(key) || @static_registers.key?(key) + end + end +end diff --git a/test/unit/context_unit_test.rb b/test/unit/context_unit_test.rb index 67a8c916..fe790cfb 100644 --- a/test/unit/context_unit_test.rb +++ b/test/unit/context_unit_test.rb @@ -518,15 +518,23 @@ class ContextUnitTest < Minitest::Test registers = { my_register: :my_value, } - super_context = Context.new({}, {}, registers) + super_context = Context.new({}, {}, StaticRegisters.new(registers)) + super_context.registers[:my_register] = :my_alt_value subcontext = super_context.new_isolated_subcontext - assert_nil subcontext.registers[:my_register] + assert_equal :my_value, subcontext.registers[:my_register] end def test_new_isolated_subcontext_inherits_static_registers - super_context = Context.build(static_registers: { my_register: :my_value }) + super_context = Context.build(registers: { my_register: :my_value }) subcontext = super_context.new_isolated_subcontext - assert_equal :my_value, subcontext.static_registers[:my_register] + assert_equal :my_value, subcontext.registers[:my_register] + end + + def test_new_isolated_subcontext_registers_do_not_pollute_context + super_context = Context.build(registers: { my_register: :my_value }) + subcontext = super_context.new_isolated_subcontext + subcontext.registers[:my_register] = :my_alt_value + assert_equal :my_value, super_context.registers[:my_register] end def test_new_isolated_subcontext_inherits_filters diff --git a/test/unit/static_registers_unit_test.rb b/test/unit/static_registers_unit_test.rb new file mode 100644 index 00000000..389cb3fb --- /dev/null +++ b/test/unit/static_registers_unit_test.rb @@ -0,0 +1,209 @@ +require 'test_helper' + +class StaticRegistersUnitTest < Minitest::Test + include Liquid + + def set + static_register = StaticRegisters.new + static_register[nil] = true + static_register[1] = :one + static_register[:one] = "one" + static_register["two"] = "three" + static_register["two"] = 3 + static_register[false] = nil + + assert_equal({ nil => true, 1 => :one, :one => "one", "two" => 3, false => nil }, static_register.registers) + + static_register + end + + def test_get + static_register = set + + assert_equal true, static_register[nil] + assert_equal :one, static_register[1] + assert_equal "one", static_register[:one] + assert_equal 3, static_register["two"] + assert_nil static_register[false] + assert_nil static_register["unknown"] + end + + def test_delete + static_register = set + + assert_equal true, static_register.delete(nil) + assert_equal :one, static_register.delete(1) + assert_equal "one", static_register.delete(:one) + assert_equal 3, static_register.delete("two") + assert_nil static_register.delete(false) + assert_nil static_register.delete("unknown") + + assert_equal({}, static_register.registers) + end + + def test_fetch + static_register = set + + assert_equal true, static_register.fetch(nil) + assert_equal :one, static_register.fetch(1) + assert_equal "one", static_register.fetch(:one) + assert_equal 3, static_register.fetch("two") + assert_nil static_register.fetch(false) + assert_nil static_register.fetch("unknown") + end + + def test_fetch_default + static_register = StaticRegisters.new + + assert_equal true, static_register.fetch(nil, true) + assert_equal :one, static_register.fetch(1, :one) + assert_equal "one", static_register.fetch(:one, "one") + assert_equal 3, static_register.fetch("two", 3) + assert_nil static_register.fetch(false, nil) + end + + def test_key + static_register = set + + assert_equal true, static_register.key?(nil) + assert_equal true, static_register.key?(1) + assert_equal true, static_register.key?(:one) + assert_equal true, static_register.key?("two") + assert_equal true, static_register.key?(false) + assert_equal false, static_register.key?("unknown") + assert_equal false, static_register.key?(true) + end + + def set_with_static + static_register = StaticRegisters.new(nil => true, 1 => :one, :one => "one", "two" => 3, false => nil) + static_register[nil] = false + static_register["two"] = 4 + static_register[true] = "foo" + + assert_equal({ nil => true, 1 => :one, :one => "one", "two" => 3, false => nil }, static_register.static_registers) + assert_equal({ nil => false, "two" => 4, true => "foo" }, static_register.registers) + + static_register + end + + def test_get_with_static + static_register = set_with_static + + assert_equal false, static_register[nil] + assert_equal :one, static_register[1] + assert_equal "one", static_register[:one] + assert_equal 4, static_register["two"] + assert_equal "foo", static_register[true] + assert_nil static_register[false] + end + + def test_delete_with_static + static_register = set_with_static + + assert_equal false, static_register.delete(nil) + assert_equal 4, static_register.delete("two") + assert_equal "foo", static_register.delete(true) + assert_nil static_register.delete("unknown") + assert_nil static_register.delete(:one) + + assert_equal({}, static_register.registers) + assert_equal({ nil => true, 1 => :one, :one => "one", "two" => 3, false => nil }, static_register.static_registers) + end + + def test_fetch_with_static + static_register = set_with_static + + assert_equal false, static_register.fetch(nil) + assert_equal :one, static_register.fetch(1) + assert_equal "one", static_register.fetch(:one) + assert_equal 4, static_register.fetch("two") + assert_equal "foo", static_register.fetch(true) + assert_nil static_register.fetch(false) + end + + def test_key_with_static + static_register = set_with_static + + assert_equal true, static_register.key?(nil) + assert_equal true, static_register.key?(1) + assert_equal true, static_register.key?(:one) + assert_equal true, static_register.key?("two") + assert_equal true, static_register.key?(false) + assert_equal false, static_register.key?("unknown") + assert_equal true, static_register.key?(true) + end + + def test_static_register_frozen + static_register = set_with_static + + static = static_register.static_registers + + assert_raises(RuntimeError) do + static["two"] = "foo" + end + + assert_raises(RuntimeError) do + static["unknown"] = "foo" + end + + assert_raises(RuntimeError) do + static.delete("two") + end + end + + def test_new_static_retains_static + static_register = StaticRegisters.new(nil => true, 1 => :one, :one => "one", "two" => 3, false => nil) + static_register["one"] = 1 + static_register["two"] = 2 + static_register["three"] = 3 + + new_register = StaticRegisters.new(static_register) + assert_equal({}, new_register.registers) + + new_register["one"] = 4 + new_register["two"] = 5 + new_register["three"] = 6 + + newest_register = StaticRegisters.new(new_register) + assert_equal({}, newest_register.registers) + + newest_register["one"] = 7 + newest_register["two"] = 8 + newest_register["three"] = 9 + + assert_equal({ "one" => 1, "two" => 2, "three" => 3 }, static_register.registers) + assert_equal({ "one" => 4, "two" => 5, "three" => 6 }, new_register.registers) + assert_equal({ "one" => 7, "two" => 8, "three" => 9 }, newest_register.registers) + assert_equal({ nil => true, 1 => :one, :one => "one", "two" => 3, false => nil }, static_register.static_registers) + assert_equal({ nil => true, 1 => :one, :one => "one", "two" => 3, false => nil }, new_register.static_registers) + assert_equal({ nil => true, 1 => :one, :one => "one", "two" => 3, false => nil }, newest_register.static_registers) + end + + def test_multiple_instances_are_unique + static_register = StaticRegisters.new(nil => true, 1 => :one, :one => "one", "two" => 3, false => nil) + static_register["one"] = 1 + static_register["two"] = 2 + static_register["three"] = 3 + + new_register = StaticRegisters.new(foo: :bar) + assert_equal({}, new_register.registers) + + new_register["one"] = 4 + new_register["two"] = 5 + new_register["three"] = 6 + + newest_register = StaticRegisters.new(bar: :foo) + assert_equal({}, newest_register.registers) + + newest_register["one"] = 7 + newest_register["two"] = 8 + newest_register["three"] = 9 + + assert_equal({ "one" => 1, "two" => 2, "three" => 3 }, static_register.registers) + assert_equal({ "one" => 4, "two" => 5, "three" => 6 }, new_register.registers) + assert_equal({ "one" => 7, "two" => 8, "three" => 9 }, newest_register.registers) + assert_equal({ nil => true, 1 => :one, :one => "one", "two" => 3, false => nil }, static_register.static_registers) + assert_equal({ foo: :bar }, new_register.static_registers) + assert_equal({ bar: :foo }, newest_register.static_registers) + end +end From adb40c41b7177fe0f84358ee50558126d1444214 Mon Sep 17 00:00:00 2001 From: Mike Angell <53470248+shopmike@users.noreply.github.com> Date: Wed, 18 Sep 2019 13:40:07 +1000 Subject: [PATCH 14/21] Enable frozen_string_literal --- lib/liquid/static_registers.rb | 2 ++ test/unit/static_registers_unit_test.rb | 2 ++ 2 files changed, 4 insertions(+) diff --git a/lib/liquid/static_registers.rb b/lib/liquid/static_registers.rb index b05056d7..6f22f705 100644 --- a/lib/liquid/static_registers.rb +++ b/lib/liquid/static_registers.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Liquid class StaticRegisters attr_reader :static_registers, :registers diff --git a/test/unit/static_registers_unit_test.rb b/test/unit/static_registers_unit_test.rb index 389cb3fb..0db80cdd 100644 --- a/test/unit/static_registers_unit_test.rb +++ b/test/unit/static_registers_unit_test.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'test_helper' class StaticRegistersUnitTest < Minitest::Test From ef133435913436c491f8dfddeb6ab56dedcd3c77 Mon Sep 17 00:00:00 2001 From: Mike Angell <53470248+shopmike@users.noreply.github.com> Date: Fri, 20 Sep 2019 00:24:48 +1000 Subject: [PATCH 15/21] Changes static registers to not be frozen (#1163) * Changes static registers to not be frozen * Add frozen test to static registers --- lib/liquid/static_registers.rb | 8 ++-- test/unit/static_registers_unit_test.rb | 57 ++++++++++++++++++++----- 2 files changed, 51 insertions(+), 14 deletions(-) diff --git a/lib/liquid/static_registers.rb b/lib/liquid/static_registers.rb index 6f22f705..06c52ab0 100644 --- a/lib/liquid/static_registers.rb +++ b/lib/liquid/static_registers.rb @@ -2,10 +2,10 @@ module Liquid class StaticRegisters - attr_reader :static_registers, :registers + attr_reader :static, :registers def initialize(registers = {}) - @static_registers = registers.is_a?(StaticRegisters) ? registers.static_registers : registers.freeze + @static = registers.is_a?(StaticRegisters) ? registers.static : registers @registers = {} end @@ -17,7 +17,7 @@ module Liquid if @registers.key?(key) @registers[key] else - @static_registers[key] + @static[key] end end @@ -30,7 +30,7 @@ module Liquid end def key?(key) - @registers.key?(key) || @static_registers.key?(key) + @registers.key?(key) || @static.key?(key) end end end diff --git a/test/unit/static_registers_unit_test.rb b/test/unit/static_registers_unit_test.rb index 0db80cdd..125440f2 100644 --- a/test/unit/static_registers_unit_test.rb +++ b/test/unit/static_registers_unit_test.rb @@ -82,7 +82,7 @@ class StaticRegistersUnitTest < Minitest::Test static_register["two"] = 4 static_register[true] = "foo" - assert_equal({ nil => true, 1 => :one, :one => "one", "two" => 3, false => nil }, static_register.static_registers) + assert_equal({ nil => true, 1 => :one, :one => "one", "two" => 3, false => nil }, static_register.static) assert_equal({ nil => false, "two" => 4, true => "foo" }, static_register.registers) static_register @@ -109,7 +109,7 @@ class StaticRegistersUnitTest < Minitest::Test assert_nil static_register.delete(:one) assert_equal({}, static_register.registers) - assert_equal({ nil => true, 1 => :one, :one => "one", "two" => 3, false => nil }, static_register.static_registers) + assert_equal({ nil => true, 1 => :one, :one => "one", "two" => 3, false => nil }, static_register.static) end def test_fetch_with_static @@ -135,10 +135,10 @@ class StaticRegistersUnitTest < Minitest::Test assert_equal true, static_register.key?(true) end - def test_static_register_frozen + def test_static_register_can_be_frozen static_register = set_with_static - static = static_register.static_registers + static = static_register.static.freeze assert_raises(RuntimeError) do static["two"] = "foo" @@ -176,9 +176,9 @@ class StaticRegistersUnitTest < Minitest::Test assert_equal({ "one" => 1, "two" => 2, "three" => 3 }, static_register.registers) assert_equal({ "one" => 4, "two" => 5, "three" => 6 }, new_register.registers) assert_equal({ "one" => 7, "two" => 8, "three" => 9 }, newest_register.registers) - assert_equal({ nil => true, 1 => :one, :one => "one", "two" => 3, false => nil }, static_register.static_registers) - assert_equal({ nil => true, 1 => :one, :one => "one", "two" => 3, false => nil }, new_register.static_registers) - assert_equal({ nil => true, 1 => :one, :one => "one", "two" => 3, false => nil }, newest_register.static_registers) + assert_equal({ nil => true, 1 => :one, :one => "one", "two" => 3, false => nil }, static_register.static) + assert_equal({ nil => true, 1 => :one, :one => "one", "two" => 3, false => nil }, new_register.static) + assert_equal({ nil => true, 1 => :one, :one => "one", "two" => 3, false => nil }, newest_register.static) end def test_multiple_instances_are_unique @@ -204,8 +204,45 @@ class StaticRegistersUnitTest < Minitest::Test assert_equal({ "one" => 1, "two" => 2, "three" => 3 }, static_register.registers) assert_equal({ "one" => 4, "two" => 5, "three" => 6 }, new_register.registers) assert_equal({ "one" => 7, "two" => 8, "three" => 9 }, newest_register.registers) - assert_equal({ nil => true, 1 => :one, :one => "one", "two" => 3, false => nil }, static_register.static_registers) - assert_equal({ foo: :bar }, new_register.static_registers) - assert_equal({ bar: :foo }, newest_register.static_registers) + assert_equal({ nil => true, 1 => :one, :one => "one", "two" => 3, false => nil }, static_register.static) + assert_equal({ foo: :bar }, new_register.static) + assert_equal({ bar: :foo }, newest_register.static) + end + + def test_can_update_static_directly_and_updates_all_instances + static_register = StaticRegisters.new(nil => true, 1 => :one, :one => "one", "two" => 3, false => nil) + static_register["one"] = 1 + static_register["two"] = 2 + static_register["three"] = 3 + + new_register = StaticRegisters.new(static_register) + assert_equal({}, new_register.registers) + + assert_equal({ nil => true, 1 => :one, :one => "one", "two" => 3, false => nil }, static_register.static) + + new_register["one"] = 4 + new_register["two"] = 5 + new_register["three"] = 6 + new_register.static["four"] = 10 + + newest_register = StaticRegisters.new(new_register) + assert_equal({}, newest_register.registers) + + assert_equal({ nil => true, 1 => :one, :one => "one", "two" => 3, false => nil, "four" => 10 }, new_register.static) + + newest_register["one"] = 7 + newest_register["two"] = 8 + newest_register["three"] = 9 + new_register.static["four"] = 5 + new_register.static["five"] = 15 + + assert_equal({ "one" => 1, "two" => 2, "three" => 3 }, static_register.registers) + assert_equal({ "one" => 4, "two" => 5, "three" => 6 }, new_register.registers) + assert_equal({ "one" => 7, "two" => 8, "three" => 9 }, newest_register.registers) + + assert_equal({ nil => true, 1 => :one, :one => "one", "two" => 3, false => nil, "four" => 5, "five" => 15 }, newest_register.static) + + assert_equal({ nil => true, 1 => :one, :one => "one", "two" => 3, false => nil, "four" => 5, "five" => 15 }, static_register.static) + assert_equal({ nil => true, 1 => :one, :one => "one", "two" => 3, false => nil, "four" => 5, "five" => 15 }, new_register.static) end end From ca207ed93f03c86f2cbcd348a25eaea6f5e7cd89 Mon Sep 17 00:00:00 2001 From: Ashwin Maroli Date: Thu, 19 Sep 2019 20:25:01 +0530 Subject: [PATCH 16/21] Cleanup RuboCop configuration file (#1161) --- .rubocop.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index 6b9aa9fe..b2316249 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -1,5 +1,5 @@ inherit_from: - - https://shopify.github.io/ruby-style-guide/rubocop.yml + - 'https://shopify.github.io/ruby-style-guide/rubocop.yml' - .rubocop_todo.yml require: rubocop-performance @@ -10,7 +10,7 @@ Performance: AllCops: Exclude: - 'vendor/bundle/**/*' - + Naming/MethodName: Exclude: - - 'example/server/liquid_servlet.rb' \ No newline at end of file + - 'example/server/liquid_servlet.rb' From 2c14e0b2ba0ce1a4f4b940175f1962a027ab77bd Mon Sep 17 00:00:00 2001 From: Ashwin Maroli Date: Thu, 19 Sep 2019 21:37:52 +0530 Subject: [PATCH 17/21] Use `Regexp#match?` when `MatchData` is not used (#1165) * Use `Regexp#match?` when `MatchData` is not used * Add `TargetRubyVersion: 2.4` to RuboCop config --- .rubocop.yml | 1 + lib/liquid/file_system.rb | 2 +- lib/liquid/tags/raw.rb | 2 +- lib/liquid/utils.rb | 2 +- 4 files changed, 4 insertions(+), 3 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index b2316249..1c0f8324 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -8,6 +8,7 @@ Performance: Enabled: true AllCops: + TargetRubyVersion: 2.4 Exclude: - 'vendor/bundle/**/*' diff --git a/lib/liquid/file_system.rb b/lib/liquid/file_system.rb index b2093aee..27ab6325 100644 --- a/lib/liquid/file_system.rb +++ b/lib/liquid/file_system.rb @@ -59,7 +59,7 @@ module Liquid end def full_path(template_path) - raise FileSystemError, "Illegal template name '#{template_path}'" unless template_path =~ %r{\A[^./][a-zA-Z0-9_/]+\z} + raise FileSystemError, "Illegal template name '#{template_path}'" unless %r{\A[^./][a-zA-Z0-9_/]+\z}.match?(template_path) full_path = if template_path.include?('/') File.join(root, File.dirname(template_path), @pattern % File.basename(template_path)) diff --git a/lib/liquid/tags/raw.rb b/lib/liquid/tags/raw.rb index 093a37e1..fde3ee10 100644 --- a/lib/liquid/tags/raw.rb +++ b/lib/liquid/tags/raw.rb @@ -40,7 +40,7 @@ module Liquid protected def ensure_valid_markup(tag_name, markup, parse_context) - unless markup =~ Syntax + unless Syntax.match?(markup) raise SyntaxError, parse_context.locale.t("errors.syntax.tag_unexpected_args", tag: tag_name) end end diff --git a/lib/liquid/utils.rb b/lib/liquid/utils.rb index 406d667b..709fb002 100644 --- a/lib/liquid/utils.rb +++ b/lib/liquid/utils.rb @@ -52,7 +52,7 @@ module Liquid when Numeric obj when String - obj.strip =~ /\A-?\d+\.\d+\z/ ? BigDecimal(obj) : obj.to_i + /\A-?\d+\.\d+\z/.match?(obj.strip) ? BigDecimal(obj) : obj.to_i else if obj.respond_to?(:to_number) obj.to_number From b667bcb48b26dab6c87827bd23ea99c6216bc7b4 Mon Sep 17 00:00:00 2001 From: Mike Angell <53470248+shopmike@users.noreply.github.com> Date: Fri, 20 Sep 2019 02:08:11 +1000 Subject: [PATCH 18/21] Shopify stye guide fixes (#1160) --- .rubocop_todo.yml | 48 +------------------------ lib/liquid/block_body.rb | 10 +++--- lib/liquid/lexer.rb | 20 +++++++---- lib/liquid/parse_context.rb | 1 - lib/liquid/standardfilters.rb | 2 +- lib/liquid/tags/for.rb | 2 +- lib/liquid/tags/if.rb | 4 +-- lib/liquid/tags/raw.rb | 2 +- lib/liquid/variable.rb | 2 +- performance/profile.rb | 2 +- performance/shopify/database.rb | 4 +-- test/integration/error_handling_test.rb | 10 ++++-- test/integration/template_test.rb | 20 ++++++++--- test/test_helper.rb | 2 +- test/unit/condition_unit_test.rb | 4 +-- test/unit/context_unit_test.rb | 20 ++++++++--- test/unit/tokenizer_unit_test.rb | 2 +- 17 files changed, 72 insertions(+), 83 deletions(-) diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 12716289..34a2e244 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -6,26 +6,6 @@ # Note that changes in the inspected code, or installation of new # versions of RuboCop, may require this file to be generated again. -# Offense count: 2 -Lint/AmbiguousOperator: - Exclude: - - 'test/unit/condition_unit_test.rb' - -# Offense count: 21 -# Configuration parameters: AllowSafeAssignment. -Lint/AssignmentInCondition: - Exclude: - - 'lib/liquid/block_body.rb' - - 'lib/liquid/lexer.rb' - - 'lib/liquid/standardfilters.rb' - - 'lib/liquid/tags/for.rb' - - 'lib/liquid/tags/if.rb' - - 'lib/liquid/tags/raw.rb' - - 'lib/liquid/variable.rb' - - 'performance/profile.rb' - - 'test/test_helper.rb' - - 'test/unit/tokenizer_unit_test.rb' - # Offense count: 2 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle. @@ -34,17 +14,6 @@ Lint/InheritException: Exclude: - 'lib/liquid/interrupts.rb' -# Offense count: 2 -Lint/UselessAssignment: - Exclude: - - 'performance/shopify/database.rb' - -# Offense count: 1 -# Configuration parameters: CheckForMethodsWithNoSideEffects. -Lint/Void: - Exclude: - - 'lib/liquid/parse_context.rb' - # Offense count: 98 # Cop supports --auto-correct. # Configuration parameters: AutoCorrect, AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, IgnoredPatterns. @@ -76,19 +45,4 @@ Style/ClassVars: Exclude: - 'lib/liquid/condition.rb' - 'lib/liquid/strainer.rb' - - 'lib/liquid/template.rb' - -# Offense count: 1 -# Configuration parameters: AllowCoercion. -Style/DateTime: - Exclude: - - 'test/unit/context_unit_test.rb' - -# Offense count: 9 -# Cop supports --auto-correct. -# Configuration parameters: AllowAsExpressionSeparator. -Style/Semicolon: - Exclude: - - 'test/integration/error_handling_test.rb' - - 'test/integration/template_test.rb' - - 'test/unit/context_unit_test.rb' + - 'lib/liquid/template.rb' \ No newline at end of file diff --git a/lib/liquid/block_body.rb b/lib/liquid/block_body.rb index c4ce2671..9400e383 100644 --- a/lib/liquid/block_body.rb +++ b/lib/liquid/block_body.rb @@ -27,7 +27,7 @@ module Liquid end private def parse_for_liquid_tag(tokenizer, parse_context) - while token = tokenizer.shift + while (token = tokenizer.shift) unless token.empty? || token =~ WhitespaceOrNothing unless token =~ LiquidTagToken # line isn't empty but didn't match tag syntax, yield and let the @@ -36,7 +36,7 @@ module Liquid end tag_name = Regexp.last_match(1) markup = Regexp.last_match(2) - unless tag = registered_tags[tag_name] + unless (tag = registered_tags[tag_name]) # end parsing if we reach an unknown tag and let the caller decide # determine how to proceed return yield tag_name, markup @@ -52,7 +52,7 @@ module Liquid end private def parse_for_document(tokenizer, parse_context, &block) - while token = tokenizer.shift + while (token = tokenizer.shift) next if token.empty? case when token.start_with?(TAGSTART) @@ -74,7 +74,7 @@ module Liquid next parse_for_liquid_tag(liquid_tag_tokenizer, parse_context, &block) end - unless tag = registered_tags[tag_name] + unless (tag = registered_tags[tag_name]) # end parsing if we reach an unknown tag and let the caller decide # determine how to proceed return yield tag_name, markup @@ -122,7 +122,7 @@ module Liquid context.resource_limits.render_score += @nodelist.length idx = 0 - while node = @nodelist[idx] + while (node = @nodelist[idx]) previous_output_size = output.bytesize case node diff --git a/lib/liquid/lexer.rb b/lib/liquid/lexer.rb index 04e0c116..a251c3e5 100644 --- a/lib/liquid/lexer.rb +++ b/lib/liquid/lexer.rb @@ -33,15 +33,21 @@ module Liquid until @ss.eos? @ss.skip(WHITESPACE_OR_NOTHING) break if @ss.eos? - tok = if t = @ss.scan(COMPARISON_OPERATOR) then [:comparison, t] - elsif t = @ss.scan(SINGLE_STRING_LITERAL) then [:string, t] - elsif t = @ss.scan(DOUBLE_STRING_LITERAL) then [:string, t] - elsif t = @ss.scan(NUMBER_LITERAL) then [:number, t] - elsif t = @ss.scan(IDENTIFIER) then [:id, t] - elsif t = @ss.scan(DOTDOT) then [:dotdot, t] + tok = if (t = @ss.scan(COMPARISON_OPERATOR)) + [:comparison, t] + elsif (t = @ss.scan(SINGLE_STRING_LITERAL)) + [:string, t] + elsif (t = @ss.scan(DOUBLE_STRING_LITERAL)) + [:string, t] + elsif (t = @ss.scan(NUMBER_LITERAL)) + [:number, t] + elsif (t = @ss.scan(IDENTIFIER)) + [:id, t] + elsif (t = @ss.scan(DOTDOT)) + [:dotdot, t] else c = @ss.getch - if s = SPECIALS[c] + if (s = SPECIALS[c]) [s, c] else raise SyntaxError, "Unexpected character #{c}" diff --git a/lib/liquid/parse_context.rb b/lib/liquid/parse_context.rb index 2da3ad75..4afdbe59 100644 --- a/lib/liquid/parse_context.rb +++ b/lib/liquid/parse_context.rb @@ -21,7 +21,6 @@ module Liquid @partial = value @options = value ? partial_options : @template_options @error_mode = @options[:error_mode] || Template.error_mode - value end def partial_options diff --git a/lib/liquid/standardfilters.rb b/lib/liquid/standardfilters.rb index 517857ac..6855cd21 100644 --- a/lib/liquid/standardfilters.rb +++ b/lib/liquid/standardfilters.rb @@ -327,7 +327,7 @@ module Liquid def date(input, format) return input if format.to_s.empty? - return input unless date = Utils.to_date(input) + return input unless (date = Utils.to_date(input)) date.strftime(format.to_s) end diff --git a/lib/liquid/tags/for.rb b/lib/liquid/tags/for.rb index d9613697..5c7b5601 100644 --- a/lib/liquid/tags/for.rb +++ b/lib/liquid/tags/for.rb @@ -111,7 +111,7 @@ module Liquid @reversed = p.id?('reversed') while p.look(:id) && p.look(:colon, 1) - unless attribute = p.id?('limit') || p.id?('offset') + unless (attribute = p.id?('limit') || p.id?('offset')) raise SyntaxError, options[:locale].t("errors.syntax.for_invalid_attribute") end p.consume diff --git a/lib/liquid/tags/if.rb b/lib/liquid/tags/if.rb index c3d1a777..b68e309a 100644 --- a/lib/liquid/tags/if.rb +++ b/lib/liquid/tags/if.rb @@ -94,7 +94,7 @@ module Liquid def parse_binary_comparisons(p) condition = parse_comparison(p) first_condition = condition - while op = (p.id?('and') || p.id?('or')) + while (op = (p.id?('and') || p.id?('or'))) child_condition = parse_comparison(p) condition.send(op, child_condition) condition = child_condition @@ -104,7 +104,7 @@ module Liquid def parse_comparison(p) a = Expression.parse(p.expression) - if op = p.consume?(:comparison) + if (op = p.consume?(:comparison)) b = Expression.parse(p.expression) Condition.new(a, op, b) else diff --git a/lib/liquid/tags/raw.rb b/lib/liquid/tags/raw.rb index fde3ee10..e4a78a81 100644 --- a/lib/liquid/tags/raw.rb +++ b/lib/liquid/tags/raw.rb @@ -13,7 +13,7 @@ module Liquid def parse(tokens) @body = +'' - while token = tokens.shift + while (token = tokens.shift) if token =~ FullTokenPossiblyInvalid @body << Regexp.last_match(1) if Regexp.last_match(1) != "" return if block_delimiter == Regexp.last_match(2) diff --git a/lib/liquid/variable.rb b/lib/liquid/variable.rb index 2fc2ea85..265748d3 100644 --- a/lib/liquid/variable.rb +++ b/lib/liquid/variable.rb @@ -110,7 +110,7 @@ module Liquid filter_args = [] keyword_args = nil unparsed_args.each do |a| - if matches = a.match(JustTagAttributes) + if (matches = a.match(JustTagAttributes)) keyword_args ||= {} keyword_args[matches[1]] = Expression.parse(matches[2]) else diff --git a/performance/profile.rb b/performance/profile.rb index 101f6e5d..70740778 100644 --- a/performance/profile.rb +++ b/performance/profile.rb @@ -15,7 +15,7 @@ profiler.run end end - if profile_type == :cpu && graph_filename = ENV['GRAPH_FILENAME'] + if profile_type == :cpu && (graph_filename = ENV['GRAPH_FILENAME']) File.open(graph_filename, 'w') do |f| StackProf::Report.new(results).print_graphviz(nil, f) end diff --git a/performance/shopify/database.rb b/performance/shopify/database.rb index 9836cd46..2db6d300 100644 --- a/performance/shopify/database.rb +++ b/performance/shopify/database.rb @@ -32,8 +32,8 @@ module Database db['article'] = db['blog']['articles'].first db['cart'] = { - 'total_price' => db['line_items'].values.inject(0) { |sum, item| sum += item['line_price'] * item['quantity'] }, - 'item_count' => db['line_items'].values.inject(0) { |sum, item| sum += item['quantity'] }, + 'total_price' => db['line_items'].values.inject(0) { |sum, item| sum + item['line_price'] * item['quantity'] }, + 'item_count' => db['line_items'].values.inject(0) { |sum, item| sum + item['quantity'] }, 'items' => db['line_items'].values, } diff --git a/test/integration/error_handling_test.rb b/test/integration/error_handling_test.rb index 265632cb..7abaec04 100644 --- a/test/integration/error_handling_test.rb +++ b/test/integration/error_handling_test.rb @@ -211,7 +211,10 @@ class ErrorHandlingTest < Minitest::Test def test_setting_default_exception_renderer old_exception_renderer = Liquid::Template.default_exception_renderer exceptions = [] - Liquid::Template.default_exception_renderer = ->(e) { exceptions << e; '' } + Liquid::Template.default_exception_renderer = ->(e) { + exceptions << e + '' + } template = Liquid::Template.parse('This is a runtime error: {{ errors.argument_error }}') output = template.render('errors' => ErrorDrop.new) @@ -225,7 +228,10 @@ class ErrorHandlingTest < Minitest::Test def test_exception_renderer_exposing_non_liquid_error template = Liquid::Template.parse('This is a runtime error: {{ errors.runtime_error }}', line_numbers: true) exceptions = [] - handler = ->(e) { exceptions << e; e.cause } + handler = ->(e) { + exceptions << e + e.cause + } output = template.render({ 'errors' => ErrorDrop.new }, exception_renderer: handler) diff --git a/test/integration/template_test.rb b/test/integration/template_test.rb index 75dd95b4..48549f55 100644 --- a/test/integration/template_test.rb +++ b/test/integration/template_test.rb @@ -81,7 +81,10 @@ class TemplateTest < Minitest::Test def test_lambda_is_called_once_from_persistent_assigns_over_multiple_parses_and_renders t = Template.new - t.assigns['number'] = -> { @global ||= 0; @global += 1 } + t.assigns['number'] = -> { + @global ||= 0 + @global += 1 + } assert_equal '1', t.parse("{{number}}").render! assert_equal '1', t.parse("{{number}}").render! assert_equal '1', t.render! @@ -90,7 +93,10 @@ class TemplateTest < Minitest::Test def test_lambda_is_called_once_from_custom_assigns_over_multiple_parses_and_renders t = Template.new - assigns = { 'number' => -> { @global ||= 0; @global += 1 } } + assigns = { 'number' => -> { + @global ||= 0 + @global += 1 + } } assert_equal '1', t.parse("{{number}}").render!(assigns) assert_equal '1', t.parse("{{number}}").render!(assigns) assert_equal '1', t.render!(assigns) @@ -237,7 +243,10 @@ class TemplateTest < Minitest::Test def test_exception_renderer_that_returns_string exception = nil - handler = ->(e) { exception = e; '' } + handler = ->(e) { + exception = e + '' + } output = Template.parse("{{ 1 | divided_by: 0 }}").render({}, exception_renderer: handler) @@ -248,7 +257,10 @@ class TemplateTest < Minitest::Test def test_exception_renderer_that_raises exception = nil assert_raises(Liquid::ZeroDivisionError) do - Template.parse("{{ 1 | divided_by: 0 }}").render({}, exception_renderer: ->(e) { exception = e; raise }) + Template.parse("{{ 1 | divided_by: 0 }}").render({}, exception_renderer: ->(e) { + exception = e + raise + }) end assert exception.is_a?(Liquid::ZeroDivisionError) end diff --git a/test/test_helper.rb b/test/test_helper.rb index d7a66413..9606ef8f 100755 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -9,7 +9,7 @@ require 'liquid.rb' require 'liquid/profiler' mode = :strict -if env_mode = ENV['LIQUID_PARSER_MODE'] +if (env_mode = ENV['LIQUID_PARSER_MODE']) puts "-- #{env_mode.upcase} ERROR MODE" mode = env_mode.to_sym end diff --git a/test/unit/condition_unit_test.rb b/test/unit/condition_unit_test.rb index 69f6b902..8d4e02f9 100644 --- a/test/unit/condition_unit_test.rb +++ b/test/unit/condition_unit_test.rb @@ -26,9 +26,9 @@ class ConditionUnitTest < Minitest::Test assert_evaluates_true 1, '<=', 1 # negative numbers assert_evaluates_true 1, '>', -1 - assert_evaluates_true -1, '<', 1 + assert_evaluates_true(-1, '<', 1) assert_evaluates_true 1.0, '>', -1.0 - assert_evaluates_true -1.0, '<', 1.0 + assert_evaluates_true(-1.0, '<', 1.0) end def test_default_operators_evalute_false diff --git a/test/unit/context_unit_test.rb b/test/unit/context_unit_test.rb index fe790cfb..3b460d7a 100644 --- a/test/unit/context_unit_test.rb +++ b/test/unit/context_unit_test.rb @@ -85,7 +85,7 @@ class ContextUnitTest < Minitest::Test @context['date'] = Date.today assert_equal Date.today, @context['date'] - now = DateTime.now + now = Time.now @context['datetime'] = now assert_equal now, @context['datetime'] @@ -405,7 +405,11 @@ class ContextUnitTest < Minitest::Test end def test_lambda_is_called_once - @context['callcount'] = proc { @global ||= 0; @global += 1; @global.to_s } + @context['callcount'] = proc { + @global ||= 0 + @global += 1 + @global.to_s + } assert_equal '1', @context['callcount'] assert_equal '1', @context['callcount'] @@ -415,7 +419,11 @@ class ContextUnitTest < Minitest::Test end def test_nested_lambda_is_called_once - @context['callcount'] = { "lambda" => proc { @global ||= 0; @global += 1; @global.to_s } } + @context['callcount'] = { "lambda" => proc { + @global ||= 0 + @global += 1 + @global.to_s + } } assert_equal '1', @context['callcount.lambda'] assert_equal '1', @context['callcount.lambda'] @@ -425,7 +433,11 @@ class ContextUnitTest < Minitest::Test end def test_lambda_in_array_is_called_once - @context['callcount'] = [1, 2, proc { @global ||= 0; @global += 1; @global.to_s }, 4, 5] + @context['callcount'] = [1, 2, proc { + @global ||= 0 + @global += 1 + @global.to_s + }, 4, 5] assert_equal '1', @context['callcount[2]'] assert_equal '1', @context['callcount[2]'] diff --git a/test/unit/tokenizer_unit_test.rb b/test/unit/tokenizer_unit_test.rb index d094aa1f..44342d6c 100644 --- a/test/unit/tokenizer_unit_test.rb +++ b/test/unit/tokenizer_unit_test.rb @@ -35,7 +35,7 @@ class TokenizerTest < Minitest::Test def tokenize(source) tokenizer = Liquid::Tokenizer.new(source) tokens = [] - while t = tokenizer.shift + while (t = tokenizer.shift) tokens << t end tokens From f4d134cd5cc920945e47acfcfe446492fc93bd3a Mon Sep 17 00:00:00 2001 From: Mike Angell <53470248+shopmike@users.noreply.github.com> Date: Fri, 20 Sep 2019 02:28:43 +1000 Subject: [PATCH 19/21] Remove jruby and truffleruby testing (#1167) --- .travis.yml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index b6a7db0d..f9c8c7fb 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,8 +7,6 @@ rvm: - &latest_ruby 2.6 - 2.7 - ruby-head - - jruby-head - - truffleruby matrix: include: @@ -17,8 +15,6 @@ matrix: name: Profiling Memory Usage allow_failures: - rvm: ruby-head - - rvm: jruby-head - - rvm: truffleruby branches: only: From 0db9c56f348f5325c52b1a86f71d7b9b92092569 Mon Sep 17 00:00:00 2001 From: Mike Angell <53470248+shopmike@users.noreply.github.com> Date: Thu, 26 Sep 2019 00:18:30 +1000 Subject: [PATCH 20/21] Disable rendering of tag based on register (#1162) * Disable rendering of tag based on register * Improvements to disable tag * Resolve disbale tag tests * Test disable_tags register * disabled_tags is now always avaiable * Allow multiple tags to be disabled at once * Move disabled check to block_body * Code improvements * Remove redundant nil check * Improve disabled tag error output * Improve disable tag API * Code improvements * Switch disabled? to not mutate output * Fix array handling shortcut in disable_tags --- lib/liquid.rb | 2 ++ lib/liquid/block_body.rb | 13 ++++++- lib/liquid/locales/en.yml | 2 ++ lib/liquid/register.rb | 6 ++++ lib/liquid/registers/disabled_tags.rb | 32 +++++++++++++++++ lib/liquid/tag.rb | 20 +++++++++++ lib/liquid/tags/render.rb | 6 ++++ lib/liquid/template.rb | 18 +++++++++- lib/liquid/variable.rb | 8 +++++ .../registers/disabled_tags_test.rb | 27 ++++++++++++++ test/integration/tags/render_tag_test.rb | 29 +++++++++++---- .../unit/registers/disabled_tags_unit_test.rb | 36 +++++++++++++++++++ 12 files changed, 191 insertions(+), 8 deletions(-) create mode 100644 lib/liquid/register.rb create mode 100644 lib/liquid/registers/disabled_tags.rb create mode 100644 test/integration/registers/disabled_tags_test.rb create mode 100644 test/unit/registers/disabled_tags_unit_test.rb diff --git a/lib/liquid.rb b/lib/liquid.rb index d102530c..cfaccee5 100644 --- a/lib/liquid.rb +++ b/lib/liquid.rb @@ -78,8 +78,10 @@ require 'liquid/tokenizer' require 'liquid/parse_context' require 'liquid/partial_cache' require 'liquid/usage' +require 'liquid/register' require 'liquid/static_registers' # Load all the tags of the standard library # Dir["#{__dir__}/liquid/tags/*.rb"].each { |f| require f } +Dir["#{__dir__}/liquid/registers/*.rb"].each { |f| require f } diff --git a/lib/liquid/block_body.rb b/lib/liquid/block_body.rb index 9400e383..c543d822 100644 --- a/lib/liquid/block_body.rb +++ b/lib/liquid/block_body.rb @@ -154,7 +154,13 @@ module Liquid private def render_node(context, output, node) - node.render_to_output_buffer(context, output) + if node.disabled?(context) + output << node.disabled_error_message + return + end + disable_tags(context, node.disabled_tags) do + node.render_to_output_buffer(context, output) + end rescue UndefinedVariable, UndefinedDropMethod, UndefinedFilter => e context.handle_error(e, node.line_number) rescue ::StandardError => e @@ -162,6 +168,11 @@ module Liquid output << context.handle_error(e, line_number) end + def disable_tags(context, tags, &block) + return yield if tags.empty? + context.registers['disabled_tags'].disable(tags, &block) + end + def raise_if_resource_limits_reached(context, length) context.resource_limits.render_length += length return unless context.resource_limits.reached? diff --git a/lib/liquid/locales/en.yml b/lib/liquid/locales/en.yml index c0a9aff7..a26320bc 100644 --- a/lib/liquid/locales/en.yml +++ b/lib/liquid/locales/en.yml @@ -25,3 +25,5 @@ render: "Syntax error in tag 'render' - Template name must be a quoted string" argument: include: "Argument error in tag 'include' - Illegal template name" + disabled: + tag: "usage is not allowed in this context" diff --git a/lib/liquid/register.rb b/lib/liquid/register.rb new file mode 100644 index 00000000..92d02266 --- /dev/null +++ b/lib/liquid/register.rb @@ -0,0 +1,6 @@ +# frozen_string_literal: true + +module Liquid + class Register + end +end diff --git a/lib/liquid/registers/disabled_tags.rb b/lib/liquid/registers/disabled_tags.rb new file mode 100644 index 00000000..79b64727 --- /dev/null +++ b/lib/liquid/registers/disabled_tags.rb @@ -0,0 +1,32 @@ +# frozen_string_literal: true +module Liquid + class DisabledTags < Register + def initialize + @disabled_tags = {} + end + + def disabled?(tag) + @disabled_tags.key?(tag) && @disabled_tags[tag] > 0 + end + + def disable(tags) + tags.each(&method(:increment)) + yield + ensure + tags.each(&method(:decrement)) + end + + private + + def increment(tag) + @disabled_tags[tag] ||= 0 + @disabled_tags[tag] += 1 + end + + def decrement(tag) + @disabled_tags[tag] -= 1 + end + end + + Template.add_register('disabled_tags', DisabledTags.new) +end diff --git a/lib/liquid/tag.rb b/lib/liquid/tag.rb index 14606391..832e32c7 100644 --- a/lib/liquid/tag.rb +++ b/lib/liquid/tag.rb @@ -13,7 +13,15 @@ module Liquid tag end + def disable_tags(*tags) + disabled_tags.push(*tags) + end + private :new + + def disabled_tags + @disabled_tags ||= [] + end end def initialize(tag_name, markup, parse_context) @@ -38,6 +46,14 @@ module Liquid '' end + def disabled?(context) + context.registers['disabled_tags'].disabled?(tag_name) + end + + def disabled_error_message + "#{tag_name} #{options[:locale].t('errors.disabled.tag')}" + end + # For backwards compatibility with custom tags. In a future release, the semantics # of the `render_to_output_buffer` method will become the default and the `render` # method will be removed. @@ -49,5 +65,9 @@ module Liquid def blank? false end + + def disabled_tags + self.class.disabled_tags + end end end diff --git a/lib/liquid/tags/render.rb b/lib/liquid/tags/render.rb index e6c62232..1403b584 100644 --- a/lib/liquid/tags/render.rb +++ b/lib/liquid/tags/render.rb @@ -4,6 +4,8 @@ module Liquid class Render < Tag SYNTAX = /(#{QuotedString})#{QuotedFragment}*/o + disable_tags "include" + attr_reader :template_name_expr, :attributes def initialize(tag_name, markup, options) @@ -22,6 +24,10 @@ module Liquid end def render_to_output_buffer(context, output) + render_tag(context, output) + end + + def render_tag(context, output) # Though we evaluate this here we will only ever parse it as a string literal. template_name = context.evaluate(@template_name_expr) raise ArgumentError, options[:locale].t("errors.argument.include") unless template_name diff --git a/lib/liquid/template.rb b/lib/liquid/template.rb index e77ba8aa..2f0bed4b 100644 --- a/lib/liquid/template.rb +++ b/lib/liquid/template.rb @@ -92,6 +92,14 @@ module Liquid @tags ||= TagRegistry.new end + def add_register(name, klass) + registers[name.to_s] = klass + end + + def registers + @registers ||= {} + end + def error_mode @error_mode ||= :lax end @@ -191,18 +199,26 @@ module Liquid output = nil + context_register = context.registers.is_a?(StaticRegisters) ? context.registers.static : context.registers + case args.last when Hash options = args.pop output = options[:output] if options[:output] - registers.merge!(options[:registers]) if options[:registers].is_a?(Hash) + options[:registers]&.each do |key, register| + context_register[key] = register + end apply_options_to_context(context, options) when Module, Array context.add_filters(args.pop) end + Template.registers.each do |key, register| + context_register[key] = register + end + # Retrying a render resets resource usage context.resource_limits.reset diff --git a/lib/liquid/variable.rb b/lib/liquid/variable.rb index 265748d3..5b686e2d 100644 --- a/lib/liquid/variable.rb +++ b/lib/liquid/variable.rb @@ -104,6 +104,14 @@ module Liquid output end + def disabled?(_context) + false + end + + def disabled_tags + [] + end + private def parse_filter_expressions(filter_name, unparsed_args) diff --git a/test/integration/registers/disabled_tags_test.rb b/test/integration/registers/disabled_tags_test.rb new file mode 100644 index 00000000..1fb24589 --- /dev/null +++ b/test/integration/registers/disabled_tags_test.rb @@ -0,0 +1,27 @@ +# frozen_string_literal: true + +require 'test_helper' + +class DisabledTagsTest < Minitest::Test + include Liquid + + class DisableRaw < Block + disable_tags "raw" + end + + class DisableRawEcho < Block + disable_tags "raw", "echo" + end + + def test_disables_raw + with_custom_tag('disable', DisableRaw) do + assert_template_result 'raw usage is not allowed in this contextfoo', '{% disable %}{% raw %}Foobar{% endraw %}{% echo "foo" %}{% enddisable %}' + end + end + + def test_disables_echo_and_raw + with_custom_tag('disable', DisableRawEcho) do + assert_template_result 'raw usage is not allowed in this contextecho usage is not allowed in this context', '{% disable %}{% raw %}Foobar{% endraw %}{% echo "foo" %}{% enddisable %}' + end + end +end diff --git a/test/integration/tags/render_tag_test.rb b/test/integration/tags/render_tag_test.rb index 154783ad..87373a28 100644 --- a/test/integration/tags/render_tag_test.rb +++ b/test/integration/tags/render_tag_test.rb @@ -89,14 +89,12 @@ class RenderTagTest < Minitest::Test end end - def test_includes_and_renders_count_towards_the_same_recursion_limit + def test_sub_contexts_count_towards_the_same_recursion_limit Liquid::Template.file_system = StubFileSystem.new( - 'loop_render' => '{% render "loop_include" %}', - 'loop_include' => '{% include "loop_render" %}' + 'loop_render' => '{% render "loop_render" %}', ) - - assert_raises Liquid::StackLevelError do - Template.parse('{% render "loop_include" %}').render! + assert_raises Liquid::StackLevelError do + Template.parse('{% render "loop_render" %}').render! end end @@ -148,4 +146,23 @@ class RenderTagTest < Minitest::Test Liquid::Template.file_system = StubFileSystem.new('decr' => '{% decrement %}') assert_template_result '-1-2-1', '{% decrement %}{% decrement %}{% render "decr" %}' end + + def test_includes_will_not_render_inside_render_tag + Liquid::Template.file_system = StubFileSystem.new( + 'foo' => 'bar', + 'test_include' => '{% include "foo" %}' + ) + + assert_template_result 'include usage is not allowed in this context', '{% render "test_include" %}' + end + + def test_includes_will_not_render_inside_nested_sibling_tags + Liquid::Template.file_system = StubFileSystem.new( + 'foo' => 'bar', + 'nested_render_with_sibling_include' => '{% render "test_include" %}{% include "foo" %}', + 'test_include' => '{% include "foo" %}' + ) + + assert_template_result 'include usage is not allowed in this contextinclude usage is not allowed in this context', '{% render "nested_render_with_sibling_include" %}' + end end diff --git a/test/unit/registers/disabled_tags_unit_test.rb b/test/unit/registers/disabled_tags_unit_test.rb new file mode 100644 index 00000000..90ac0166 --- /dev/null +++ b/test/unit/registers/disabled_tags_unit_test.rb @@ -0,0 +1,36 @@ +# frozen_string_literal: true + +require 'test_helper' + +class DisabledTagsUnitTest < Minitest::Test + include Liquid + + def test_disables_tag_specified + register = DisabledTags.new + register.disable(%w(foo bar)) do + assert_equal true, register.disabled?("foo") + assert_equal true, register.disabled?("bar") + assert_equal false, register.disabled?("unknown") + end + end + + def test_disables_nested_tags + register = DisabledTags.new + register.disable(["foo"]) do + register.disable(["foo"]) do + assert_equal true, register.disabled?("foo") + assert_equal false, register.disabled?("bar") + end + register.disable(["bar"]) do + assert_equal true, register.disabled?("foo") + assert_equal true, register.disabled?("bar") + register.disable(["foo"]) do + assert_equal true, register.disabled?("foo") + assert_equal true, register.disabled?("bar") + end + end + assert_equal true, register.disabled?("foo") + assert_equal false, register.disabled?("bar") + end + end +end From 1aa7d3d2bab67defbf61b0f3d014a610b233e506 Mon Sep 17 00:00:00 2001 From: Mike Angell <53470248+shopmike@users.noreply.github.com> Date: Fri, 27 Sep 2019 04:32:24 +1000 Subject: [PATCH 21/21] Change registers to by symbols (#1178) --- lib/liquid/block_body.rb | 2 +- lib/liquid/registers/disabled_tags.rb | 2 +- lib/liquid/tag.rb | 2 +- lib/liquid/template.rb | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/liquid/block_body.rb b/lib/liquid/block_body.rb index c543d822..45be8b8a 100644 --- a/lib/liquid/block_body.rb +++ b/lib/liquid/block_body.rb @@ -170,7 +170,7 @@ module Liquid def disable_tags(context, tags, &block) return yield if tags.empty? - context.registers['disabled_tags'].disable(tags, &block) + context.registers[:disabled_tags].disable(tags, &block) end def raise_if_resource_limits_reached(context, length) diff --git a/lib/liquid/registers/disabled_tags.rb b/lib/liquid/registers/disabled_tags.rb index 79b64727..b1cd3bda 100644 --- a/lib/liquid/registers/disabled_tags.rb +++ b/lib/liquid/registers/disabled_tags.rb @@ -28,5 +28,5 @@ module Liquid end end - Template.add_register('disabled_tags', DisabledTags.new) + Template.add_register(:disabled_tags, DisabledTags.new) end diff --git a/lib/liquid/tag.rb b/lib/liquid/tag.rb index 832e32c7..ffd22868 100644 --- a/lib/liquid/tag.rb +++ b/lib/liquid/tag.rb @@ -47,7 +47,7 @@ module Liquid end def disabled?(context) - context.registers['disabled_tags'].disabled?(tag_name) + context.registers[:disabled_tags].disabled?(tag_name) end def disabled_error_message diff --git a/lib/liquid/template.rb b/lib/liquid/template.rb index 2f0bed4b..e23df246 100644 --- a/lib/liquid/template.rb +++ b/lib/liquid/template.rb @@ -93,7 +93,7 @@ module Liquid end def add_register(name, klass) - registers[name.to_s] = klass + registers[name.to_sym] = klass end def registers