Compare commits

..

2 Commits

Author SHA1 Message Date
Mike Angell
cbea19b59f Switch to aliasing methods 2019-08-31 20:32:07 +10:00
Mike Angell
0521d78b30 Initial concept 2019-08-30 14:29:07 +10:00
8 changed files with 102 additions and 15 deletions

View File

@@ -75,7 +75,12 @@ 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
#
Dir["#{__dir__}/liquid/tags/*.rb"].each { |f| require f }
# Load all usage tracking
#
Dir["#{__dir__}/liquid/usages/*.rb"].each { |f| require f }

View File

@@ -15,8 +15,6 @@ module Liquid
attr_reader :scopes, :errors, :registers, :environments, :resource_limits, :static_registers, :static_environments
attr_accessor :exception_renderer, :template_name, :partial, :global_filter, :strict_variables, :strict_filters
BLANK_SCOPE = {}
# 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)
@@ -193,12 +191,15 @@ module Liquid
def find_variable(key, raise_on_not_found: true)
# 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
scope = (index = @scopes.find_index { |s| s.key?(key) }) && @scopes[index]
scope ||= (index = @environments.find_index { |s| s.key?(key) || s.default_proc }) && @environments[index]
scope ||= (index = @static_environments.find_index { |s| s.key?(key) }) && @static_environments[index]
scope ||= BLANK_SCOPE
index = @scopes.find_index { |s| s.key?(key) }
variable = lookup_and_evaluate(scope, key, raise_on_not_found: raise_on_not_found).to_liquid
variable = if index
lookup_and_evaluate(@scopes[index], key, raise_on_not_found: raise_on_not_found)
else
try_variable_find_in_environments(key, raise_on_not_found: raise_on_not_found)
end
variable = variable.to_liquid
variable.context = self if variable.respond_to?(:context=)
variable
@@ -226,6 +227,22 @@ module Liquid
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

23
lib/liquid/usage.rb Normal file
View File

@@ -0,0 +1,23 @@
module Liquid
# Usage is used to store
class Usage
@messages = {}
class << self
def enable
Liquid::Context.send(:alias_method, :try_variable_find_in_environments, :try_variable_find_in_environments_usage)
end
def disable
Liquid::Context.send(:alias_method, :try_variable_find_in_environments, :try_variable_find_in_environments_original)
end
def track(message)
@messages[message] = true
end
def results
@messages
end
end
end
end

View File

@@ -0,0 +1,26 @@
module Liquid
class Context
alias try_variable_find_in_environments_original try_variable_find_in_environments
def try_variable_find_in_environments_usage(key, raise_on_not_found:)
Usage.track("Using try_variable_find_in_environment")
@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
Usage.track("try_variable_find_in_environment reports Nil but responds to key") if environment.key?(key)
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
Usage.track("try_variable_find_in_environment reports Nil but responds to key") if environment.key?(key)
end
nil
end
end
end

View File

@@ -0,0 +1 @@
Liquid::Usage.track("Usage is enabled")

View File

@@ -0,0 +1,14 @@
require 'test_helper'
class TryVariablesUsageTest < Minitest::Test
include Liquid
def test_test_usages
Usage.enable
template = Template.parse(%({{test}}))
assert_equal 'worked', template.render!('test' => 'worked')
assert_equal 'worked wonderfully', template.render!('test' => 'worked wonderfully')
assert_equal true, Usage.results["Using try_variable_find_in_environment"]
Usage.disable
end
end

View File

@@ -0,0 +1,9 @@
require 'test_helper'
class UsageEnabledUsageTest < Minitest::Test
include Liquid
def test_live_usages
assert_equal true, Usage.results["Usage is enabled"]
end
end

View File

@@ -86,14 +86,6 @@ class VariableTest < Minitest::Test
assert_equal "Unknown variable 'test'", e.message
end
def test_environment_falsy
template = Template.parse(%({{ test }}{% assign test = 'bar' %}{{ test }}))
template.assigns['test'] = 'foo'
assert_equal 'foobar', template.render!
assert_equal 'bar', template.render!('test' => nil)
assert_equal 'falsebar', template.render!('test' => false)
end
def test_multiline_variable
assert_equal 'worked', Template.parse("{{\ntest\n}}").render!('test' => 'worked')
end