diff --git a/lib/liquid/standardfilters.rb b/lib/liquid/standardfilters.rb index 19ace466..6128f785 100644 --- a/lib/liquid/standardfilters.rb +++ b/lib/liquid/standardfilters.rb @@ -185,22 +185,35 @@ module Liquid # addition def plus(input, operand) - input + operand if input.respond_to?('+') + to_number(input) + to_number(operand) end # subtraction def minus(input, operand) - input - operand if input.respond_to?('-') + to_number(input) - to_number(operand) end # multiplication def times(input, operand) - input * operand if input.respond_to?('*') + to_number(input) * to_number(operand) end # division def divided_by(input, operand) - input / operand if input.respond_to?('/') + to_number(input) / to_number(operand) + end + + private + + def to_number(obj) + case obj + when Numeric + obj + when String + (obj.strip =~ /^\d+\.\d+$/) ? obj.to_f : obj.to_i + else + 0 + end end end diff --git a/test/standard_filter_test.rb b/test/standard_filter_test.rb index 916c1139..9c442e1c 100644 --- a/test/standard_filter_test.rb +++ b/test/standard_filter_test.rb @@ -131,18 +131,29 @@ class StandardFiltersTest < Test::Unit::TestCase def test_plus assert_template_result "2", "{{ 1 | plus:1 }}" - assert_template_result "11", "{{ '1' | plus:'1' }}" + assert_template_result "2.0", "{{ '1' | plus:'1.0' }}" end def test_minus assert_template_result "4", "{{ input | minus:operand }}", 'input' => 5, 'operand' => 1 + assert_template_result "2.3", "{{ '4.3' | minus:'2' }}" end def test_times assert_template_result "12", "{{ 3 | times:4 }}" - assert_template_result "foofoofoofoo", "{{ 'foo' | times:4 }}" + assert_template_result "0", "{{ 'foo' | times:4 }}" + assert_template_result "6.3", "{{ '2.1' | times:3 }}" + assert_template_result "6", "{{ '2.1' | times:3 | replace: '.','-' | plus:0}}" end + def test_divided_by + assert_template_result "4", "{{ 12 | divided_by:3 }}" + assert_template_result "4", "{{ 14 | divided_by:3 }}" + assert_template_result "4.66666666666667", "{{ 14 | divided_by:'3.0' }}" + assert_template_result "5", "{{ 15 | divided_by:3 }}" + assert_template_result "Liquid error: divided by 0", "{{ 5 | divided_by:0 }}" + end + def test_append assigns = {'a' => 'bc', 'b' => 'd' } assert_template_result('bcd',"{{ a | append: 'd'}}",assigns) @@ -155,10 +166,8 @@ class StandardFiltersTest < Test::Unit::TestCase assert_template_result('abc',"{{ a | prepend: b}}",assigns) end - def test_divided_by - assert_template_result "4", "{{ 12 | divided_by:3 }}" - assert_template_result "4", "{{ 14 | divided_by:3 }}" - assert_template_result "5", "{{ 15 | divided_by:3 }}" + def test_cannot_access_private_methods + assert_template_result('a',"{{ 'a' | to_number }}") end end