From d03c4ae8e860e20c27f46cf25ee83d2bbba14906 Mon Sep 17 00:00:00 2001 From: Ismael Celis Date: Wed, 30 Mar 2016 01:57:21 -0300 Subject: [PATCH 1/2] Allow Utils.to_number to work with anything that responds to #to_number --- lib/liquid/utils.rb | 6 +++++- test/integration/standard_filter_test.rb | 12 ++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/lib/liquid/utils.rb b/lib/liquid/utils.rb index 4e18138b..f8f5d711 100644 --- a/lib/liquid/utils.rb +++ b/lib/liquid/utils.rb @@ -52,7 +52,11 @@ module Liquid when String (obj.strip =~ /\A\d+\.\d+\z/) ? BigDecimal.new(obj) : obj.to_i else - 0 + if obj.respond_to?(:to_number) + obj.to_number + else + 0 + end end end diff --git a/test/integration/standard_filter_test.rb b/test/integration/standard_filter_test.rb index eb883844..38a43b3f 100644 --- a/test/integration/standard_filter_test.rb +++ b/test/integration/standard_filter_test.rb @@ -41,6 +41,16 @@ class TestEnumerable < Liquid::Drop end end +class NumberLikeThing < Liquid::Drop + def initialize(amount) + @amount = amount + end + + def to_number + @amount + end +end + class StandardFiltersTest < Minitest::Test include Liquid @@ -391,6 +401,8 @@ class StandardFiltersTest < Minitest::Test assert_raises(Liquid::ZeroDivisionError) do assert_template_result "4", "{{ 1 | modulo: 0 }}" end + + assert_template_result "5", "{{ price | divided_by:2 }}", 'price' => NumberLikeThing.new(10) end def test_modulo From 929c89789f9cc9eb62513ef571502de2acbcebe5 Mon Sep 17 00:00:00 2001 From: Ismael Celis Date: Wed, 30 Mar 2016 13:35:04 -0300 Subject: [PATCH 2/2] Test that all maths filters work with duck-typed #to_number --- test/integration/standard_filter_test.rb | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/test/integration/standard_filter_test.rb b/test/integration/standard_filter_test.rb index 38a43b3f..7412f65e 100644 --- a/test/integration/standard_filter_test.rb +++ b/test/integration/standard_filter_test.rb @@ -374,11 +374,15 @@ class StandardFiltersTest < Minitest::Test def test_plus assert_template_result "2", "{{ 1 | plus:1 }}" assert_template_result "2.0", "{{ '1' | plus:'1.0' }}" + + assert_template_result "5", "{{ price | plus:'2' }}", 'price' => NumberLikeThing.new(3) end def test_minus assert_template_result "4", "{{ input | minus:operand }}", 'input' => 5, 'operand' => 1 assert_template_result "2.3", "{{ '4.3' | minus:'2' }}" + + assert_template_result "5", "{{ price | minus:'2' }}", 'price' => NumberLikeThing.new(7) end def test_times @@ -388,6 +392,8 @@ class StandardFiltersTest < Minitest::Test assert_template_result "6", "{{ '2.1' | times:3 | replace: '.','-' | plus:0}}" assert_template_result "7.25", "{{ 0.0725 | times:100 }}" + + assert_template_result "4", "{{ price | times:2 }}", 'price' => NumberLikeThing.new(2) end def test_divided_by @@ -410,6 +416,8 @@ class StandardFiltersTest < Minitest::Test assert_raises(Liquid::ZeroDivisionError) do assert_template_result "4", "{{ 1 | modulo: 0 }}" end + + assert_template_result "1", "{{ price | modulo:2 }}", 'price' => NumberLikeThing.new(3) end def test_round @@ -419,6 +427,9 @@ class StandardFiltersTest < Minitest::Test assert_raises(Liquid::FloatDomainError) do assert_template_result "4", "{{ 1.0 | divided_by: 0.0 | round }}" end + + assert_template_result "5", "{{ price | round }}", 'price' => NumberLikeThing.new(4.6) + assert_template_result "4", "{{ price | round }}", 'price' => NumberLikeThing.new(4.3) end def test_ceil @@ -427,6 +438,8 @@ class StandardFiltersTest < Minitest::Test assert_raises(Liquid::FloatDomainError) do assert_template_result "4", "{{ 1.0 | divided_by: 0.0 | ceil }}" end + + assert_template_result "5", "{{ price | ceil }}", 'price' => NumberLikeThing.new(4.6) end def test_floor @@ -435,6 +448,8 @@ class StandardFiltersTest < Minitest::Test assert_raises(Liquid::FloatDomainError) do assert_template_result "4", "{{ 1.0 | divided_by: 0.0 | floor }}" end + + assert_template_result "5", "{{ price | floor }}", 'price' => NumberLikeThing.new(5.4) end def test_append