mirror of
https://github.com/kemko/liquid.git
synced 2026-01-03 16:55:40 +03:00
use BigDecimal on filters to have better precision
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
require 'cgi'
|
||||
require 'bigdecimal'
|
||||
|
||||
module Liquid
|
||||
|
||||
@@ -210,41 +211,47 @@ module Liquid
|
||||
|
||||
# addition
|
||||
def plus(input, operand)
|
||||
to_number(input) + to_number(operand)
|
||||
apply_operation(input, operand, :+)
|
||||
end
|
||||
|
||||
# subtraction
|
||||
def minus(input, operand)
|
||||
to_number(input) - to_number(operand)
|
||||
apply_operation(input, operand, :-)
|
||||
end
|
||||
|
||||
# multiplication
|
||||
def times(input, operand)
|
||||
to_number(input) * to_number(operand)
|
||||
apply_operation(input, operand, :*)
|
||||
end
|
||||
|
||||
# division
|
||||
def divided_by(input, operand)
|
||||
to_number(input) / to_number(operand)
|
||||
apply_operation(input, operand, :/)
|
||||
end
|
||||
|
||||
def modulo(input, operand)
|
||||
to_number(input) % to_number(operand)
|
||||
apply_operation(input, 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
|
||||
def to_number(obj)
|
||||
case obj
|
||||
when Float
|
||||
BigDecimal.new(obj.to_s)
|
||||
when Numeric
|
||||
obj
|
||||
when String
|
||||
(obj.strip =~ /^\d+\.\d+$/) ? BigDecimal.new(obj) : obj.to_i
|
||||
else
|
||||
0
|
||||
end
|
||||
end
|
||||
|
||||
def apply_operation(input, operand, operation)
|
||||
result = to_number(input).send(operation, to_number(operand))
|
||||
result.is_a?(BigDecimal) ? result.to_f : result
|
||||
end
|
||||
end
|
||||
|
||||
Template.register_filter(StandardFilters)
|
||||
|
||||
@@ -164,6 +164,8 @@ class StandardFiltersTest < Test::Unit::TestCase
|
||||
assert_match(/(6\.3)|(6\.(0{13})1)/, Template.parse("{{ '2.1' | times:3 }}").render)
|
||||
|
||||
assert_template_result "6", "{{ '2.1' | times:3 | replace: '.','-' | plus:0}}"
|
||||
|
||||
assert_template_result "7.25", "{{ 0.0725 | times:100 }}"
|
||||
end
|
||||
|
||||
def test_divided_by
|
||||
@@ -175,6 +177,8 @@ class StandardFiltersTest < Test::Unit::TestCase
|
||||
|
||||
assert_template_result "5", "{{ 15 | divided_by:3 }}"
|
||||
assert_template_result "Liquid error: divided by 0", "{{ 5 | divided_by:0 }}"
|
||||
|
||||
assert_template_result "0.5", "{{ 2.0 | divided_by:4 }}"
|
||||
end
|
||||
|
||||
def test_modulo
|
||||
|
||||
Reference in New Issue
Block a user