Skip to content

Commit

Permalink
Merge pull request #1848 from Shopify/env-warn-cleanup
Browse files Browse the repository at this point in the history
clean up all warnings by using new Environment
  • Loading branch information
ggmichaelgo authored Nov 4, 2024
2 parents b0cba0b + c77ff68 commit e5d18c8
Show file tree
Hide file tree
Showing 11 changed files with 73 additions and 79 deletions.
1 change: 0 additions & 1 deletion lib/liquid.rb
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,6 @@ module Liquid
require 'liquid/errors'
require 'liquid/interrupts'
require 'liquid/strainer_template'
require 'liquid/strainer_factory'
require 'liquid/expression'
require 'liquid/context'
require 'liquid/tag'
Expand Down
23 changes: 0 additions & 23 deletions lib/liquid/strainer_factory.rb

This file was deleted.

3 changes: 2 additions & 1 deletion performance/benchmark.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
require_relative 'theme_runner'

RubyVM::YJIT.enable if defined?(RubyVM::YJIT)
Liquid::Template.error_mode = ARGV.first.to_sym if ARGV.first
Liquid::Environment.default.error_mode = ARGV.first.to_sym if ARGV.first

profiler = ThemeRunner.new

Benchmark.ips do |x|
Expand Down
15 changes: 8 additions & 7 deletions performance/shopify/liquid.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,12 @@
require_relative 'tag_filter'
require_relative 'weight_filter'

Liquid::Template.register_tag('paginate', Paginate)
Liquid::Template.register_tag('form', CommentForm)
default_environment = Liquid::Environment.default
default_environment.register_tag('paginate', Paginate)
default_environment.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)
default_environment.register_filter(JsonFilter)
default_environment.register_filter(MoneyFilter)
default_environment.register_filter(WeightFilter)
default_environment.register_filter(ShopFilter)
default_environment.register_filter(TagFilter)
9 changes: 4 additions & 5 deletions test/integration/error_handling_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -203,20 +203,19 @@ def test_default_exception_renderer_with_internal_error
end

def test_setting_default_exception_renderer
old_exception_renderer = Liquid::Template.default_exception_renderer
exceptions = []
Liquid::Template.default_exception_renderer = ->(e) {
default_exception_renderer = ->(e) {
exceptions << e
''
}
template = Liquid::Template.parse('This is a runtime error: {{ errors.argument_error }}')

env = Liquid::Environment.build(exception_renderer: default_exception_renderer)
template = Liquid::Template.parse('This is a runtime error: {{ errors.argument_error }}', environment: env)

output = template.render('errors' => ErrorDrop.new)

assert_equal('This is a runtime error: ', output)
assert_equal([Liquid::ArgumentError], template.errors.map(&:class))
ensure
Liquid::Template.default_exception_renderer = old_exception_renderer if old_exception_renderer
end

def test_setting_exception_renderer_on_environment
Expand Down
2 changes: 1 addition & 1 deletion test/integration/profiler_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ def read_template_file(template_path)
end

def setup
Liquid::Template.file_system = ProfilingFileSystem.new
Liquid::Environment.default.file_system = ProfilingFileSystem.new
end

def test_template_allows_flagging_profiling
Expand Down
26 changes: 15 additions & 11 deletions test/integration/tags/include_tag_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -174,10 +174,10 @@ def read_template_file(_template_path)
end
end

Liquid::Template.file_system = infinite_file_system.new
env = Liquid::Environment.build(file_system: infinite_file_system.new)

assert_raises(Liquid::StackLevelError) do
Template.parse("{% include 'loop' %}").render!
Template.parse("{% include 'loop' %}", environment: env).render!
end
end

Expand Down Expand Up @@ -264,26 +264,27 @@ def test_custom_include_tag_within_if_statement
end

def test_does_not_add_error_in_strict_mode_for_missing_variable
Liquid::Template.file_system = TestFileSystem.new
env = Liquid::Environment.build(file_system: TestFileSystem.new)

a = Liquid::Template.parse(' {% include "nested_template" %}')
a = Liquid::Template.parse(' {% include "nested_template" %}', environment: env)
a.render!
assert_empty(a.errors)
end

def test_passing_options_to_included_templates
Liquid::Template.file_system = TestFileSystem.new
env = Liquid::Environment.build(file_system: TestFileSystem.new)

assert_raises(Liquid::SyntaxError) do
Template.parse("{% include template %}", error_mode: :strict).render!("template" => '{{ "X" || downcase }}')
Template.parse("{% include template %}", error_mode: :strict, environment: env).render!("template" => '{{ "X" || downcase }}')
end
with_error_mode(:lax) do
assert_equal('x', Template.parse("{% include template %}", error_mode: :strict, include_options_blacklist: true).render!("template" => '{{ "X" || downcase }}'))
assert_equal('x', Template.parse("{% include template %}", error_mode: :strict, include_options_blacklist: true, environment: env).render!("template" => '{{ "X" || downcase }}'))
end
assert_raises(Liquid::SyntaxError) do
Template.parse("{% include template %}", error_mode: :strict, include_options_blacklist: [:locale]).render!("template" => '{{ "X" || downcase }}')
Template.parse("{% include template %}", error_mode: :strict, include_options_blacklist: [:locale], environment: env).render!("template" => '{{ "X" || downcase }}')
end
with_error_mode(:lax) do
assert_equal('x', Template.parse("{% include template %}", error_mode: :strict, include_options_blacklist: [:error_mode]).render!("template" => '{{ "X" || downcase }}'))
assert_equal('x', Template.parse("{% include template %}", error_mode: :strict, include_options_blacklist: [:error_mode], environment: env).render!("template" => '{{ "X" || downcase }}'))
end
end

Expand Down Expand Up @@ -334,8 +335,11 @@ def test_including_via_variable_value
end

def test_including_with_strict_variables
Liquid::Template.file_system = StubFileSystem.new({ "simple" => "simple" })
template = Liquid::Template.parse("{% include 'simple' %}", error_mode: :warn)
env = Liquid::Environment.build(
file_system: StubFileSystem.new('simple' => 'simple'),
)

template = Liquid::Template.parse("{% include 'simple' %}", error_mode: :warn, environment: env)
template.render(nil, strict_variables: true)

assert_equal([], template.errors)
Expand Down
13 changes: 8 additions & 5 deletions test/integration/tags/render_tag_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -82,19 +82,22 @@ def test_nested_render_tag
end

def test_recursively_rendered_template_does_not_produce_endless_loop
Liquid::Template.file_system = StubFileSystem.new('loop' => '{% render "loop" %}')
env = Liquid::Environment.build(
file_system: StubFileSystem.new('loop' => '{% render "loop" %}'),
)

assert_raises(Liquid::StackLevelError) do
Template.parse('{% render "loop" %}').render!
Template.parse('{% render "loop" %}', environment: env).render!
end
end

def test_sub_contexts_count_towards_the_same_recursion_limit
Liquid::Template.file_system = StubFileSystem.new(
'loop_render' => '{% render "loop_render" %}',
env = Liquid::Environment.build(
file_system: StubFileSystem.new('loop_render' => '{% render "loop_render" %}'),
)

assert_raises(Liquid::StackLevelError) do
Template.parse('{% render "loop_render" %}').render!
Template.parse('{% render "loop_render" %}', environment: env).render!
end
end

Expand Down
8 changes: 4 additions & 4 deletions test/test_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
puts "-- #{env_mode.upcase} ERROR MODE"
mode = env_mode.to_sym
end
Liquid::Template.error_mode = mode
Liquid::Environment.default.error_mode = mode

if ENV['LIQUID_C'] == '1'
puts "-- LIQUID C"
Expand Down Expand Up @@ -88,11 +88,11 @@ def with_global_filter(*globals, &blk)
end

def with_error_mode(mode)
old_mode = Liquid::Template.error_mode
Liquid::Template.error_mode = mode
old_mode = Liquid::Environment.default.error_mode
Liquid::Environment.default.error_mode = mode
yield
ensure
Liquid::Template.error_mode = old_mode
Liquid::Environment.default.error_mode = old_mode
end

def with_custom_tag(tag_name, tag_class, &block)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

require 'test_helper'

class StrainerFactoryUnitTest < Minitest::Test
class EnvironmentFilterTest < Minitest::Test
include Liquid

module AccessScopeFilters
Expand All @@ -16,33 +16,35 @@ def private_filter
private :private_filter
end

StrainerFactory.add_global_filter(AccessScopeFilters)

module LateAddedFilter
def late_added_filter(_input)
"filtered"
end
end

def setup
@context = Context.build
@environment = Liquid::Environment.build do |env|
env.register_filter(AccessScopeFilters)
end

@context = Context.build(environment: @environment)
end

def test_strainer
strainer = StrainerFactory.create(@context)
strainer = @environment.create_strainer(@context)
assert_equal(5, strainer.invoke('size', 'input'))
assert_equal("public", strainer.invoke("public_filter"))
end

def test_stainer_raises_argument_error
strainer = StrainerFactory.create(@context)
strainer = @environment.create_strainer(@context)
assert_raises(Liquid::ArgumentError) do
strainer.invoke("public_filter", 1)
end
end

def test_stainer_argument_error_contains_backtrace
strainer = StrainerFactory.create(@context)
strainer = @environment.create_strainer(@context)

exception = assert_raises(Liquid::ArgumentError) do
strainer.invoke("public_filter", 1)
Expand All @@ -57,7 +59,7 @@ def test_stainer_argument_error_contains_backtrace
end

def test_strainer_only_invokes_public_filter_methods
strainer = StrainerFactory.create(@context)
strainer = @environment.create_strainer(@context)
assert_equal(false, strainer.class.invokable?('__test__'))
assert_equal(false, strainer.class.invokable?('test'))
assert_equal(false, strainer.class.invokable?('instance_eval'))
Expand All @@ -66,18 +68,18 @@ def test_strainer_only_invokes_public_filter_methods
end

def test_strainer_returns_nil_if_no_filter_method_found
strainer = StrainerFactory.create(@context)
strainer = @environment.create_strainer(@context)
assert_nil(strainer.invoke("private_filter"))
assert_nil(strainer.invoke("undef_the_filter"))
end

def test_strainer_returns_first_argument_if_no_method_and_arguments_given
strainer = StrainerFactory.create(@context)
strainer = @environment.create_strainer(@context)
assert_equal("password", strainer.invoke("undef_the_method", "password"))
end

def test_strainer_only_allows_methods_defined_in_filters
strainer = StrainerFactory.create(@context)
strainer = @environment.create_strainer(@context)
assert_equal("1 + 1", strainer.invoke("instance_eval", "1 + 1"))
assert_equal("puts", strainer.invoke("__send__", "puts", "Hi Mom"))
assert_equal("has_method?", strainer.invoke("invoke", "has_method?", "invoke"))
Expand All @@ -86,16 +88,20 @@ def test_strainer_only_allows_methods_defined_in_filters
def test_strainer_uses_a_class_cache_to_avoid_method_cache_invalidation
a = Module.new
b = Module.new
strainer = StrainerFactory.create(@context, [a, b])

strainer = @environment.create_strainer(@context, [a, b])

assert_kind_of(StrainerTemplate, strainer)
assert_kind_of(a, strainer)
assert_kind_of(b, strainer)
assert_kind_of(Liquid::StandardFilters, strainer)
end

def test_add_global_filter_clears_cache
assert_equal('input', StrainerFactory.create(@context).invoke('late_added_filter', 'input'))
StrainerFactory.add_global_filter(LateAddedFilter)
assert_equal('filtered', StrainerFactory.create(nil).invoke('late_added_filter', 'input'))
assert_equal('input', @environment.create_strainer(@context).invoke('late_added_filter', 'input'))

@environment.register_filter(LateAddedFilter)

assert_equal('filtered', @environment.create_strainer(nil).invoke('late_added_filter', 'input'))
end
end
16 changes: 10 additions & 6 deletions test/unit/strainer_template_unit_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,13 @@ def public_filter
end

def test_add_filter_raises_when_module_privately_overrides_registered_public_methods
strainer = Context.new.strainer

error = assert_raises(Liquid::MethodOverrideError) do
strainer.class.add_filter(PrivateMethodOverrideFilter)
Liquid::Environment.build do |env|
env.register_filter(PublicMethodOverrideFilter)
env.register_filter(PrivateMethodOverrideFilter)
end
end

assert_equal('Liquid error: Filter overrides registered public methods as non public: public_filter', error.message)
end

Expand All @@ -42,11 +44,13 @@ def public_filter
end

def test_add_filter_raises_when_module_overrides_registered_public_method_as_protected
strainer = Context.new.strainer

error = assert_raises(Liquid::MethodOverrideError) do
strainer.class.add_filter(ProtectedMethodOverrideFilter)
Liquid::Environment.build do |env|
env.register_filter(PublicMethodOverrideFilter)
env.register_filter(ProtectedMethodOverrideFilter)
end
end

assert_equal('Liquid error: Filter overrides registered public methods as non public: public_filter', error.message)
end

Expand Down

0 comments on commit e5d18c8

Please sign in to comment.