From 8c1bbfec57e4a422ca9ecf3f1513f66d894fb587 Mon Sep 17 00:00:00 2001 From: Tasos Stathopoulos Date: Fri, 13 Jul 2012 15:32:04 +0300 Subject: [PATCH] Use array instead of Hash to keep the registered filters 1.8.7 compatibility fix In Ruby 1.8.7, Hash does not preserve insertion ordering as Array does. This could cause a problem when registering filters which depend on others and the registration order is important. So, the @@filters variable was changed to array where the order of the filters is the same as the insertion order. --- lib/liquid/strainer.rb | 6 +++--- test/liquid/hash_ordering_test.rb | 25 +++++++++++++++++++++++++ 2 files changed, 28 insertions(+), 3 deletions(-) create mode 100644 test/liquid/hash_ordering_test.rb diff --git a/lib/liquid/strainer.rb b/lib/liquid/strainer.rb index 15aefa4..5e75cdd 100644 --- a/lib/liquid/strainer.rb +++ b/lib/liquid/strainer.rb @@ -8,7 +8,7 @@ module Liquid # The Strainer only allows method calls defined in filters given to it via Strainer.global_filter, # Context#add_filters or Template.register_filter class Strainer #:nodoc: - @@filters = {} + @@filters = [] @@known_filters = Set.new @@known_methods = Set.new @@ -19,7 +19,7 @@ module Liquid def self.global_filter(filter) raise ArgumentError, "Passed filter is not a module" unless filter.is_a?(Module) add_known_filter(filter) - @@filters[filter.name] = filter + @@filters << filter unless @@filters.include?(filter) end def self.add_known_filter(filter) @@ -34,7 +34,7 @@ module Liquid def self.create(context) strainer = Strainer.new(context) - @@filters.each { |k,m| strainer.extend(m) } + @@filters.each { |m| strainer.extend(m) } strainer end diff --git a/test/liquid/hash_ordering_test.rb b/test/liquid/hash_ordering_test.rb new file mode 100644 index 0000000..3b77709 --- /dev/null +++ b/test/liquid/hash_ordering_test.rb @@ -0,0 +1,25 @@ +require 'test_helper' + +module MoneyFilter + def money(input) + sprintf(' %d$ ', input) + end +end + +module CanadianMoneyFilter + def money(input) + sprintf(' %d$ CAD ', input) + end +end + +class HashOrderingTest < Test::Unit::TestCase + include Liquid + + def test_global_register_order + Template.register_filter(MoneyFilter) + Template.register_filter(CanadianMoneyFilter) + + assert_equal " 1000$ CAD ", Template.parse("{{1000 | money}}").render(nil, nil) + end + +end