Testing Strainer Template Filter Registration in Shopify/liquid
This test suite validates the behavior of Liquid’s strainer template functionality, focusing on filter registration and method visibility. It ensures proper handling of filter modules and method overrides within the Liquid templating system.
Test Coverage Overview
Implementation Analysis
Technical Details
Best Practices Demonstrated
shopify/liquid
test/unit/strainer_template_unit_test.rb
# frozen_string_literal: true
require 'test_helper'
class StrainerTemplateUnitTest < Minitest::Test
include Liquid
def test_add_filter_when_wrong_filter_class
c = Context.new
s = c.strainer
wrong_filter = ->(v) { v.reverse }
exception = assert_raises(TypeError) do
s.class.add_filter(wrong_filter)
end
assert_equal(exception.message, "wrong argument type Proc (expected Module)")
end
module PrivateMethodOverrideFilter
private
def public_filter
"overriden as private"
end
end
def test_add_filter_raises_when_module_privately_overrides_registered_public_methods
error = assert_raises(Liquid::MethodOverrideError) do
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
module ProtectedMethodOverrideFilter
protected
def public_filter
"overriden as protected"
end
end
def test_add_filter_raises_when_module_overrides_registered_public_method_as_protected
error = assert_raises(Liquid::MethodOverrideError) do
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
module PublicMethodOverrideFilter
def public_filter
"public"
end
end
def test_add_filter_does_not_raise_when_module_overrides_previously_registered_method
with_global_filter do
context = Context.new
context.add_filters([PublicMethodOverrideFilter])
strainer = context.strainer
assert(strainer.class.send(:filter_methods).include?('public_filter'))
end
end
def test_add_filter_does_not_include_already_included_module
mod = Module.new do
class << self
attr_accessor :include_count
def included(_mod)
self.include_count += 1
end
end
self.include_count = 0
end
strainer = Context.new.strainer
strainer.class.add_filter(mod)
strainer.class.add_filter(mod)
assert_equal(1, mod.include_count)
end
end