mirror of
https://github.com/hakanensari/frankfurter.git
synced 2024-11-25 12:32:30 +01:00
Handle rounding edge case
A lower-rate base currency like IDR previously produced less precise quotes. Fixes #14
This commit is contained in:
parent
2e83b9d50d
commit
2d56ce2e77
@ -4,6 +4,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).
|
|||||||
|
|
||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
### Changed
|
### Changed
|
||||||
|
- Handle rounding edge case where a lower-rate base currency like IDR produces less precise quotes
|
||||||
- Sample weekly when querying over a year
|
- Sample weekly when querying over a year
|
||||||
- Bump PostgreSQL to 12
|
- Bump PostgreSQL to 12
|
||||||
|
|
||||||
|
@ -7,6 +7,8 @@ module Roundable
|
|||||||
# greater than around 20 are usually quoted to three decimal places and
|
# greater than around 20 are usually quoted to three decimal places and
|
||||||
# exchange rates greater than 80 are quoted to two decimal places.
|
# exchange rates greater than 80 are quoted to two decimal places.
|
||||||
# Currencies over 5000 are usually quoted with no decimal places.
|
# Currencies over 5000 are usually quoted with no decimal places.
|
||||||
|
#
|
||||||
|
# https://en.wikipedia.org/wiki/Exchange_rate#Quotations
|
||||||
def round(value)
|
def round(value)
|
||||||
if value > 5000
|
if value > 5000
|
||||||
value.round
|
value.round
|
||||||
@ -16,8 +18,13 @@ module Roundable
|
|||||||
Float(format('%<value>.3f', value: value))
|
Float(format('%<value>.3f', value: value))
|
||||||
elsif value > 1
|
elsif value > 1
|
||||||
Float(format('%<value>.4f', value: value))
|
Float(format('%<value>.4f', value: value))
|
||||||
else
|
# I had originally opted to round smaller numbers simply to five decimal
|
||||||
|
# places but introduced this refinement to handle an edge case where a
|
||||||
|
# lower-rate base currency like IDR produces less precise quotes.
|
||||||
|
elsif value > 0.0001
|
||||||
Float(format('%<value>.5f', value: value))
|
Float(format('%<value>.5f', value: value))
|
||||||
|
else
|
||||||
|
Float(format('%<value>.6f', value: value))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -7,25 +7,38 @@ describe Roundable do
|
|||||||
include Roundable
|
include Roundable
|
||||||
|
|
||||||
it 'rounds values over 5,000 to zero decimal places' do
|
it 'rounds values over 5,000 to zero decimal places' do
|
||||||
round(5000.123456).must_equal 5000.0
|
_(round(5000.123456)).must_equal 5000
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'rounds values over 80 and below 5,000 to two decimal places' do
|
it 'rounds values over 80 and below 5,000 to two decimal places' do
|
||||||
round(80.123456).must_equal 80.12
|
_(round(80.123456)).must_equal 80.12
|
||||||
round(4999.123456).must_equal 4999.12
|
_(round(4999.123456)).must_equal 4999.12
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'rounds values over 20 and below 80 to three decimal places' do
|
it 'rounds values over 20 and below 80 to three decimal places' do
|
||||||
round(79.123456).must_equal 79.123
|
_(round(79.123456)).must_equal 79.123
|
||||||
round(20.123456).must_equal 20.123
|
_(round(20.123456)).must_equal 20.123
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'rounds values over 1 and below 20 to four decimal places' do
|
it 'rounds values over 1 and below 20 to four decimal places' do
|
||||||
round(19.123456).must_equal 19.1235
|
_(round(19.123456)).must_equal 19.1235
|
||||||
round(1.123456).must_equal 1.1235
|
_(round(1.123456)).must_equal 1.1235
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'rounds values below 1 to five decimal places' do
|
it 'rounds values below 1 to five decimal places' do
|
||||||
round(0.123456).must_equal 0.12346
|
_(round(0.123456)).must_equal 0.12346
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'rounds values below 0.0001 to six decimal places' do
|
||||||
|
_(round(0.0000655)).must_equal 0.000066
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'conforms to ECB conventions' do
|
||||||
|
skip "We don't conform ¯\_(ツ)_/¯"
|
||||||
|
require 'day'
|
||||||
|
rates = Day.all.sample.rates.to_a
|
||||||
|
rates.shuffle.each do |_currency, rate|
|
||||||
|
_(round(rate)).must_equal rate
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
Loading…
Reference in New Issue
Block a user