mirror of
https://github.com/kemko/liquid.git
synced 2026-01-02 08:15:41 +03:00
Compare commits
2 Commits
master-fix
...
context_si
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6fd5e4e6ce | ||
|
|
56c667d8f9 |
File diff suppressed because it is too large
Load Diff
130
.rubocop.yml
130
.rubocop.yml
@@ -1,15 +1,131 @@
|
|||||||
inherit_from:
|
inherit_from:
|
||||||
- https://shopify.github.io/ruby-style-guide/rubocop.yml
|
|
||||||
- .rubocop_todo.yml
|
- .rubocop_todo.yml
|
||||||
|
- ./.rubocop_todo.yml
|
||||||
require: rubocop-performance
|
|
||||||
|
|
||||||
Performance:
|
|
||||||
Enabled: true
|
|
||||||
|
|
||||||
AllCops:
|
AllCops:
|
||||||
Exclude:
|
Exclude:
|
||||||
- 'vendor/bundle/**/*'
|
- 'performance/shopify/*'
|
||||||
|
- 'pkg/**'
|
||||||
|
|
||||||
|
Metrics/BlockNesting:
|
||||||
|
Max: 3
|
||||||
|
|
||||||
|
Metrics/ModuleLength:
|
||||||
|
Enabled: false
|
||||||
|
|
||||||
|
Metrics/ClassLength:
|
||||||
|
Enabled: false
|
||||||
|
|
||||||
|
Lint/AssignmentInCondition:
|
||||||
|
Enabled: false
|
||||||
|
|
||||||
|
Lint/AmbiguousOperator:
|
||||||
|
Enabled: false
|
||||||
|
|
||||||
|
Lint/AmbiguousRegexpLiteral:
|
||||||
|
Enabled: false
|
||||||
|
|
||||||
|
Lint/ParenthesesAsGroupedExpression:
|
||||||
|
Enabled: false
|
||||||
|
|
||||||
|
Lint/UnusedBlockArgument:
|
||||||
|
Enabled: false
|
||||||
|
|
||||||
|
Layout/EndAlignment:
|
||||||
|
EnforcedStyleAlignWith: variable
|
||||||
|
|
||||||
|
Lint/UnusedMethodArgument:
|
||||||
|
Enabled: false
|
||||||
|
|
||||||
|
Style/SingleLineBlockParams:
|
||||||
|
Enabled: false
|
||||||
|
|
||||||
|
Style/DoubleNegation:
|
||||||
|
Enabled: false
|
||||||
|
|
||||||
|
Style/StringLiteralsInInterpolation:
|
||||||
|
Enabled: false
|
||||||
|
|
||||||
|
Style/AndOr:
|
||||||
|
Enabled: false
|
||||||
|
|
||||||
|
Style/SignalException:
|
||||||
|
Enabled: false
|
||||||
|
|
||||||
|
Style/StringLiterals:
|
||||||
|
Enabled: false
|
||||||
|
|
||||||
|
Style/BracesAroundHashParameters:
|
||||||
|
Enabled: false
|
||||||
|
|
||||||
|
Style/NumericLiterals:
|
||||||
|
Enabled: false
|
||||||
|
|
||||||
|
Layout/SpaceInsideArrayLiteralBrackets:
|
||||||
|
Enabled: false
|
||||||
|
|
||||||
|
Layout/SpaceBeforeBlockBraces:
|
||||||
|
Enabled: false
|
||||||
|
|
||||||
|
Style/Documentation:
|
||||||
|
Enabled: false
|
||||||
|
|
||||||
|
Style/ClassAndModuleChildren:
|
||||||
|
Enabled: false
|
||||||
|
|
||||||
|
Style/TrailingCommaInArrayLiteral:
|
||||||
|
Enabled: false
|
||||||
|
|
||||||
|
Style/TrailingCommaInHashLiteral:
|
||||||
|
Enabled: false
|
||||||
|
|
||||||
|
Layout/IndentHash:
|
||||||
|
EnforcedStyle: consistent
|
||||||
|
|
||||||
|
Style/FormatString:
|
||||||
|
Enabled: false
|
||||||
|
|
||||||
|
Layout/AlignParameters:
|
||||||
|
EnforcedStyle: with_fixed_indentation
|
||||||
|
|
||||||
|
Layout/MultilineOperationIndentation:
|
||||||
|
EnforcedStyle: indented
|
||||||
|
|
||||||
|
Style/IfUnlessModifier:
|
||||||
|
Enabled: false
|
||||||
|
|
||||||
|
Style/RaiseArgs:
|
||||||
|
Enabled: false
|
||||||
|
|
||||||
|
Style/PreferredHashMethods:
|
||||||
|
Enabled: false
|
||||||
|
|
||||||
|
Style/RegexpLiteral:
|
||||||
|
Enabled: false
|
||||||
|
|
||||||
|
Style/SymbolLiteral:
|
||||||
|
Enabled: false
|
||||||
|
|
||||||
|
Performance/Count:
|
||||||
|
Enabled: false
|
||||||
|
|
||||||
|
Naming/ConstantName:
|
||||||
|
Enabled: false
|
||||||
|
|
||||||
|
Layout/CaseIndentation:
|
||||||
|
Enabled: false
|
||||||
|
|
||||||
|
Style/ClassVars:
|
||||||
|
Enabled: false
|
||||||
|
|
||||||
|
Style/PerlBackrefs:
|
||||||
|
Enabled: false
|
||||||
|
|
||||||
|
Style/TrivialAccessors:
|
||||||
|
AllowPredicates: true
|
||||||
|
|
||||||
|
Style/WordArray:
|
||||||
|
Enabled: false
|
||||||
|
|
||||||
Naming/MethodName:
|
Naming/MethodName:
|
||||||
Exclude:
|
Exclude:
|
||||||
|
|||||||
@@ -1,37 +1,23 @@
|
|||||||
# This configuration was generated by
|
# This configuration was generated by
|
||||||
# `rubocop --auto-gen-config`
|
# `rubocop --auto-gen-config`
|
||||||
# on 2019-08-29 12:16:25 +1000 using RuboCop version 0.74.0.
|
# on 2019-04-22 19:11:24 -0400 using RuboCop version 0.53.0.
|
||||||
# The point is for the user to remove these configuration records
|
# The point is for the user to remove these configuration records
|
||||||
# one by one as the offenses are removed from the code base.
|
# one by one as the offenses are removed from the code base.
|
||||||
# Note that changes in the inspected code, or installation of new
|
# Note that changes in the inspected code, or installation of new
|
||||||
# versions of RuboCop, may require this file to be generated again.
|
# versions of RuboCop, may require this file to be generated again.
|
||||||
|
|
||||||
# Offense count: 13
|
# Offense count: 1
|
||||||
# Cop supports --auto-correct.
|
# Cop supports --auto-correct.
|
||||||
# Configuration parameters: AllowMultipleStyles, EnforcedHashRocketStyle, EnforcedColonStyle, EnforcedLastArgumentHashStyle.
|
# Configuration parameters: Include, TreatCommentsAsGroupSeparators.
|
||||||
# SupportedHashRocketStyles: key, separator, table
|
# Include: **/*.gemspec
|
||||||
# SupportedColonStyles: key, separator, table
|
Gemspec/OrderedDependencies:
|
||||||
# SupportedLastArgumentHashStyles: always_inspect, always_ignore, ignore_implicit, ignore_explicit
|
|
||||||
Layout/AlignHash:
|
|
||||||
Exclude:
|
Exclude:
|
||||||
- 'lib/liquid/condition.rb'
|
- 'liquid.gemspec'
|
||||||
- '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
|
# Offense count: 5
|
||||||
# Cop supports --auto-correct.
|
# Cop supports --auto-correct.
|
||||||
# Configuration parameters: EnforcedStyle.
|
# Configuration parameters: EnforcedStyle.
|
||||||
# SupportedStyles: squiggly, active_support, powerpack, unindent
|
# SupportedStyles: auto_detection, squiggly, active_support, powerpack, unindent
|
||||||
Layout/IndentHeredoc:
|
Layout/IndentHeredoc:
|
||||||
Exclude:
|
Exclude:
|
||||||
- 'test/integration/tags/for_tag_test.rb'
|
- 'test/integration/tags/for_tag_test.rb'
|
||||||
@@ -46,62 +32,6 @@ Layout/MultilineMethodCallBraceLayout:
|
|||||||
- 'test/integration/error_handling_test.rb'
|
- 'test/integration/error_handling_test.rb'
|
||||||
- 'test/unit/strainer_unit_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
|
|
||||||
# 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/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
|
# Offense count: 2
|
||||||
# Cop supports --auto-correct.
|
# Cop supports --auto-correct.
|
||||||
# Configuration parameters: EnforcedStyle.
|
# Configuration parameters: EnforcedStyle.
|
||||||
@@ -110,184 +40,145 @@ Lint/InheritException:
|
|||||||
Exclude:
|
Exclude:
|
||||||
- 'lib/liquid/interrupts.rb'
|
- '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:
|
|
||||||
- 'performance/shopify/database.rb'
|
|
||||||
|
|
||||||
# Offense count: 1
|
# Offense count: 1
|
||||||
# Configuration parameters: CheckForMethodsWithNoSideEffects.
|
# Configuration parameters: CheckForMethodsWithNoSideEffects.
|
||||||
Lint/Void:
|
Lint/Void:
|
||||||
Exclude:
|
Exclude:
|
||||||
- 'lib/liquid/parse_context.rb'
|
- 'lib/liquid/parse_context.rb'
|
||||||
|
|
||||||
# Offense count: 95
|
# Offense count: 53
|
||||||
# Cop supports --auto-correct.
|
Metrics/AbcSize:
|
||||||
# Configuration parameters: AutoCorrect, AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, IgnoredPatterns.
|
Max: 56
|
||||||
# URISchemes: http, https
|
|
||||||
Metrics/LineLength:
|
|
||||||
Max: 294
|
|
||||||
|
|
||||||
# Offense count: 44
|
# Offense count: 12
|
||||||
Naming/ConstantName:
|
Metrics/CyclomaticComplexity:
|
||||||
|
Max: 13
|
||||||
|
|
||||||
|
# Offense count: 112
|
||||||
|
# Configuration parameters: CountComments.
|
||||||
|
Metrics/MethodLength:
|
||||||
|
Max: 38
|
||||||
|
|
||||||
|
# Offense count: 8
|
||||||
|
Metrics/PerceivedComplexity:
|
||||||
|
Max: 11
|
||||||
|
|
||||||
|
# Offense count: 52
|
||||||
|
# Configuration parameters: Blacklist.
|
||||||
|
# Blacklist: END, (?-mix:EO[A-Z]{1})
|
||||||
|
Naming/HeredocDelimiterNaming:
|
||||||
Exclude:
|
Exclude:
|
||||||
- 'lib/liquid.rb'
|
- 'test/integration/assign_test.rb'
|
||||||
- 'lib/liquid/block_body.rb'
|
- 'test/integration/capture_test.rb'
|
||||||
- 'lib/liquid/tags/assign.rb'
|
- 'test/integration/trim_mode_test.rb'
|
||||||
- 'lib/liquid/tags/capture.rb'
|
|
||||||
- 'lib/liquid/tags/case.rb'
|
# Offense count: 23
|
||||||
- 'lib/liquid/tags/cycle.rb'
|
# Configuration parameters: MinNameLength, AllowNamesEndingInNumbers, AllowedNames, ForbiddenNames.
|
||||||
- 'lib/liquid/tags/for.rb'
|
# AllowedNames: io, id
|
||||||
|
Naming/UncommunicativeMethodParamName:
|
||||||
|
Exclude:
|
||||||
|
- 'example/server/example_servlet.rb'
|
||||||
|
- 'lib/liquid/condition.rb'
|
||||||
|
- 'lib/liquid/context.rb'
|
||||||
|
- 'lib/liquid/standardfilters.rb'
|
||||||
- 'lib/liquid/tags/if.rb'
|
- 'lib/liquid/tags/if.rb'
|
||||||
- 'lib/liquid/tags/include.rb'
|
- 'lib/liquid/utils.rb'
|
||||||
- 'lib/liquid/tags/raw.rb'
|
|
||||||
- 'lib/liquid/tags/table_row.rb'
|
|
||||||
- 'lib/liquid/variable.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/filter_test.rb'
|
||||||
- 'test/integration/render_profiling_test.rb'
|
|
||||||
- 'test/integration/standard_filter_test.rb'
|
- 'test/integration/standard_filter_test.rb'
|
||||||
- 'test/integration/tags/echo_test.rb'
|
- 'test/integration/tags/for_tag_test.rb'
|
||||||
- 'test/integration/tags/increment_tag_test.rb'
|
|
||||||
- 'test/integration/tags/standard_tag_test.rb'
|
|
||||||
- 'test/integration/template_test.rb'
|
- 'test/integration/template_test.rb'
|
||||||
- 'test/unit/condition_unit_test.rb'
|
- 'test/unit/condition_unit_test.rb'
|
||||||
- 'test/unit/context_unit_test.rb'
|
|
||||||
|
|
||||||
# Offense count: 5
|
# Offense count: 12
|
||||||
Style/ClassVars:
|
# Cop supports --auto-correct.
|
||||||
|
# Configuration parameters: EnforcedStyle.
|
||||||
|
# SupportedStyles: prefer_alias, prefer_alias_method
|
||||||
|
Style/Alias:
|
||||||
Exclude:
|
Exclude:
|
||||||
- 'lib/liquid/condition.rb'
|
- 'lib/liquid/drop.rb'
|
||||||
- 'lib/liquid/strainer.rb'
|
- 'lib/liquid/i18n.rb'
|
||||||
- 'lib/liquid/template.rb'
|
- 'lib/liquid/profiler/hooks.rb'
|
||||||
|
- 'lib/liquid/standardfilters.rb'
|
||||||
|
- 'lib/liquid/tag.rb'
|
||||||
|
- 'lib/liquid/tags/include.rb'
|
||||||
|
- 'lib/liquid/variable.rb'
|
||||||
|
|
||||||
# Offense count: 2
|
# Offense count: 22
|
||||||
|
Style/CommentedKeyword:
|
||||||
|
Enabled: false
|
||||||
|
|
||||||
|
# Offense count: 1
|
||||||
# Cop supports --auto-correct.
|
# Cop supports --auto-correct.
|
||||||
# Configuration parameters: EnforcedStyle, SingleLineConditionsOnly, IncludeTernaryExpressions.
|
# Configuration parameters: EnforcedStyle, SingleLineConditionsOnly, IncludeTernaryExpressions.
|
||||||
# SupportedStyles: assign_to_condition, assign_inside_condition
|
# SupportedStyles: assign_to_condition, assign_inside_condition
|
||||||
Style/ConditionalAssignment:
|
Style/ConditionalAssignment:
|
||||||
Exclude:
|
Exclude:
|
||||||
- 'lib/liquid/errors.rb'
|
- 'lib/liquid/errors.rb'
|
||||||
- 'performance/shopify/shop_filter.rb'
|
|
||||||
|
|
||||||
# Offense count: 1
|
# Offense count: 1
|
||||||
# Configuration parameters: AllowCoercion.
|
|
||||||
Style/DateTime:
|
Style/DateTime:
|
||||||
Exclude:
|
Exclude:
|
||||||
- 'test/unit/context_unit_test.rb'
|
- 'test/unit/context_unit_test.rb'
|
||||||
|
|
||||||
# Offense count: 2
|
# Offense count: 2
|
||||||
# Cop supports --auto-correct.
|
# Cop supports --auto-correct.
|
||||||
Style/EachWithObject:
|
|
||||||
Exclude:
|
|
||||||
- 'performance/shopify/database.rb'
|
|
||||||
|
|
||||||
# Offense count: 1
|
|
||||||
# Cop supports --auto-correct.
|
|
||||||
Style/EmptyCaseCondition:
|
Style/EmptyCaseCondition:
|
||||||
Exclude:
|
Exclude:
|
||||||
|
- 'lib/liquid/block_body.rb'
|
||||||
- 'lib/liquid/lexer.rb'
|
- 'lib/liquid/lexer.rb'
|
||||||
|
|
||||||
# Offense count: 1
|
# Offense count: 5
|
||||||
# Cop supports --auto-correct.
|
# Cop supports --auto-correct.
|
||||||
# Configuration parameters: EnforcedStyle.
|
# Configuration parameters: EnforcedStyle.
|
||||||
# SupportedStyles: each, for
|
# SupportedStyles: compact, expanded
|
||||||
Style/For:
|
Style/EmptyMethod:
|
||||||
Exclude:
|
Exclude:
|
||||||
- 'performance/shopify/shop_filter.rb'
|
- 'lib/liquid/tag.rb'
|
||||||
|
- 'lib/liquid/tags/comment.rb'
|
||||||
|
- 'lib/liquid/tags/include.rb'
|
||||||
|
- 'test/integration/tags/include_tag_test.rb'
|
||||||
|
- 'test/unit/context_unit_test.rb'
|
||||||
|
|
||||||
# Offense count: 9
|
# Offense count: 3
|
||||||
# Cop supports --auto-correct.
|
# Cop supports --auto-correct.
|
||||||
# Configuration parameters: EnforcedStyle.
|
Style/Encoding:
|
||||||
# SupportedStyles: format, sprintf, percent
|
Exclude:
|
||||||
Style/FormatString:
|
- 'lib/liquid/version.rb'
|
||||||
|
- 'liquid.gemspec'
|
||||||
|
- 'test/integration/standard_filter_test.rb'
|
||||||
|
|
||||||
|
# Offense count: 2
|
||||||
|
# Cop supports --auto-correct.
|
||||||
|
Style/ExpandPathArguments:
|
||||||
|
Exclude:
|
||||||
|
- 'Rakefile'
|
||||||
|
- 'liquid.gemspec'
|
||||||
|
|
||||||
|
# Offense count: 7
|
||||||
|
# Configuration parameters: EnforcedStyle.
|
||||||
|
# SupportedStyles: annotated, template, unannotated
|
||||||
|
Style/FormatStringToken:
|
||||||
Exclude:
|
Exclude:
|
||||||
- 'example/server/example_servlet.rb'
|
|
||||||
- 'performance/shopify/money_filter.rb'
|
|
||||||
- 'performance/shopify/weight_filter.rb'
|
|
||||||
- 'test/integration/filter_test.rb'
|
- 'test/integration/filter_test.rb'
|
||||||
- 'test/integration/hash_ordering_test.rb'
|
- 'test/integration/hash_ordering_test.rb'
|
||||||
|
|
||||||
# Offense count: 115
|
# Offense count: 14
|
||||||
# Cop supports --auto-correct.
|
# Configuration parameters: MinBodyLength.
|
||||||
# Configuration parameters: EnforcedStyle.
|
Style/GuardClause:
|
||||||
# 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:
|
Exclude:
|
||||||
- 'Gemfile'
|
- 'lib/liquid/condition.rb'
|
||||||
- 'Rakefile'
|
- 'lib/liquid/lexer.rb'
|
||||||
- 'lib/liquid/block_body.rb'
|
- 'lib/liquid/strainer.rb'
|
||||||
- 'lib/liquid/parser.rb'
|
- 'lib/liquid/tags/assign.rb'
|
||||||
|
- 'lib/liquid/tags/capture.rb'
|
||||||
|
- 'lib/liquid/tags/case.rb'
|
||||||
- 'lib/liquid/tags/for.rb'
|
- 'lib/liquid/tags/for.rb'
|
||||||
- 'liquid.gemspec'
|
- 'lib/liquid/tags/include.rb'
|
||||||
- 'performance/shopify/database.rb'
|
- 'lib/liquid/tags/raw.rb'
|
||||||
- 'performance/shopify/liquid.rb'
|
- 'lib/liquid/tags/table_row.rb'
|
||||||
- 'test/test_helper.rb'
|
- 'lib/liquid/variable.rb'
|
||||||
- 'test/unit/condition_unit_test.rb'
|
- 'test/unit/tokenizer_unit_test.rb'
|
||||||
- 'test/unit/tags/if_tag_unit_test.rb'
|
|
||||||
|
|
||||||
# Offense count: 1
|
# Offense count: 1
|
||||||
# Cop supports --auto-correct.
|
# Cop supports --auto-correct.
|
||||||
@@ -297,17 +188,27 @@ Style/Next:
|
|||||||
Exclude:
|
Exclude:
|
||||||
- 'lib/liquid/tags/for.rb'
|
- 'lib/liquid/tags/for.rb'
|
||||||
|
|
||||||
# Offense count: 52
|
# Offense count: 4
|
||||||
# Cop supports --auto-correct.
|
# Cop supports --auto-correct.
|
||||||
Style/PerlBackrefs:
|
# Configuration parameters: AutoCorrect, EnforcedStyle.
|
||||||
Enabled: false
|
# SupportedStyles: predicate, comparison
|
||||||
|
Style/NumericPredicate:
|
||||||
|
Exclude:
|
||||||
|
- 'spec/**/*'
|
||||||
|
- 'lib/liquid/context.rb'
|
||||||
|
- 'lib/liquid/forloop_drop.rb'
|
||||||
|
- 'lib/liquid/standardfilters.rb'
|
||||||
|
- 'lib/liquid/tablerowloop_drop.rb'
|
||||||
|
|
||||||
# Offense count: 33
|
# Offense count: 14
|
||||||
# Cop supports --auto-correct.
|
# Cop supports --auto-correct.
|
||||||
# Configuration parameters: EnforcedStyle.
|
# Configuration parameters: PreferredDelimiters.
|
||||||
# SupportedStyles: compact, exploded
|
Style/PercentLiteralDelimiters:
|
||||||
Style/RaiseArgs:
|
Exclude:
|
||||||
Enabled: false
|
- 'lib/liquid/tags/if.rb'
|
||||||
|
- 'liquid.gemspec'
|
||||||
|
- 'test/integration/assign_test.rb'
|
||||||
|
- 'test/integration/standard_filter_test.rb'
|
||||||
|
|
||||||
# Offense count: 1
|
# Offense count: 1
|
||||||
# Cop supports --auto-correct.
|
# Cop supports --auto-correct.
|
||||||
@@ -315,52 +216,21 @@ Style/RedundantSelf:
|
|||||||
Exclude:
|
Exclude:
|
||||||
- 'lib/liquid/strainer.rb'
|
- 'lib/liquid/strainer.rb'
|
||||||
|
|
||||||
# Offense count: 5
|
# Offense count: 9
|
||||||
# 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
|
|
||||||
# Cop supports --auto-correct.
|
# Cop supports --auto-correct.
|
||||||
# Configuration parameters: AllowAsExpressionSeparator.
|
# Configuration parameters: AllowAsExpressionSeparator.
|
||||||
Style/Semicolon:
|
Style/Semicolon:
|
||||||
Exclude:
|
Exclude:
|
||||||
- 'performance/shopify/database.rb'
|
|
||||||
- 'test/integration/error_handling_test.rb'
|
- 'test/integration/error_handling_test.rb'
|
||||||
- 'test/integration/template_test.rb'
|
- 'test/integration/template_test.rb'
|
||||||
- 'test/unit/context_unit_test.rb'
|
- 'test/unit/context_unit_test.rb'
|
||||||
|
|
||||||
# Offense count: 1
|
# Offense count: 7
|
||||||
# Cop supports --auto-correct.
|
# Cop supports --auto-correct.
|
||||||
# Configuration parameters: EnforcedStyle.
|
# Configuration parameters: MinSize.
|
||||||
# SupportedStyles: use_perl_names, use_english_names
|
# SupportedStyles: percent, brackets
|
||||||
Style/SpecialGlobalVars:
|
Style/SymbolArray:
|
||||||
Exclude:
|
EnforcedStyle: brackets
|
||||||
- '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
|
# Offense count: 2
|
||||||
# Cop supports --auto-correct.
|
# Cop supports --auto-correct.
|
||||||
@@ -371,33 +241,6 @@ Style/TernaryParentheses:
|
|||||||
- 'lib/liquid/context.rb'
|
- 'lib/liquid/context.rb'
|
||||||
- 'lib/liquid/utils.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
|
# Offense count: 2
|
||||||
# Cop supports --auto-correct.
|
# Cop supports --auto-correct.
|
||||||
Style/UnneededPercentQ:
|
Style/UnneededPercentQ:
|
||||||
@@ -409,3 +252,9 @@ Style/UnneededPercentQ:
|
|||||||
Style/WhileUntilModifier:
|
Style/WhileUntilModifier:
|
||||||
Exclude:
|
Exclude:
|
||||||
- 'lib/liquid/tags/case.rb'
|
- 'lib/liquid/tags/case.rb'
|
||||||
|
|
||||||
|
# Offense count: 648
|
||||||
|
# Configuration parameters: AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, IgnoredPatterns.
|
||||||
|
# URISchemes: http, https
|
||||||
|
Metrics/LineLength:
|
||||||
|
Max: 294
|
||||||
|
|||||||
22
.travis.yml
22
.travis.yml
@@ -1,14 +1,20 @@
|
|||||||
language: ruby
|
language: ruby
|
||||||
cache: bundler
|
|
||||||
|
|
||||||
rvm:
|
rvm:
|
||||||
|
- 2.1
|
||||||
|
- 2.2
|
||||||
|
- 2.3
|
||||||
- 2.4
|
- 2.4
|
||||||
- 2.5
|
- 2.5
|
||||||
- &latest_ruby 2.6
|
- &latest_ruby 2.6
|
||||||
- 2.7
|
|
||||||
- ruby-head
|
- ruby-head
|
||||||
- jruby-head
|
- jruby-head
|
||||||
- truffleruby
|
# - rbx-2
|
||||||
|
|
||||||
|
addons:
|
||||||
|
apt:
|
||||||
|
packages:
|
||||||
|
- libgmp3-dev
|
||||||
|
|
||||||
matrix:
|
matrix:
|
||||||
include:
|
include:
|
||||||
@@ -18,13 +24,11 @@ matrix:
|
|||||||
allow_failures:
|
allow_failures:
|
||||||
- rvm: ruby-head
|
- rvm: ruby-head
|
||||||
- rvm: jruby-head
|
- rvm: jruby-head
|
||||||
- rvm: truffleruby
|
|
||||||
|
|
||||||
branches:
|
install:
|
||||||
only:
|
- bundle install
|
||||||
- master
|
|
||||||
- gh-pages
|
script: bundle exec rake
|
||||||
- /.*-stable/
|
|
||||||
|
|
||||||
notifications:
|
notifications:
|
||||||
disable: true
|
disable: true
|
||||||
|
|||||||
7
Gemfile
7
Gemfile
@@ -10,16 +10,15 @@ group :benchmark, :test do
|
|||||||
gem 'memory_profiler'
|
gem 'memory_profiler'
|
||||||
gem 'terminal-table'
|
gem 'terminal-table'
|
||||||
|
|
||||||
install_if -> { RUBY_PLATFORM !~ /mingw|mswin|java/ && RUBY_ENGINE != 'truffleruby' } do
|
install_if -> { RUBY_PLATFORM !~ /mingw|mswin|java/ } do
|
||||||
gem 'stackprof'
|
gem 'stackprof'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
group :test do
|
group :test do
|
||||||
gem 'rubocop', '~> 0.74.0', require: false
|
gem 'rubocop', '~> 0.53.0'
|
||||||
gem 'rubocop-performance', require: false
|
|
||||||
|
|
||||||
platform :mri, :truffleruby do
|
platform :mri do
|
||||||
gem 'liquid-c', github: 'Shopify/liquid-c', ref: 'liquid-tag'
|
gem 'liquid-c', github: 'Shopify/liquid-c', ref: 'liquid-tag'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
10
Rakefile
10
Rakefile
@@ -19,10 +19,8 @@ task :warn_test do
|
|||||||
end
|
end
|
||||||
|
|
||||||
task :rubocop do
|
task :rubocop do
|
||||||
if RUBY_ENGINE == 'ruby'
|
require 'rubocop/rake_task'
|
||||||
require 'rubocop/rake_task'
|
RuboCop::RakeTask.new
|
||||||
RuboCop::RakeTask.new
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
desc 'runs test suite with both strict and lax parsers'
|
desc 'runs test suite with both strict and lax parsers'
|
||||||
@@ -34,8 +32,8 @@ task :test do
|
|||||||
Rake::Task['base_test'].reenable
|
Rake::Task['base_test'].reenable
|
||||||
Rake::Task['base_test'].invoke
|
Rake::Task['base_test'].invoke
|
||||||
|
|
||||||
if RUBY_ENGINE == 'ruby' || RUBY_ENGINE == 'truffleruby'
|
if RUBY_ENGINE == 'ruby'
|
||||||
ENV['LIQUID_C'] = '1'
|
ENV['LIQUID-C'] = '1'
|
||||||
|
|
||||||
ENV['LIQUID_PARSER_MODE'] = 'lax'
|
ENV['LIQUID_PARSER_MODE'] = 'lax'
|
||||||
Rake::Task['base_test'].reenable
|
Rake::Task['base_test'].reenable
|
||||||
|
|||||||
@@ -74,7 +74,6 @@ require 'liquid/condition'
|
|||||||
require 'liquid/utils'
|
require 'liquid/utils'
|
||||||
require 'liquid/tokenizer'
|
require 'liquid/tokenizer'
|
||||||
require 'liquid/parse_context'
|
require 'liquid/parse_context'
|
||||||
require 'liquid/partial_cache'
|
|
||||||
|
|
||||||
# Load all the tags of the standard library
|
# Load all the tags of the standard library
|
||||||
#
|
#
|
||||||
|
|||||||
@@ -12,41 +12,26 @@ module Liquid
|
|||||||
#
|
#
|
||||||
# context['bob'] #=> nil class Context
|
# context['bob'] #=> nil class Context
|
||||||
class Context
|
class Context
|
||||||
attr_reader :scopes, :errors, :registers, :environments, :resource_limits, :static_registers, :static_environments
|
attr_reader :scopes, :errors, :registers, :environments, :resource_limits
|
||||||
attr_accessor :exception_renderer, :template_name, :partial, :global_filter, :strict_variables, :strict_filters
|
attr_accessor :exception_renderer, :template_name, :partial, :global_filter, :strict_variables, :strict_filters
|
||||||
|
|
||||||
# rubocop:disable Metrics/ParameterLists
|
def initialize(environments = {}, outer_scope = {}, registers = {}, rethrow_errors = false, resource_limits = nil)
|
||||||
def self.build(environments: {}, outer_scope: {}, registers: {}, rethrow_errors: false, resource_limits: nil, static_registers: {}, static_environments: {})
|
@environments = [environments].flatten
|
||||||
new(environments, outer_scope, registers, rethrow_errors, resource_limits, static_registers, static_environments)
|
@scopes = [(outer_scope || {})]
|
||||||
end
|
@registers = registers
|
||||||
|
@errors = []
|
||||||
def initialize(environments = {}, outer_scope = {}, registers = {}, rethrow_errors = false, resource_limits = nil, static_registers = {}, static_environments = {})
|
@interrupts = []
|
||||||
@environments = [environments]
|
@filters = []
|
||||||
@environments.flatten!
|
@global_filter = nil
|
||||||
|
@partial = false
|
||||||
@static_environments = [static_environments].flat_map(&:freeze).freeze
|
@strict_variables = false
|
||||||
@scopes = [(outer_scope || {})]
|
@resource_limits = resource_limits || ResourceLimits.new(Template.default_resource_limits)
|
||||||
@registers = registers
|
|
||||||
@static_registers = static_registers.freeze
|
|
||||||
@errors = []
|
|
||||||
@partial = false
|
|
||||||
@strict_variables = false
|
|
||||||
@resource_limits = resource_limits || ResourceLimits.new(Template.default_resource_limits)
|
|
||||||
@base_scope_depth = 0
|
|
||||||
squash_instance_assigns_with_environments
|
|
||||||
|
|
||||||
@this_stack_used = false
|
|
||||||
|
|
||||||
self.exception_renderer = Template.default_exception_renderer
|
self.exception_renderer = Template.default_exception_renderer
|
||||||
if rethrow_errors
|
self.exception_renderer = ->(e) { raise } if rethrow_errors
|
||||||
self.exception_renderer = ->(e) { raise }
|
|
||||||
end
|
|
||||||
|
|
||||||
@interrupts = []
|
squash_instance_assigns_with_environments
|
||||||
@filters = []
|
|
||||||
@global_filter = nil
|
|
||||||
end
|
end
|
||||||
# rubocop:enable Metrics/ParameterLists
|
|
||||||
|
|
||||||
def warnings
|
def warnings
|
||||||
@warnings ||= []
|
@warnings ||= []
|
||||||
@@ -98,9 +83,9 @@ module Liquid
|
|||||||
end
|
end
|
||||||
|
|
||||||
# Push new local scope on the stack. use <tt>Context#stack</tt> instead
|
# Push new local scope on the stack. use <tt>Context#stack</tt> instead
|
||||||
def push(new_scope = {})
|
def push
|
||||||
@scopes.unshift(new_scope)
|
@scopes.unshift({})
|
||||||
check_overflow
|
raise StackLevelError, "Nesting too deep".freeze if @scopes.length > (Block::MAX_DEPTH + 1)
|
||||||
end
|
end
|
||||||
|
|
||||||
# Merge a hash of variables in the current local scope
|
# Merge a hash of variables in the current local scope
|
||||||
@@ -122,50 +107,15 @@ module Liquid
|
|||||||
# end
|
# end
|
||||||
#
|
#
|
||||||
# context['var] #=> nil
|
# context['var] #=> nil
|
||||||
def stack(new_scope = nil)
|
def stack
|
||||||
old_stack_used = @this_stack_used
|
push
|
||||||
if new_scope
|
|
||||||
push(new_scope)
|
|
||||||
@this_stack_used = true
|
|
||||||
else
|
|
||||||
@this_stack_used = false
|
|
||||||
end
|
|
||||||
|
|
||||||
yield
|
yield
|
||||||
ensure
|
ensure
|
||||||
pop if @this_stack_used
|
pop
|
||||||
@this_stack_used = old_stack_used
|
|
||||||
end
|
|
||||||
|
|
||||||
# Creates a new context inheriting resource limits, filters, environment etc.,
|
|
||||||
# but with an isolated scope.
|
|
||||||
def new_isolated_subcontext
|
|
||||||
check_overflow
|
|
||||||
|
|
||||||
Context.build(
|
|
||||||
resource_limits: resource_limits,
|
|
||||||
static_environments: static_environments,
|
|
||||||
static_registers: static_registers
|
|
||||||
).tap do |subcontext|
|
|
||||||
subcontext.base_scope_depth = base_scope_depth + 1
|
|
||||||
subcontext.exception_renderer = exception_renderer
|
|
||||||
subcontext.filters = @filters
|
|
||||||
subcontext.strainer = nil
|
|
||||||
subcontext.errors = errors
|
|
||||||
subcontext.warnings = warnings
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def clear_instance_assigns
|
|
||||||
@scopes[0] = {}
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# Only allow String, Numeric, Hash, Array, Proc, Boolean or <tt>Liquid::Drop</tt>
|
# Only allow String, Numeric, Hash, Array, Proc, Boolean or <tt>Liquid::Drop</tt>
|
||||||
def []=(key, value)
|
def []=(key, value)
|
||||||
unless @this_stack_used
|
|
||||||
@this_stack_used = true
|
|
||||||
push({})
|
|
||||||
end
|
|
||||||
@scopes[0][key] = value
|
@scopes[0][key] = value
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -193,15 +143,12 @@ module Liquid
|
|||||||
def find_variable(key, raise_on_not_found: true)
|
def find_variable(key, raise_on_not_found: true)
|
||||||
# This was changed from find() to find_index() because this is a very hot
|
# This was changed from find() to find_index() because this is a very hot
|
||||||
# path and find_index() is optimized in MRI to reduce object allocation
|
# path and find_index() is optimized in MRI to reduce object allocation
|
||||||
index = @scopes.find_index { |s| s.key?(key) }
|
|
||||||
|
|
||||||
variable = if index
|
scope = (index = @scopes.find_index { |s| s.key?(key) }) && @scopes[index]
|
||||||
lookup_and_evaluate(@scopes[index], key, raise_on_not_found: raise_on_not_found)
|
scope ||= (index = @environments.find_index { |s| s.key?(key) }) && @environments[index]
|
||||||
else
|
scope ||= {}
|
||||||
try_variable_find_in_environments(key, raise_on_not_found: raise_on_not_found)
|
|
||||||
end
|
|
||||||
|
|
||||||
variable = variable.to_liquid
|
variable = lookup_and_evaluate(scope, key, raise_on_not_found: raise_on_not_found).to_liquid
|
||||||
variable.context = self if variable.respond_to?(:context=)
|
variable.context = self if variable.respond_to?(:context=)
|
||||||
|
|
||||||
variable
|
variable
|
||||||
@@ -221,38 +168,8 @@ module Liquid
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
protected
|
|
||||||
|
|
||||||
attr_writer :base_scope_depth, :warnings, :errors, :strainer, :filters
|
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
attr_reader :base_scope_depth
|
|
||||||
|
|
||||||
def try_variable_find_in_environments(key, raise_on_not_found:)
|
|
||||||
@environments.each do |environment|
|
|
||||||
found_variable = lookup_and_evaluate(environment, key, raise_on_not_found: raise_on_not_found)
|
|
||||||
if !found_variable.nil? || @strict_variables && raise_on_not_found
|
|
||||||
return found_variable
|
|
||||||
end
|
|
||||||
end
|
|
||||||
@static_environments.each do |environment|
|
|
||||||
found_variable = lookup_and_evaluate(environment, key, raise_on_not_found: raise_on_not_found)
|
|
||||||
if !found_variable.nil? || @strict_variables && raise_on_not_found
|
|
||||||
return found_variable
|
|
||||||
end
|
|
||||||
end
|
|
||||||
nil
|
|
||||||
end
|
|
||||||
|
|
||||||
def check_overflow
|
|
||||||
raise StackLevelError, "Nesting too deep".freeze if overflow?
|
|
||||||
end
|
|
||||||
|
|
||||||
def overflow?
|
|
||||||
base_scope_depth + @scopes.length > Block::MAX_DEPTH
|
|
||||||
end
|
|
||||||
|
|
||||||
def internal_error
|
def internal_error
|
||||||
# raise and catch to set backtrace and cause on exception
|
# raise and catch to set backtrace and cause on exception
|
||||||
raise Liquid::InternalError, 'internal'
|
raise Liquid::InternalError, 'internal'
|
||||||
|
|||||||
@@ -22,6 +22,5 @@
|
|||||||
tag_never_closed: "'%{block_name}' tag was never closed"
|
tag_never_closed: "'%{block_name}' tag was never closed"
|
||||||
meta_syntax_error: "Liquid syntax error: #{e.message}"
|
meta_syntax_error: "Liquid syntax error: #{e.message}"
|
||||||
table_row: "Syntax Error in 'table_row loop' - Valid syntax: table_row [item] in [collection] cols=3"
|
table_row: "Syntax Error in 'table_row loop' - Valid syntax: table_row [item] in [collection] cols=3"
|
||||||
render: "Syntax error in tag 'render' - Template name must be a quoted string"
|
|
||||||
argument:
|
argument:
|
||||||
include: "Argument error in tag 'include' - Illegal template name"
|
include: "Argument error in tag 'include' - Illegal template name"
|
||||||
|
|||||||
@@ -1,18 +0,0 @@
|
|||||||
module Liquid
|
|
||||||
class PartialCache
|
|
||||||
def self.load(template_name, context:, parse_context:)
|
|
||||||
cached_partials = (context.registers[:cached_partials] ||= {})
|
|
||||||
cached = cached_partials[template_name]
|
|
||||||
return cached if cached
|
|
||||||
|
|
||||||
file_system = (context.registers[:file_system] ||= Liquid::Template.file_system)
|
|
||||||
source = file_system.read_template_file(template_name)
|
|
||||||
parse_context.partial = true
|
|
||||||
|
|
||||||
partial = Liquid::Template.parse(source, parse_context)
|
|
||||||
cached_partials[template_name] = partial
|
|
||||||
ensure
|
|
||||||
parse_context.partial = false
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
@@ -16,7 +16,7 @@ module Liquid
|
|||||||
end
|
end
|
||||||
|
|
||||||
def render(context)
|
def render(context)
|
||||||
@variable.render_to_output_buffer(context, '')
|
@variable.render(context)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -46,12 +46,7 @@ module Liquid
|
|||||||
template_name = context.evaluate(@template_name_expr)
|
template_name = context.evaluate(@template_name_expr)
|
||||||
raise ArgumentError.new(options[:locale].t("errors.argument.include")) unless template_name
|
raise ArgumentError.new(options[:locale].t("errors.argument.include")) unless template_name
|
||||||
|
|
||||||
partial = PartialCache.load(
|
partial = load_cached_partial(template_name, context)
|
||||||
template_name,
|
|
||||||
context: context,
|
|
||||||
parse_context: parse_context
|
|
||||||
)
|
|
||||||
|
|
||||||
context_variable_name = template_name.split('/'.freeze).last
|
context_variable_name = template_name.split('/'.freeze).last
|
||||||
|
|
||||||
variable = if @variable_name_expr
|
variable = if @variable_name_expr
|
||||||
@@ -88,9 +83,35 @@ module Liquid
|
|||||||
output
|
output
|
||||||
end
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
alias_method :parse_context, :options
|
alias_method :parse_context, :options
|
||||||
private :parse_context
|
private :parse_context
|
||||||
|
|
||||||
|
def load_cached_partial(template_name, context)
|
||||||
|
cached_partials = context.registers[:cached_partials] || {}
|
||||||
|
|
||||||
|
if cached = cached_partials[template_name]
|
||||||
|
return cached
|
||||||
|
end
|
||||||
|
source = read_template_from_file_system(context)
|
||||||
|
begin
|
||||||
|
parse_context.partial = true
|
||||||
|
partial = Liquid::Template.parse(source, parse_context)
|
||||||
|
ensure
|
||||||
|
parse_context.partial = false
|
||||||
|
end
|
||||||
|
cached_partials[template_name] = partial
|
||||||
|
context.registers[:cached_partials] = cached_partials
|
||||||
|
partial
|
||||||
|
end
|
||||||
|
|
||||||
|
def read_template_from_file_system(context)
|
||||||
|
file_system = context.registers[:file_system] || Liquid::Template.file_system
|
||||||
|
|
||||||
|
file_system.read_template_file(context.evaluate(@template_name_expr))
|
||||||
|
end
|
||||||
|
|
||||||
class ParseTreeVisitor < Liquid::ParseTreeVisitor
|
class ParseTreeVisitor < Liquid::ParseTreeVisitor
|
||||||
def children
|
def children
|
||||||
[
|
[
|
||||||
|
|||||||
@@ -23,7 +23,6 @@ module Liquid
|
|||||||
def render_to_output_buffer(context, output)
|
def render_to_output_buffer(context, output)
|
||||||
value = context.environments.first[@variable] ||= 0
|
value = context.environments.first[@variable] ||= 0
|
||||||
context.environments.first[@variable] = value + 1
|
context.environments.first[@variable] = value + 1
|
||||||
|
|
||||||
output << value.to_s
|
output << value.to_s
|
||||||
output
|
output
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,54 +0,0 @@
|
|||||||
module Liquid
|
|
||||||
class Render < Tag
|
|
||||||
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
|
|
||||||
|
|
||||||
template_name = $1
|
|
||||||
|
|
||||||
@template_name_expr = Expression.parse(template_name)
|
|
||||||
|
|
||||||
@attributes = {}
|
|
||||||
markup.scan(TagAttributes) do |key, value|
|
|
||||||
@attributes[key] = Expression.parse(value)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
partial = PartialCache.load(
|
|
||||||
template_name,
|
|
||||||
context: context,
|
|
||||||
parse_context: parse_context
|
|
||||||
)
|
|
||||||
|
|
||||||
inner_context = context.new_isolated_subcontext
|
|
||||||
inner_context.template_name = template_name
|
|
||||||
inner_context.partial = true
|
|
||||||
@attributes.each do |key, value|
|
|
||||||
inner_context[key] = context.evaluate(value)
|
|
||||||
end
|
|
||||||
partial.render_to_output_buffer(inner_context, output)
|
|
||||||
|
|
||||||
output
|
|
||||||
end
|
|
||||||
|
|
||||||
class ParseTreeVisitor < Liquid::ParseTreeVisitor
|
|
||||||
def children
|
|
||||||
[
|
|
||||||
@node.template_name_expr,
|
|
||||||
] + @node.attributes.values
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
Template.register_tag('render'.freeze, Render)
|
|
||||||
end
|
|
||||||
@@ -16,7 +16,7 @@ Gem::Specification.new do |s|
|
|||||||
s.license = "MIT"
|
s.license = "MIT"
|
||||||
# s.description = "A secure, non-evaling end user template engine with aesthetic markup."
|
# s.description = "A secure, non-evaling end user template engine with aesthetic markup."
|
||||||
|
|
||||||
s.required_ruby_version = ">= 2.4.0"
|
s.required_ruby_version = ">= 2.1.0"
|
||||||
s.required_rubygems_version = ">= 1.3.7"
|
s.required_rubygems_version = ">= 1.3.7"
|
||||||
|
|
||||||
s.test_files = Dir.glob("{test}/**/*")
|
s.test_files = Dir.glob("{test}/**/*")
|
||||||
|
|||||||
@@ -30,7 +30,6 @@ class Profiler
|
|||||||
@retained << "#{report.scale_bytes(report.total_retained_memsize)} (#{report.total_retained} objects)"
|
@retained << "#{report.scale_bytes(report.total_retained_memsize)} (#{report.total_retained} objects)"
|
||||||
|
|
||||||
return if ENV['CI']
|
return if ENV['CI']
|
||||||
|
|
||||||
require 'fileutils'
|
require 'fileutils'
|
||||||
report_file = File.join(REPORTS_DIR, "#{sanitize(phase)}.txt")
|
report_file = File.join(REPORTS_DIR, "#{sanitize(phase)}.txt")
|
||||||
FileUtils.mkdir_p(REPORTS_DIR)
|
FileUtils.mkdir_p(REPORTS_DIR)
|
||||||
|
|||||||
@@ -5,72 +5,72 @@ class LiquidTagTest < Minitest::Test
|
|||||||
|
|
||||||
def test_liquid_tag
|
def test_liquid_tag
|
||||||
assert_template_result('1 2 3', <<~LIQUID, 'array' => [1, 2, 3])
|
assert_template_result('1 2 3', <<~LIQUID, 'array' => [1, 2, 3])
|
||||||
{%- liquid
|
{%- liquid
|
||||||
echo array | join: " "
|
echo array | join: " "
|
||||||
-%}
|
-%}
|
||||||
LIQUID
|
LIQUID
|
||||||
|
|
||||||
assert_template_result('1 2 3', <<~LIQUID, 'array' => [1, 2, 3])
|
assert_template_result('1 2 3', <<~LIQUID, 'array' => [1, 2, 3])
|
||||||
{%- liquid
|
{%- liquid
|
||||||
for value in array
|
for value in array
|
||||||
echo value
|
echo value
|
||||||
unless forloop.last
|
unless forloop.last
|
||||||
echo " "
|
echo " "
|
||||||
endunless
|
endunless
|
||||||
endfor
|
endfor
|
||||||
-%}
|
-%}
|
||||||
LIQUID
|
LIQUID
|
||||||
|
|
||||||
assert_template_result('4 8 12 6', <<~LIQUID, 'array' => [1, 2, 3])
|
assert_template_result('4 8 12 6', <<~LIQUID, 'array' => [1, 2, 3])
|
||||||
{%- liquid
|
{%- liquid
|
||||||
for value in array
|
for value in array
|
||||||
assign double_value = value | times: 2
|
assign double_value = value | times: 2
|
||||||
echo double_value | times: 2
|
echo double_value | times: 2
|
||||||
unless forloop.last
|
unless forloop.last
|
||||||
echo " "
|
echo " "
|
||||||
endunless
|
endunless
|
||||||
endfor
|
endfor
|
||||||
|
|
||||||
echo " "
|
echo " "
|
||||||
echo double_value
|
echo double_value
|
||||||
-%}
|
-%}
|
||||||
LIQUID
|
LIQUID
|
||||||
|
|
||||||
assert_template_result('abc', <<~LIQUID)
|
assert_template_result('abc', <<~LIQUID)
|
||||||
{%- liquid echo "a" -%}
|
{%- liquid echo "a" -%}
|
||||||
b
|
b
|
||||||
{%- liquid echo "c" -%}
|
{%- liquid echo "c" -%}
|
||||||
LIQUID
|
LIQUID
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_liquid_tag_errors
|
def test_liquid_tag_errors
|
||||||
assert_match_syntax_error("syntax error (line 1): Unknown tag 'error'", <<~LIQUID)
|
assert_match_syntax_error("syntax error (line 1): Unknown tag 'error'", <<~LIQUID)
|
||||||
{%- liquid error no such tag -%}
|
{%- liquid error no such tag -%}
|
||||||
LIQUID
|
LIQUID
|
||||||
|
|
||||||
assert_match_syntax_error("syntax error (line 7): Unknown tag 'error'", <<~LIQUID)
|
assert_match_syntax_error("syntax error (line 7): Unknown tag 'error'", <<~LIQUID)
|
||||||
{{ test }}
|
{{ test }}
|
||||||
|
|
||||||
{%-
|
{%-
|
||||||
liquid
|
liquid
|
||||||
for value in array
|
for value in array
|
||||||
|
|
||||||
error no such tag
|
error no such tag
|
||||||
endfor
|
endfor
|
||||||
-%}
|
-%}
|
||||||
LIQUID
|
LIQUID
|
||||||
|
|
||||||
assert_match_syntax_error("syntax error (line 2): Unknown tag '!!! the guards are vigilant'", <<~LIQUID)
|
assert_match_syntax_error("syntax error (line 2): Unknown tag '!!! the guards are vigilant'", <<~LIQUID)
|
||||||
{%- liquid
|
{%- liquid
|
||||||
!!! the guards are vigilant
|
!!! the guards are vigilant
|
||||||
-%}
|
-%}
|
||||||
LIQUID
|
LIQUID
|
||||||
|
|
||||||
assert_match_syntax_error("syntax error (line 4): 'for' tag was never closed", <<~LIQUID)
|
assert_match_syntax_error("syntax error (line 4): 'for' tag was never closed", <<~LIQUID)
|
||||||
{%- liquid
|
{%- liquid
|
||||||
for value in array
|
for value in array
|
||||||
echo 'forgot to close the for tag'
|
echo 'forgot to close the for tag'
|
||||||
-%}
|
-%}
|
||||||
LIQUID
|
LIQUID
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -81,24 +81,24 @@ class LiquidTagTest < Minitest::Test
|
|||||||
|
|
||||||
def test_cannot_open_blocks_living_past_a_liquid_tag
|
def test_cannot_open_blocks_living_past_a_liquid_tag
|
||||||
assert_match_syntax_error("syntax error (line 3): 'if' tag was never closed", <<~LIQUID)
|
assert_match_syntax_error("syntax error (line 3): 'if' tag was never closed", <<~LIQUID)
|
||||||
{%- liquid
|
{%- liquid
|
||||||
if true
|
if true
|
||||||
-%}
|
-%}
|
||||||
{%- endif -%}
|
{%- endif -%}
|
||||||
LIQUID
|
LIQUID
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_quirk_can_close_blocks_created_before_a_liquid_tag
|
def test_quirk_can_close_blocks_created_before_a_liquid_tag
|
||||||
assert_template_result("42", <<~LIQUID)
|
assert_template_result("42", <<~LIQUID)
|
||||||
{%- if true -%}
|
{%- if true -%}
|
||||||
42
|
42
|
||||||
{%- liquid endif -%}
|
{%- liquid endif -%}
|
||||||
LIQUID
|
LIQUID
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_liquid_tag_in_raw
|
def test_liquid_tag_in_raw
|
||||||
assert_template_result("{% liquid echo 'test' %}\n", <<~LIQUID)
|
assert_template_result("{% liquid echo 'test' %}\n", <<~LIQUID)
|
||||||
{% raw %}{% liquid echo 'test' %}{% endraw %}
|
{% raw %}{% liquid echo 'test' %}{% endraw %}
|
||||||
LIQUID
|
LIQUID
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,149 +0,0 @@
|
|||||||
require 'test_helper'
|
|
||||||
|
|
||||||
class RenderTagTest < Minitest::Test
|
|
||||||
include Liquid
|
|
||||||
|
|
||||||
def test_render_with_no_arguments
|
|
||||||
Liquid::Template.file_system = StubFileSystem.new('source' => 'rendered content')
|
|
||||||
assert_template_result 'rendered content', '{% render "source" %}'
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_render_tag_looks_for_file_system_in_registers_first
|
|
||||||
file_system = StubFileSystem.new('pick_a_source' => 'from register file system')
|
|
||||||
assert_equal 'from register file system',
|
|
||||||
Template.parse('{% render "pick_a_source" %}').render!({}, registers: { file_system: file_system })
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_render_passes_named_arguments_into_inner_scope
|
|
||||||
Liquid::Template.file_system = StubFileSystem.new('product' => '{{ inner_product.title }}')
|
|
||||||
assert_template_result 'My Product', '{% render "product", inner_product: outer_product %}',
|
|
||||||
'outer_product' => { 'title' => 'My Product' }
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_render_accepts_literals_as_arguments
|
|
||||||
Liquid::Template.file_system = StubFileSystem.new('snippet' => '{{ price }}')
|
|
||||||
assert_template_result '123', '{% render "snippet", price: 123 %}'
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_render_accepts_multiple_named_arguments
|
|
||||||
Liquid::Template.file_system = StubFileSystem.new('snippet' => '{{ one }} {{ two }}')
|
|
||||||
assert_template_result '1 2', '{% render "snippet", one: 1, two: 2 %}'
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_render_does_not_inherit_parent_scope_variables
|
|
||||||
Liquid::Template.file_system = StubFileSystem.new('snippet' => '{{ outer_variable }}')
|
|
||||||
assert_template_result '', '{% assign outer_variable = "should not be visible" %}{% render "snippet" %}'
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_render_does_not_inherit_variable_with_same_name_as_snippet
|
|
||||||
Liquid::Template.file_system = StubFileSystem.new('snippet' => '{{ snippet }}')
|
|
||||||
assert_template_result '', "{% assign snippet = 'should not be visible' %}{% render 'snippet' %}"
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_render_sets_the_correct_template_name_for_errors
|
|
||||||
Liquid::Template.file_system = StubFileSystem.new('snippet' => '{{ unsafe }}')
|
|
||||||
|
|
||||||
with_taint_mode :error do
|
|
||||||
template = Liquid::Template.parse('{% render "snippet", unsafe: unsafe %}')
|
|
||||||
context = Context.new('unsafe' => (+'unsafe').tap(&:taint))
|
|
||||||
template.render(context)
|
|
||||||
|
|
||||||
assert_equal [Liquid::TaintedError], template.errors.map(&:class)
|
|
||||||
assert_equal 'snippet', template.errors.first.template_name
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_render_sets_the_correct_template_name_for_warnings
|
|
||||||
Liquid::Template.file_system = StubFileSystem.new('snippet' => '{{ unsafe }}')
|
|
||||||
|
|
||||||
with_taint_mode :warn do
|
|
||||||
template = Liquid::Template.parse('{% render "snippet", unsafe: unsafe %}')
|
|
||||||
context = Context.new('unsafe' => (+'unsafe').tap(&:taint))
|
|
||||||
template.render(context)
|
|
||||||
|
|
||||||
assert_equal [Liquid::TaintedError], context.warnings.map(&:class)
|
|
||||||
assert_equal 'snippet', context.warnings.first.template_name
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_render_does_not_mutate_parent_scope
|
|
||||||
Liquid::Template.file_system = StubFileSystem.new('snippet' => '{% assign inner = 1 %}')
|
|
||||||
assert_template_result '', "{% render 'snippet' %}{{ inner }}"
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_nested_render_tag
|
|
||||||
Liquid::Template.file_system = StubFileSystem.new(
|
|
||||||
'one' => "one {% render 'two' %}",
|
|
||||||
'two' => 'two'
|
|
||||||
)
|
|
||||||
assert_template_result 'one two', "{% render 'one' %}"
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_recursively_rendered_template_does_not_produce_endless_loop
|
|
||||||
Liquid::Template.file_system = StubFileSystem.new('loop' => '{% render "loop" %}')
|
|
||||||
|
|
||||||
assert_raises Liquid::StackLevelError do
|
|
||||||
Template.parse('{% render "loop" %}').render!
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_includes_and_renders_count_towards_the_same_recursion_limit
|
|
||||||
Liquid::Template.file_system = StubFileSystem.new(
|
|
||||||
'loop_render' => '{% render "loop_include" %}',
|
|
||||||
'loop_include' => '{% include "loop_render" %}'
|
|
||||||
)
|
|
||||||
|
|
||||||
assert_raises Liquid::StackLevelError do
|
|
||||||
Template.parse('{% render "loop_include" %}').render!
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_dynamically_choosen_templates_are_not_allowed
|
|
||||||
Liquid::Template.file_system = StubFileSystem.new('snippet' => 'should not be rendered')
|
|
||||||
|
|
||||||
assert_raises Liquid::SyntaxError do
|
|
||||||
Liquid::Template.parse("{% assign name = 'snippet' %}{% render name %}")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_include_tag_caches_second_read_of_same_partial
|
|
||||||
file_system = StubFileSystem.new('snippet' => 'echo')
|
|
||||||
assert_equal 'echoecho',
|
|
||||||
Template.parse('{% render "snippet" %}{% render "snippet" %}')
|
|
||||||
.render!({}, registers: { file_system: file_system })
|
|
||||||
assert_equal 1, file_system.file_read_count
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_render_tag_doesnt_cache_partials_across_renders
|
|
||||||
file_system = StubFileSystem.new('snippet' => 'my message')
|
|
||||||
|
|
||||||
assert_equal 'my message',
|
|
||||||
Template.parse('{% include "snippet" %}').render!({}, registers: { file_system: file_system })
|
|
||||||
assert_equal 1, file_system.file_read_count
|
|
||||||
|
|
||||||
assert_equal 'my message',
|
|
||||||
Template.parse('{% include "snippet" %}').render!({}, registers: { file_system: file_system })
|
|
||||||
assert_equal 2, file_system.file_read_count
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_render_tag_within_if_statement
|
|
||||||
Liquid::Template.file_system = StubFileSystem.new('snippet' => 'my message')
|
|
||||||
assert_template_result 'my message', '{% if true %}{% render "snippet" %}{% endif %}'
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_break_through_render
|
|
||||||
Liquid::Template.file_system = StubFileSystem.new('break' => '{% break %}')
|
|
||||||
assert_template_result '1', '{% for i in (1..3) %}{{ i }}{% break %}{{ i }}{% endfor %}'
|
|
||||||
assert_template_result '112233', '{% for i in (1..3) %}{{ i }}{% render "break" %}{{ i }}{% endfor %}'
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_increment_is_isolated_between_renders
|
|
||||||
Liquid::Template.file_system = StubFileSystem.new('incr' => '{% increment %}')
|
|
||||||
assert_template_result '010', '{% increment %}{% increment %}{% render "incr" %}'
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_decrement_is_isolated_between_renders
|
|
||||||
Liquid::Template.file_system = StubFileSystem.new('decr' => '{% decrement %}')
|
|
||||||
assert_template_result '-1-2-1', '{% decrement %}{% decrement %}{% render "decr" %}'
|
|
||||||
end
|
|
||||||
end
|
|
||||||
@@ -80,10 +80,7 @@ class VariableTest < Minitest::Test
|
|||||||
assigns['test'] = 'Tobi'
|
assigns['test'] = 'Tobi'
|
||||||
assert_equal 'Hello Tobi', template.render!(assigns)
|
assert_equal 'Hello Tobi', template.render!(assigns)
|
||||||
assigns.delete('test')
|
assigns.delete('test')
|
||||||
e = assert_raises(RuntimeError) do
|
assert_equal "Hello ", template.render!(assigns)
|
||||||
template.render!(assigns)
|
|
||||||
end
|
|
||||||
assert_equal "Unknown variable 'test'", e.message
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_multiline_variable
|
def test_multiline_variable
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ if env_mode = ENV['LIQUID_PARSER_MODE']
|
|||||||
end
|
end
|
||||||
Liquid::Template.error_mode = mode
|
Liquid::Template.error_mode = mode
|
||||||
|
|
||||||
if ENV['LIQUID_C'] == '1'
|
if ENV['LIQUID-C'] == '1'
|
||||||
puts "-- LIQUID C"
|
puts "-- LIQUID C"
|
||||||
require 'liquid/c'
|
require 'liquid/c'
|
||||||
end
|
end
|
||||||
@@ -121,17 +121,3 @@ class ErrorDrop < Liquid::Drop
|
|||||||
raise Exception, 'exception'
|
raise Exception, 'exception'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
class StubFileSystem
|
|
||||||
attr_reader :file_read_count
|
|
||||||
|
|
||||||
def initialize(values)
|
|
||||||
@file_read_count = 0
|
|
||||||
@values = values
|
|
||||||
end
|
|
||||||
|
|
||||||
def read_template_file(template_path)
|
|
||||||
@file_read_count += 1
|
|
||||||
@values.fetch(template_path)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|||||||
@@ -468,79 +468,11 @@ class ContextUnitTest < Minitest::Test
|
|||||||
assert_equal 'hi filtered', context.apply_global_filter('hi')
|
assert_equal 'hi filtered', context.apply_global_filter('hi')
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_static_environments_are_read_with_lower_priority_than_environments
|
|
||||||
context = Context.build(
|
|
||||||
static_environments: { 'shadowed' => 'static', 'unshadowed' => 'static' },
|
|
||||||
environments: { 'shadowed' => 'dynamic' }
|
|
||||||
)
|
|
||||||
|
|
||||||
assert_equal 'dynamic', context['shadowed']
|
|
||||||
assert_equal 'static', context['unshadowed']
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_apply_global_filter_when_no_global_filter_exist
|
def test_apply_global_filter_when_no_global_filter_exist
|
||||||
context = Context.new
|
context = Context.new
|
||||||
assert_equal 'hi', context.apply_global_filter('hi')
|
assert_equal 'hi', context.apply_global_filter('hi')
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_new_isolated_subcontext_does_not_inherit_variables
|
|
||||||
super_context = Context.new
|
|
||||||
super_context['my_variable'] = 'some value'
|
|
||||||
subcontext = super_context.new_isolated_subcontext
|
|
||||||
|
|
||||||
assert_nil subcontext['my_variable']
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_new_isolated_subcontext_inherits_static_environment
|
|
||||||
super_context = Context.build(static_environments: { 'my_environment_value' => 'my value' })
|
|
||||||
subcontext = super_context.new_isolated_subcontext
|
|
||||||
|
|
||||||
assert_equal 'my value', subcontext['my_environment_value']
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_new_isolated_subcontext_inherits_resource_limits
|
|
||||||
resource_limits = ResourceLimits.new({})
|
|
||||||
super_context = Context.new({}, {}, {}, false, resource_limits)
|
|
||||||
subcontext = super_context.new_isolated_subcontext
|
|
||||||
assert_equal resource_limits, subcontext.resource_limits
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_new_isolated_subcontext_inherits_exception_renderer
|
|
||||||
super_context = Context.new
|
|
||||||
super_context.exception_renderer = ->(_e) { 'my exception message' }
|
|
||||||
subcontext = super_context.new_isolated_subcontext
|
|
||||||
assert_equal 'my exception message', subcontext.handle_error(Liquid::Error.new)
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_new_isolated_subcontext_does_not_inherit_non_static_registers
|
|
||||||
registers = {
|
|
||||||
my_register: :my_value
|
|
||||||
}
|
|
||||||
super_context = Context.new({}, {}, registers)
|
|
||||||
subcontext = super_context.new_isolated_subcontext
|
|
||||||
assert_nil subcontext.registers[:my_register]
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_new_isolated_subcontext_inherits_static_registers
|
|
||||||
super_context = Context.build(static_registers: { my_register: :my_value })
|
|
||||||
subcontext = super_context.new_isolated_subcontext
|
|
||||||
assert_equal :my_value, subcontext.static_registers[:my_register]
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_new_isolated_subcontext_inherits_filters
|
|
||||||
my_filter = Module.new do
|
|
||||||
def my_filter(*)
|
|
||||||
'my filter result'
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
super_context = Context.new
|
|
||||||
super_context.add_filters([my_filter])
|
|
||||||
subcontext = super_context.new_isolated_subcontext
|
|
||||||
template = Template.parse('{{ 123 | my_filter }}')
|
|
||||||
assert_equal 'my filter result', template.render(subcontext)
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def assert_no_object_allocations
|
def assert_no_object_allocations
|
||||||
|
|||||||
@@ -1,91 +0,0 @@
|
|||||||
require 'test_helper'
|
|
||||||
|
|
||||||
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'),
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
partial = Liquid::PartialCache.load(
|
|
||||||
'my_partial',
|
|
||||||
context: context,
|
|
||||||
parse_context: Liquid::ParseContext.new
|
|
||||||
)
|
|
||||||
|
|
||||||
assert_equal 'my partial body', partial.render
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_reads_from_the_file_system_only_once_per_file
|
|
||||||
file_system = StubFileSystem.new('my_partial' => 'some partial body')
|
|
||||||
context = Liquid::Context.build(
|
|
||||||
registers: { file_system: file_system }
|
|
||||||
)
|
|
||||||
|
|
||||||
2.times do
|
|
||||||
Liquid::PartialCache.load(
|
|
||||||
'my_partial',
|
|
||||||
context: context,
|
|
||||||
parse_context: Liquid::ParseContext.new
|
|
||||||
)
|
|
||||||
end
|
|
||||||
|
|
||||||
assert_equal 1, file_system.file_read_count
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_cache_state_is_stored_per_context
|
|
||||||
parse_context = Liquid::ParseContext.new
|
|
||||||
shared_file_system = StubFileSystem.new(
|
|
||||||
'my_partial' => 'my shared value'
|
|
||||||
)
|
|
||||||
context_one = Liquid::Context.build(
|
|
||||||
registers: {
|
|
||||||
file_system: shared_file_system,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
context_two = Liquid::Context.build(
|
|
||||||
registers: {
|
|
||||||
file_system: shared_file_system,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
2.times do
|
|
||||||
Liquid::PartialCache.load(
|
|
||||||
'my_partial',
|
|
||||||
context: context_one,
|
|
||||||
parse_context: parse_context
|
|
||||||
)
|
|
||||||
end
|
|
||||||
|
|
||||||
Liquid::PartialCache.load(
|
|
||||||
'my_partial',
|
|
||||||
context: context_two,
|
|
||||||
parse_context: parse_context
|
|
||||||
)
|
|
||||||
|
|
||||||
assert_equal 2, shared_file_system.file_read_count
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_cache_is_not_broken_when_a_different_parse_context_is_used
|
|
||||||
file_system = StubFileSystem.new('my_partial' => 'some partial body')
|
|
||||||
context = Liquid::Context.build(
|
|
||||||
registers: { file_system: file_system }
|
|
||||||
)
|
|
||||||
|
|
||||||
Liquid::PartialCache.load(
|
|
||||||
'my_partial',
|
|
||||||
context: context,
|
|
||||||
parse_context: Liquid::ParseContext.new(my_key: 'value one')
|
|
||||||
)
|
|
||||||
Liquid::PartialCache.load(
|
|
||||||
'my_partial',
|
|
||||||
context: context,
|
|
||||||
parse_context: Liquid::ParseContext.new(my_key: 'value two')
|
|
||||||
)
|
|
||||||
|
|
||||||
# Technically what we care about is that the file was parsed twice,
|
|
||||||
# but measuring file reads is an OK proxy for this.
|
|
||||||
assert_equal 1, file_system.file_read_count
|
|
||||||
end
|
|
||||||
end
|
|
||||||
Reference in New Issue
Block a user