money-historical-bank 0.0.3 → 0.0.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/Gemfile +1 -1
- data/{README.markdown → README.md} +4 -3
- data/lib/money/bank/historical_bank.rb +8 -8
- data/lib/money/bank/open_exchange_rates_loader.rb +5 -5
- data/test/historical_bank_test.rb +46 -10
- data/test/test_helper.rb +2 -0
- metadata +71 -34
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 21c9ce9d3105a6853c5a8fb3a5de1f9db1c5176e25aba677987836b8e735b9e0
|
4
|
+
data.tar.gz: 98f96e0111260245d8174c0386599e01b8958232ddf815d75232b1e1093e711c
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: c8232d2f2ae42575bf588d3cb794d612c459272559b1fb89da875dfa1c8845a6db38790a04a8ab2a8c0f56d24730fa42f3f5bc92013cd9d266a32c6a9d47a8cf
|
7
|
+
data.tar.gz: cb9f96adacf27e06a544cad7b3d828e624ee84d9e7b19795bca6c219ca60834a60e1cb23a74138f367de295b9db1157626dbe84be68ec47cda272ed6968362f9
|
data/Gemfile
CHANGED
@@ -1,5 +1,4 @@
|
|
1
|
-
# Money Historical Bank
|
2
|
-
[![Build Status](https://secure.travis-ci.org/coutud/money-historical-bank.png)](http://travis-ci.org/coutud/money-historical-bank)
|
1
|
+
# Money Historical Bank [![TravisCI][badge]][travis]
|
3
2
|
|
4
3
|
A gem that add a `Money::Bank` able to handle historical rates, and infer rates from limited rates.
|
5
4
|
|
@@ -47,5 +46,7 @@ The above copyright notice and this permission notice shall be included in all c
|
|
47
46
|
|
48
47
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
49
48
|
|
50
|
-
|
51
49
|
Copyright © 2012 Damien Couture <wam@atwam.com>
|
50
|
+
|
51
|
+
[travis]: https://travis-ci.org/github/atwam/money-historical-bank
|
52
|
+
[badge]: https://travis-ci.org/atwam/money-historical-bank.svg
|
@@ -14,7 +14,7 @@ class Money
|
|
14
14
|
attr_reader :rates
|
15
15
|
# Available formats for importing/exporting rates.
|
16
16
|
RATE_FORMATS = [:json, :ruby, :yaml]
|
17
|
-
|
17
|
+
|
18
18
|
def setup
|
19
19
|
@rates = {}
|
20
20
|
@mutex = Mutex.new
|
@@ -38,7 +38,7 @@ class Money
|
|
38
38
|
internal_set_rate(date, from, to, rate)
|
39
39
|
end
|
40
40
|
end
|
41
|
-
|
41
|
+
|
42
42
|
# Retrieve the rate for the given currencies. Uses +Mutex+ to synchronize
|
43
43
|
# data access. If no rates have been set for +date+, will try to load them
|
44
44
|
# using #load_data.
|
@@ -60,9 +60,9 @@ class Money
|
|
60
60
|
# bank.get_rate(d2, "CAD", "USD") #=> 0.803115
|
61
61
|
def get_rate(date, from, to)
|
62
62
|
@mutex.synchronize do
|
63
|
-
unless existing_rates = @rates[date]
|
63
|
+
unless existing_rates = @rates[date.to_s]
|
64
64
|
load_data(date)
|
65
|
-
existing_rates = @rates[date]
|
65
|
+
existing_rates = @rates[date.to_s]
|
66
66
|
end
|
67
67
|
rate = nil
|
68
68
|
if existing_rates
|
@@ -90,7 +90,7 @@ class Money
|
|
90
90
|
rate
|
91
91
|
end
|
92
92
|
end
|
93
|
-
|
93
|
+
|
94
94
|
#
|
95
95
|
# @overload exchange_with(from, to_currency)
|
96
96
|
# Exchanges the given +Money+ object to a new +Money+ object in
|
@@ -144,9 +144,9 @@ class Money
|
|
144
144
|
end
|
145
145
|
_to_currency_ = Currency.wrap(to_currency)
|
146
146
|
|
147
|
-
cents = BigDecimal
|
147
|
+
cents = BigDecimal(from.cents.to_s) / (BigDecimal(from.currency.subunit_to_unit.to_s) / BigDecimal(_to_currency_.subunit_to_unit.to_s))
|
148
148
|
|
149
|
-
ex = cents * BigDecimal
|
149
|
+
ex = cents * BigDecimal(rate.to_s)
|
150
150
|
ex = ex.to_f
|
151
151
|
ex = if block_given?
|
152
152
|
yield ex
|
@@ -257,7 +257,7 @@ class Money
|
|
257
257
|
# @return [Numeric]
|
258
258
|
def internal_set_rate(date, from, to, rate)
|
259
259
|
if Money::Currency.find(from) && Money::Currency.find(to)
|
260
|
-
date_rates = @rates[date] ||= {}
|
260
|
+
date_rates = @rates[date.to_s] ||= {}
|
261
261
|
date_rates[rate_key_for(from, to)] = rate
|
262
262
|
end
|
263
263
|
end
|
@@ -7,19 +7,19 @@ require 'open-uri'
|
|
7
7
|
class Money
|
8
8
|
module Bank
|
9
9
|
module OpenExchangeRatesLoader
|
10
|
-
HIST_URL = '
|
11
|
-
OER_URL = '
|
10
|
+
HIST_URL = 'https://openexchangerates.org/api/historical/'
|
11
|
+
OER_URL = 'https://openexchangerates.org/api/latest.json'
|
12
12
|
|
13
13
|
# Tries to load data from OpenExchangeRates for the given rate.
|
14
14
|
# Won't do anything if there's no data available for that date
|
15
15
|
# in OpenExchangeRates (short) history.
|
16
16
|
def load_data(date)
|
17
17
|
rates_source = if date == Date.today
|
18
|
-
OER_URL
|
18
|
+
OER_URL.dup
|
19
19
|
else
|
20
|
-
|
21
|
-
HIST_URL + date.to_s + '.json'
|
20
|
+
HIST_URL + date.strftime('%Y-%m-%d') + '.json'
|
22
21
|
end
|
22
|
+
rates_source << "?app_id=#{ENV['OPENEXCHANGERATES_APP_ID']}" if ENV['OPENEXCHANGERATES_APP_ID']
|
23
23
|
doc = Yajl::Parser.parse(open(rates_source).read)
|
24
24
|
|
25
25
|
base_currency = doc['base'] || 'USD'
|
@@ -17,14 +17,14 @@ describe Money::Bank::HistoricalBank do
|
|
17
17
|
@bank.set_rate(d1, "USD", "EUR", 1.234)
|
18
18
|
@bank.set_rate(d2, "GBP", "USD", 1.456)
|
19
19
|
|
20
|
-
@bank.get_rate(d1, "USD", "EUR")
|
21
|
-
@bank.get_rate(d2, "GBP", "USD")
|
20
|
+
assert_equal @bank.get_rate(d1, "USD", "EUR"), 1.234
|
21
|
+
assert_equal @bank.get_rate(d2, "GBP", "USD"), 1.456
|
22
22
|
end
|
23
23
|
|
24
24
|
it "shouldn't throw an error when internal_set_rate is called with a non existing currency" do
|
25
25
|
d1 = Date.new(2011,1,1)
|
26
26
|
@bank.set_rate(d1, "BLA", "ZZZ", 1.01)
|
27
|
-
@bank.rates
|
27
|
+
assert_empty @bank.rates
|
28
28
|
end
|
29
29
|
|
30
30
|
it "should return the correct rate interpolated from existing pairs when asked" do
|
@@ -32,37 +32,73 @@ describe Money::Bank::HistoricalBank do
|
|
32
32
|
@bank.set_rate(d1, "USD", "EUR", 1.234)
|
33
33
|
@bank.set_rate(d1, "GBP", "USD", 1.456)
|
34
34
|
|
35
|
-
@bank.get_rate(d1, "EUR", "USD")
|
36
|
-
@bank.get_rate(d1, "GBP", "EUR")
|
35
|
+
assert_in_epsilon @bank.get_rate(d1, "EUR", "USD"), 1.0 / 1.234
|
36
|
+
assert_in_epsilon @bank.get_rate(d1, "GBP", "EUR"), 1.456 * 1.234
|
37
37
|
end
|
38
38
|
|
39
39
|
it "should return the correct rates using exchange_with a date" do
|
40
40
|
d1 = Date.new(2001,1,1)
|
41
41
|
@bank.set_rate(d1, "USD", "EUR", 0.73062465)
|
42
|
-
|
42
|
+
from = Money.new(5000, 'EUR')
|
43
|
+
assert_equal @bank.exchange_with(d1, from, 'USD').cents, 6843
|
43
44
|
end
|
44
45
|
it "should return the correct rates using exchange_with no date (today)" do
|
45
46
|
d1 = Date.today
|
46
47
|
@bank.set_rate(d1, "USD", "EUR", 0.8)
|
47
|
-
|
48
|
+
from = Money.new(5000, 'EUR')
|
49
|
+
assert_equal @bank.exchange_with(from, 'USD').cents, 6250
|
48
50
|
end
|
49
51
|
|
50
52
|
end
|
51
53
|
|
52
54
|
describe 'no rates available yet' do
|
53
|
-
include RR::Adapters::TestUnit
|
54
55
|
before do
|
55
56
|
@bank = Money::Bank::HistoricalBank.new
|
56
57
|
@cache_path = "#{File.dirname(__FILE__)}/test.json"
|
58
|
+
ENV['OPENEXCHANGERATES_APP_ID'] = nil
|
57
59
|
end
|
58
60
|
|
59
61
|
it 'should download new rates from url' do
|
60
62
|
source = Money::Bank::OpenExchangeRatesLoader::HIST_URL + '2009-09-09.json'
|
61
63
|
stub(@bank).open(source) { File.open @cache_path }
|
62
64
|
d1 = Date.new(2009,9,9)
|
63
|
-
|
65
|
+
|
64
66
|
rate = @bank.get_rate(d1, 'USD', 'EUR')
|
65
|
-
rate
|
67
|
+
assert_equal rate, 0.73062465
|
68
|
+
end
|
69
|
+
|
70
|
+
describe 'environment variable set with api id' do
|
71
|
+
before do
|
72
|
+
ENV['OPENEXCHANGERATES_APP_ID'] = 'example-of-app-id'
|
73
|
+
end
|
74
|
+
it 'should download new rates from url' do
|
75
|
+
source = Money::Bank::OpenExchangeRatesLoader::HIST_URL + '2009-09-09.json' + '?app_id=example-of-app-id'
|
76
|
+
stub(@bank).open(source) { File.open @cache_path }
|
77
|
+
d1 = Date.new(2009,9,9)
|
78
|
+
|
79
|
+
rate = @bank.get_rate(d1, 'USD', 'EUR')
|
80
|
+
assert_equal rate, 0.73062465
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
|
85
|
+
end
|
86
|
+
|
87
|
+
describe 'export/import' do
|
88
|
+
before do
|
89
|
+
@bank = Money::Bank::HistoricalBank.new
|
90
|
+
end
|
91
|
+
it "should store any rate stored for a date, and retrieve it after importing exported json" do
|
92
|
+
d1 = Date.new(2001,1,1)
|
93
|
+
d2 = Date.new(2002,1,1)
|
94
|
+
@bank.set_rate(d1, "USD", "EUR", 1.234)
|
95
|
+
@bank.set_rate(d2, "GBP", "USD", 1.456)
|
96
|
+
|
97
|
+
json = @bank.export_rates(:json)
|
98
|
+
@bank.import_rates(:json, json)
|
99
|
+
|
100
|
+
assert_equal @bank.get_rate(d1, "USD", "EUR"), 1.234
|
101
|
+
assert_equal @bank.get_rate(d2, "GBP", "USD"), 1.456
|
66
102
|
end
|
67
103
|
end
|
68
104
|
|
data/test/test_helper.rb
CHANGED
metadata
CHANGED
@@ -1,100 +1,137 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: money-historical-bank
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
5
|
-
prerelease:
|
4
|
+
version: 0.0.4
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- atwam
|
8
|
+
- Jon Allured
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2020-09-04 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: yajl-ruby
|
16
|
-
requirement:
|
17
|
-
none: false
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
18
17
|
requirements:
|
19
|
-
- -
|
18
|
+
- - "~>"
|
20
19
|
- !ruby/object:Gem::Version
|
21
|
-
version:
|
20
|
+
version: '1.3'
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 1.3.1
|
22
24
|
type: :runtime
|
23
25
|
prerelease: false
|
24
|
-
version_requirements:
|
26
|
+
version_requirements: !ruby/object:Gem::Requirement
|
27
|
+
requirements:
|
28
|
+
- - "~>"
|
29
|
+
- !ruby/object:Gem::Version
|
30
|
+
version: '1.3'
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 1.3.1
|
25
34
|
- !ruby/object:Gem::Dependency
|
26
35
|
name: money
|
27
|
-
requirement:
|
28
|
-
none: false
|
36
|
+
requirement: !ruby/object:Gem::Requirement
|
29
37
|
requirements:
|
30
|
-
- -
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '6'
|
41
|
+
- - ">="
|
31
42
|
- !ruby/object:Gem::Version
|
32
|
-
version:
|
43
|
+
version: 6.13.1
|
33
44
|
type: :runtime
|
34
45
|
prerelease: false
|
35
|
-
version_requirements:
|
46
|
+
version_requirements: !ruby/object:Gem::Requirement
|
47
|
+
requirements:
|
48
|
+
- - "~>"
|
49
|
+
- !ruby/object:Gem::Version
|
50
|
+
version: '6'
|
51
|
+
- - ">="
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: 6.13.1
|
36
54
|
- !ruby/object:Gem::Dependency
|
37
55
|
name: minitest
|
38
|
-
requirement:
|
39
|
-
none: false
|
56
|
+
requirement: !ruby/object:Gem::Requirement
|
40
57
|
requirements:
|
41
|
-
- -
|
58
|
+
- - ">="
|
42
59
|
- !ruby/object:Gem::Version
|
43
|
-
version: '
|
60
|
+
version: '5.0'
|
61
|
+
- - "~>"
|
62
|
+
- !ruby/object:Gem::Version
|
63
|
+
version: '5'
|
44
64
|
type: :development
|
45
65
|
prerelease: false
|
46
|
-
version_requirements:
|
66
|
+
version_requirements: !ruby/object:Gem::Requirement
|
67
|
+
requirements:
|
68
|
+
- - ">="
|
69
|
+
- !ruby/object:Gem::Version
|
70
|
+
version: '5.0'
|
71
|
+
- - "~>"
|
72
|
+
- !ruby/object:Gem::Version
|
73
|
+
version: '5'
|
47
74
|
- !ruby/object:Gem::Dependency
|
48
75
|
name: rr
|
49
|
-
requirement:
|
50
|
-
none: false
|
76
|
+
requirement: !ruby/object:Gem::Requirement
|
51
77
|
requirements:
|
52
|
-
- -
|
78
|
+
- - "~>"
|
79
|
+
- !ruby/object:Gem::Version
|
80
|
+
version: '1.0'
|
81
|
+
- - ">="
|
53
82
|
- !ruby/object:Gem::Version
|
54
83
|
version: 1.0.4
|
55
84
|
type: :development
|
56
85
|
prerelease: false
|
57
|
-
version_requirements:
|
86
|
+
version_requirements: !ruby/object:Gem::Requirement
|
87
|
+
requirements:
|
88
|
+
- - "~>"
|
89
|
+
- !ruby/object:Gem::Version
|
90
|
+
version: '1.0'
|
91
|
+
- - ">="
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: 1.0.4
|
58
94
|
description: A gem that provides rates for the money gem. Able to handle history (rates
|
59
95
|
varying in time), and auto download rates from open-exchange-rates. Highly inspired
|
60
96
|
by money-open-exchange-rates gem.
|
61
|
-
email:
|
97
|
+
email:
|
98
|
+
- wam@atwam.com
|
99
|
+
- jon.allured@gmail.com
|
62
100
|
executables: []
|
63
101
|
extensions: []
|
64
102
|
extra_rdoc_files:
|
65
|
-
- README.
|
103
|
+
- README.md
|
66
104
|
files:
|
67
|
-
- LICENSE
|
68
|
-
- README.markdown
|
69
105
|
- Gemfile
|
106
|
+
- LICENSE
|
107
|
+
- README.md
|
70
108
|
- lib/money/bank/historical_bank.rb
|
71
109
|
- lib/money/bank/open_exchange_rates_loader.rb
|
72
110
|
- test/historical_bank_test.rb
|
73
111
|
- test/test.json
|
74
112
|
- test/test_helper.rb
|
75
113
|
homepage: http://github.com/atwam/money-historical-bank
|
76
|
-
licenses:
|
114
|
+
licenses:
|
115
|
+
- MIT
|
116
|
+
metadata: {}
|
77
117
|
post_install_message:
|
78
118
|
rdoc_options: []
|
79
119
|
require_paths:
|
80
120
|
- lib
|
81
121
|
required_ruby_version: !ruby/object:Gem::Requirement
|
82
|
-
none: false
|
83
122
|
requirements:
|
84
|
-
- -
|
123
|
+
- - ">="
|
85
124
|
- !ruby/object:Gem::Version
|
86
125
|
version: '0'
|
87
126
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
88
|
-
none: false
|
89
127
|
requirements:
|
90
|
-
- -
|
128
|
+
- - ">="
|
91
129
|
- !ruby/object:Gem::Version
|
92
130
|
version: '0'
|
93
131
|
requirements: []
|
94
|
-
|
95
|
-
rubygems_version: 1.8.10
|
132
|
+
rubygems_version: 3.0.3
|
96
133
|
signing_key:
|
97
|
-
specification_version:
|
134
|
+
specification_version: 4
|
98
135
|
summary: A gem that offers exchange rates varying in time.
|
99
136
|
test_files:
|
100
137
|
- test/historical_bank_test.rb
|