money-ecb 0.0.2 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +8 -8
- data/.gitignore +1 -0
- data/Gemfile.lock +36 -0
- data/README.rst +31 -13
- data/lib/money/bank/ecb/cache.rb +22 -0
- data/lib/money/bank/ecb/cache_file.rb +23 -0
- data/lib/money/bank/ecb/simple_cache.rb +17 -0
- data/lib/money/bank/ecb.rb +43 -28
- data/money-ecb.gemspec +1 -1
- data/spec/ecb/cache_spec.rb +22 -0
- data/spec/ecb_spec.rb +70 -46
- metadata +7 -2
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
ZDRiZDk3M2U0MmVmNjM1ZTUzMTAzMDhlZjY3OWU4MzEyNGNiMDYzZQ==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
MjExZmM4NDQwNjBhYTQ4OGRkNzM4MjQ0YzcyOTNlMWQ4OWQ1MWFkNA==
|
7
7
|
SHA512:
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
NDg0Y2ViNzdmYzY5MTk2MzVmZTc3NTU1MmMwZThlZDdhZDdlMjYzODE0NzU4
|
10
|
+
NDUzOWJkMGUxNGQwZjg2NjgwYmE4ZDAzOWM2YmQ5ZjIzYjdkMzhmNDljY2Fk
|
11
|
+
ODIyOWQ5OWFiNWZhNjUxZmQ1OTI2MTA4ZmEzMWIxN2E1NjU5ZWI=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
YjkxODk1NWY1ODNmYjBlYzM4NWUwOTJiMjRmZGU5Y2UwZjlkYjk1NmQ0Yzky
|
14
|
+
YmYyY2RiYjE5OTk3MjcwOTE1YzQ2OGRjMDk2NDBiMzFhYjFhMjU4NWQwYjVk
|
15
|
+
YTc2ZDJkODU2YzJhMmI4Y2MzY2I1ZGYxYzUwZDZiNDg0YWQ2Mjg=
|
data/.gitignore
CHANGED
data/Gemfile.lock
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
GEM
|
2
|
+
remote: https://rubygems.org/
|
3
|
+
specs:
|
4
|
+
coderay (1.1.0)
|
5
|
+
diff-lcs (1.2.5)
|
6
|
+
i18n (0.6.9)
|
7
|
+
method_source (0.8.2)
|
8
|
+
monetize (0.1.4)
|
9
|
+
money (6.0.1)
|
10
|
+
i18n (~> 0.6.4)
|
11
|
+
monetize (~> 0.1.3)
|
12
|
+
pry (0.9.12.6)
|
13
|
+
coderay (~> 1.0)
|
14
|
+
method_source (~> 0.8)
|
15
|
+
slop (~> 3.4)
|
16
|
+
rake (10.1.1)
|
17
|
+
rspec (2.14.1)
|
18
|
+
rspec-core (~> 2.14.0)
|
19
|
+
rspec-expectations (~> 2.14.0)
|
20
|
+
rspec-mocks (~> 2.14.0)
|
21
|
+
rspec-core (2.14.7)
|
22
|
+
rspec-expectations (2.14.5)
|
23
|
+
diff-lcs (>= 1.1.3, < 2.0)
|
24
|
+
rspec-mocks (2.14.5)
|
25
|
+
rubyzip (1.1.0)
|
26
|
+
slop (3.4.7)
|
27
|
+
|
28
|
+
PLATFORMS
|
29
|
+
ruby
|
30
|
+
|
31
|
+
DEPENDENCIES
|
32
|
+
money
|
33
|
+
pry
|
34
|
+
rake
|
35
|
+
rspec
|
36
|
+
rubyzip
|
data/README.rst
CHANGED
@@ -56,16 +56,10 @@ Using ``money`` and ``monetize``:
|
|
56
56
|
require 'money/bank/ecb'
|
57
57
|
require 'monetize/core_extensions'
|
58
58
|
|
59
|
-
Money.default_bank = Money::Bank::ECB.new
|
59
|
+
Money.default_bank = Money::Bank::ECB.new
|
60
60
|
|
61
61
|
puts '1 EUR'.to_money.exchange_to(:USD)
|
62
62
|
|
63
|
-
If ``/tmp/ecb.cache`` is a valid CSV file with exchange rates, the rates will be
|
64
|
-
used for conversion (unless newer rates are available; if so, new rates will be
|
65
|
-
fetched—see `auto-update`_). If the file does not exist or is "somehow bogus",
|
66
|
-
new rates will be downloaded from the European Central Bank and stored in the
|
67
|
-
file.
|
68
|
-
|
69
63
|
|
70
64
|
Rounding
|
71
65
|
--------
|
@@ -81,7 +75,19 @@ creating the ``ECB`` instance:
|
|
81
75
|
|
82
76
|
.. code-block:: ruby
|
83
77
|
|
84
|
-
Money.default_bank = Money::Bank::ECB.new
|
78
|
+
Money.default_bank = Money::Bank::ECB.new {|x| x.round}
|
79
|
+
|
80
|
+
Local cache file
|
81
|
+
----------------
|
82
|
+
|
83
|
+
For your convenience, :ruby:`.new` will accept a string representing a file
|
84
|
+
path.
|
85
|
+
|
86
|
+
If the file path holds a valid CSV file with exchange rates, the rates will be
|
87
|
+
used for conversion (unless newer rates are available; if so, new rates will be
|
88
|
+
fetched—see `auto-update`_). If the file does not exist or is "somehow bogus",
|
89
|
+
new rates will be downloaded from the European Central Bank and stored in the
|
90
|
+
file (or an :ruby:`InvalidCacheError` will be raise if `auto-update`_ is off).
|
85
91
|
|
86
92
|
|
87
93
|
.. _`auto-update`:
|
@@ -92,12 +98,24 @@ Auto-update rates
|
|
92
98
|
The European Central Bank publishes foreign exchange rates daily, and they
|
93
99
|
should be available at 14:00 CE(S)T. The cache is automatically updated when
|
94
100
|
doing an exchange after new rates has been published; to disable this, set
|
95
|
-
:ruby
|
101
|
+
:ruby:`#auto_update = false`; to force, :ruby:`#update_cache` and
|
102
|
+
:ruby:`#reload` (or both in one take, :ruby:`#update`).
|
103
|
+
|
104
|
+
Also notice that when instantiating an :ruby:`ECB`, rates will be loaded from
|
105
|
+
the cache file, and if that fails, new rates will be fetched automatically. So
|
106
|
+
if you want to handle updating rates "by hand", you should place a valid cache
|
107
|
+
before :ruby:`.new` and then call :ruby:`#reload` after you updated the cache.
|
108
|
+
|
109
|
+
.. _`Can I code my own cache?`:
|
110
|
+
|
111
|
+
Can I code my own cache?
|
112
|
+
------------------------
|
96
113
|
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
114
|
+
Yes, just :ruby:`include Money::Bank::ECB::Cache` and implement
|
115
|
+
:ruby:`.new_from?` (if you accept what :ruby:`.new` was given) and
|
116
|
+
:ruby:`.priority` (let it be ``=> 2`` since ``0`` and ``1`` are already used for
|
117
|
+
:ruby:`SimpleCache` and :ruby:`CacheFile` respectively). No monkey patching
|
118
|
+
needed!
|
101
119
|
|
102
120
|
|
103
121
|
Contribute
|
@@ -0,0 +1,22 @@
|
|
1
|
+
class Money
|
2
|
+
module Bank
|
3
|
+
class ECB < Money::Bank::VariableExchange
|
4
|
+
module Cache
|
5
|
+
# Set the cache.
|
6
|
+
#
|
7
|
+
# @param [String] value Set the cache to hold the value.
|
8
|
+
# @return [String]
|
9
|
+
def set(value)
|
10
|
+
raise StandardError, "Implement '.set(&block)' in your Cache!"
|
11
|
+
end
|
12
|
+
|
13
|
+
# Get what the cache contains.
|
14
|
+
#
|
15
|
+
# @return [String]
|
16
|
+
def get
|
17
|
+
raise StandardError, "Implement '.get' in your Cache!"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
class Money
|
2
|
+
module Bank
|
3
|
+
class ECB < Money::Bank::VariableExchange
|
4
|
+
class CacheFile
|
5
|
+
include Cache
|
6
|
+
|
7
|
+
def initialize(path)
|
8
|
+
@path = path
|
9
|
+
end
|
10
|
+
attr_reader :path
|
11
|
+
|
12
|
+
def set(value)
|
13
|
+
File.write(@path, value)
|
14
|
+
value
|
15
|
+
end
|
16
|
+
|
17
|
+
def get
|
18
|
+
File.read(@path)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
data/lib/money/bank/ecb.rb
CHANGED
@@ -5,6 +5,11 @@ require 'bigdecimal'
|
|
5
5
|
require 'zip'
|
6
6
|
require 'csv'
|
7
7
|
|
8
|
+
# Cache require order is important!
|
9
|
+
require 'money/bank/ecb/cache'
|
10
|
+
require 'money/bank/ecb/simple_cache'
|
11
|
+
require 'money/bank/ecb/cache_file'
|
12
|
+
|
8
13
|
class Money
|
9
14
|
module Bank
|
10
15
|
# This class represents the European Central Bank or more precisely, its
|
@@ -14,16 +19,12 @@ class Money
|
|
14
19
|
# The available currencies to exchange between.
|
15
20
|
# @return [Array<String>]
|
16
21
|
#
|
17
|
-
# @!attribute [r] rounding_method
|
18
|
-
# The default rounding method for the bank.
|
19
|
-
# @return [Proc]
|
20
|
-
#
|
21
22
|
# @!attribute [rw] auto_update
|
22
23
|
# Auto-updating on or off.
|
23
24
|
# @param [true,false] bool
|
24
25
|
# @return [true,false]
|
25
26
|
#
|
26
|
-
# @!attribute [r]
|
27
|
+
# @!attribute [r] cache
|
27
28
|
# The cache path and file name
|
28
29
|
# @return[String]
|
29
30
|
#
|
@@ -47,22 +48,36 @@ class Money
|
|
47
48
|
# @return [Money::Bank::ECB]
|
48
49
|
#
|
49
50
|
# @example
|
50
|
-
# Money::Bank::ECB.new
|
51
|
+
# Money::Bank::ECB.new {|x| x.floor}
|
51
52
|
# #=> #<Money::Bank::ECB
|
52
|
-
# @cache_filename='/tmp/ecb.cache',
|
53
53
|
# @rounding_method=#<Proc>,
|
54
54
|
# @auto_update=true,
|
55
55
|
# @rates=#<Hash>,
|
56
56
|
# @rates_date=#<Time>,
|
57
57
|
# @currencies=#<Array>>
|
58
|
-
def initialize(
|
59
|
-
@
|
60
|
-
|
58
|
+
def initialize(cache = nil, &rounding_method)
|
59
|
+
@cache = self.class.build(cache)
|
60
|
+
super(&rounding_method)
|
61
|
+
|
61
62
|
setup
|
62
63
|
end
|
63
64
|
|
64
|
-
|
65
|
-
|
65
|
+
# Builds a Cache from input.
|
66
|
+
#
|
67
|
+
# @param [*] something The thing to build a Cache from.
|
68
|
+
# @return [Cache]
|
69
|
+
def self.build(cache)
|
70
|
+
case cache
|
71
|
+
when Money::Bank::ECB::Cache
|
72
|
+
cache
|
73
|
+
when String
|
74
|
+
Money::Bank::ECB::CacheFile.new(cache)
|
75
|
+
else
|
76
|
+
Money::Bank::ECB::SimpleCache.new
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
attr_reader :cache
|
66
81
|
attr_accessor :auto_update
|
67
82
|
|
68
83
|
# Setup rates hash, mutex for rates locking, and auto_update default.
|
@@ -86,7 +101,6 @@ class Money
|
|
86
101
|
#
|
87
102
|
# @example
|
88
103
|
# ecb.exchange_with(Money.new(100, :EUR), :USD)
|
89
|
-
# #=> #<Money
|
90
104
|
def exchange_with(from, to, &rounding_method)
|
91
105
|
update if @auto_update and Time.now.utc > (@rates_date + 60*60*24)
|
92
106
|
super(from, to, &rounding_method)
|
@@ -108,11 +122,9 @@ class Money
|
|
108
122
|
#
|
109
123
|
# @return [self]
|
110
124
|
def update_cache
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
cache_file.puts(io.read)
|
115
|
-
end
|
125
|
+
Zip::InputStream.open(open(RATES_URL)) do |io|
|
126
|
+
io.get_next_entry
|
127
|
+
@cache.set(io.read)
|
116
128
|
end
|
117
129
|
|
118
130
|
self
|
@@ -132,17 +144,19 @@ class Money
|
|
132
144
|
|
133
145
|
@mutex.synchronize do
|
134
146
|
@rates_date = time
|
135
|
-
@currencies = quotations.
|
147
|
+
@currencies = quotations.map{|key, _| key}
|
136
148
|
|
137
149
|
quotations.each do |currency, rate|
|
138
150
|
set_rate('EUR', currency, rate, :without_mutex => true)
|
139
151
|
set_rate(currency, 'EUR', 1/rate, :without_mutex => true)
|
152
|
+
end
|
140
153
|
|
141
|
-
|
142
|
-
|
154
|
+
quotations.product(quotations) do |one, another|
|
155
|
+
one_cur, one_rate = one
|
156
|
+
another_cur, another_rate = another
|
157
|
+
next if one_cur == another_cur
|
143
158
|
|
144
|
-
|
145
|
-
end
|
159
|
+
set_rate(one_cur, another_cur, another_rate/one_rate, :without_mutex => true)
|
146
160
|
end
|
147
161
|
end
|
148
162
|
|
@@ -155,17 +169,18 @@ class Money
|
|
155
169
|
#
|
156
170
|
# @return [[Time, Hash]]
|
157
171
|
def cache_content
|
158
|
-
csv = CSV.parse(
|
172
|
+
csv = CSV.parse(@cache.get, :headers => true)
|
159
173
|
csv = csv.first # Only one line.
|
160
174
|
|
161
175
|
# Clean-up
|
162
|
-
|
163
|
-
|
176
|
+
csv = csv.map{|key, value| [key.strip, value.strip]}
|
177
|
+
.delete_if{|key, _| key.empty?}
|
164
178
|
|
165
|
-
|
179
|
+
date_entry, *quotations = *csv
|
180
|
+
_, date = date_entry
|
166
181
|
|
167
182
|
time = Time.parse(date + ' ' + self.class.new_rates_time_of_day_s(date))
|
168
|
-
quotations
|
183
|
+
quotations.map!{|cur,rate| [cur, BigDecimal.new(rate)]}
|
169
184
|
|
170
185
|
[time, quotations]
|
171
186
|
rescue
|
data/money-ecb.gemspec
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = 'money-ecb'
|
3
|
-
s.version = '0.0
|
3
|
+
s.version = '0.1.0'
|
4
4
|
s.summary = 'Foreign exchange rates from the EU Central Bank (ECB).'
|
5
5
|
s.description = 'A Money::Bank that will fetch foreign exchange rates from the EU Central Bank (ECB).'
|
6
6
|
s.license = 'MIT'
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'securerandom'
|
2
|
+
require 'tempfile'
|
3
|
+
|
4
|
+
describe 'Money::Bank::ECB::SimpleCache' do
|
5
|
+
it 'should respect the set/get interface' do
|
6
|
+
c = Money::Bank::ECB::SimpleCache.new
|
7
|
+
random = SecureRandom.urlsafe_base64(10)
|
8
|
+
|
9
|
+
expect(c.set(random)).to eq(random)
|
10
|
+
expect(c.get).to eq(random)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
describe 'Money::Bank::ECB::CacheFile' do
|
15
|
+
it 'should respect the set/get interface' do
|
16
|
+
c = Money::Bank::ECB::CacheFile.new(Tempfile.new('money-ecb-spec').path)
|
17
|
+
random = SecureRandom.urlsafe_base64(10)
|
18
|
+
|
19
|
+
expect(c.set(random)).to eq(random)
|
20
|
+
expect(c.get).to eq(random)
|
21
|
+
end
|
22
|
+
end
|
data/spec/ecb_spec.rb
CHANGED
@@ -1,13 +1,17 @@
|
|
1
1
|
require 'money/bank/ecb'
|
2
2
|
require_relative 'support/custom_expectations/write_expectation'
|
3
3
|
|
4
|
-
describe 'ECB' do
|
4
|
+
describe 'Money::Bank::ECB' do
|
5
5
|
before do
|
6
6
|
@assetsdir = File.dirname(__FILE__) + '/assets'
|
7
7
|
@tmpdir = File.dirname(__FILE__) + '/tmp'
|
8
8
|
%x{cp -r #{@assetsdir} #{@tmpdir}}
|
9
9
|
end
|
10
10
|
|
11
|
+
after do
|
12
|
+
%x{rm -rf #{@tmpdir}}
|
13
|
+
end
|
14
|
+
|
11
15
|
let(:bank) do
|
12
16
|
bank = Money::Bank::ECB.new(@tmpdir + '/good_rates.csv')
|
13
17
|
bank.auto_update = false
|
@@ -15,8 +19,65 @@ describe 'ECB' do
|
|
15
19
|
bank
|
16
20
|
end
|
17
21
|
|
18
|
-
|
19
|
-
|
22
|
+
describe '#new' do
|
23
|
+
let(:good_rates) do
|
24
|
+
{
|
25
|
+
'USD' => 1.3574, 'JPY' => 139.28, 'BGN' => 1.9558, 'CZK' => 27.594,
|
26
|
+
'DKK' => 7.4622, 'GBP' => 0.82380, 'HUF' => 310.97, 'LTL' => 3.4528,
|
27
|
+
'PLN' => 4.2312, 'RON' => 4.5110, 'SEK' => 8.8347, 'CHF' => 1.2233,
|
28
|
+
'NOK' => 8.4680, 'HRK' => 7.6605, 'RUB' => 47.8025, 'TRY' => 3.0808,
|
29
|
+
'AUD' => 1.5459, 'BRL' => 3.2955, 'CAD' => 1.5176, 'CNY' => 8.2302,
|
30
|
+
'HKD' => 10.5421, 'IDR' => 16551.39, 'INR' => 85.0840, 'KRW' => 1469.53,
|
31
|
+
'MXN' => 18.1111, 'MYR' => 4.5417, 'NZD' => 1.6624, 'PHP' => 61.527,
|
32
|
+
'SGD' => 1.7323, 'THB' => 44.745, 'ZAR' => 15.2700, 'ILS' => 4.7416,
|
33
|
+
}
|
34
|
+
end
|
35
|
+
|
36
|
+
context 'when no cache is given' do
|
37
|
+
it 'should fetch rates and store in mem' do
|
38
|
+
expect{
|
39
|
+
Money::Bank::ECB::RATES_URL = File.expand_path(@tmpdir + '/eurofxref.zip')
|
40
|
+
}.to write(/warning: already initialized constant .*RATES_URL/).to(:stderr)
|
41
|
+
|
42
|
+
bank = Money::Bank::ECB.new
|
43
|
+
expect(bank.cache).to be_a(Money::Bank::ECB::SimpleCache)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
context 'when cache file path is given' do
|
48
|
+
it 'should use the file path as a cache' do
|
49
|
+
expect(bank.cache).to be_a(Money::Bank::ECB::CacheFile)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
context 'when cache file is good' do
|
54
|
+
it 'should use rates from cache' do
|
55
|
+
expect(bank.rates_date).to eq(Time.utc(2014, 01, 30, 14))
|
56
|
+
bank.currencies.each do |cur|
|
57
|
+
expect(bank.rates['EUR_TO_' + cur]).to eq(good_rates[cur])
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
context 'when cache file is bogus' do
|
63
|
+
it 'should fetch rates from ECB' do
|
64
|
+
expect{
|
65
|
+
Money::Bank::ECB::RATES_URL = File.expand_path(@tmpdir + '/eurofxref.zip')
|
66
|
+
}.to write(/warning: already initialized constant .*RATES_URL/).to(:stderr)
|
67
|
+
|
68
|
+
bogus = Money::Bank::ECB.new(@tmpdir + '/bogus_rates.csv')
|
69
|
+
bogus.auto_update = false
|
70
|
+
|
71
|
+
expect(bogus.rates_date).to eq(Time.utc(2014, 01, 31, 14))
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
context 'when a rounding method is given' do
|
76
|
+
it 'rounding method should be used' do
|
77
|
+
weird = Money::Bank::ECB.new(@tmpdir + '/good_rates.csv') {|x| 5}
|
78
|
+
expect(weird.exchange_with(Money.new(100, :EUR), :USD)).to eq(Money.new(5, :USD))
|
79
|
+
end
|
80
|
+
end
|
20
81
|
end
|
21
82
|
|
22
83
|
describe '#currencies' do
|
@@ -25,6 +86,8 @@ describe 'ECB' do
|
|
25
86
|
it 'should have 32 currencies' do
|
26
87
|
expect(currencies.length).to eq(32)
|
27
88
|
end
|
89
|
+
|
90
|
+
it { expect(currencies).to include('USD', 'DKK', 'SEK', 'NOK', 'GBP') }
|
28
91
|
end
|
29
92
|
|
30
93
|
describe '#exchange_with' do
|
@@ -79,7 +142,7 @@ describe 'ECB' do
|
|
79
142
|
rate = good_rates[to_cur]/good_rates[from_cur]
|
80
143
|
to_cents = factor * Money::Currency.wrap(to_cur).subunit_to_unit * rate
|
81
144
|
|
82
|
-
expect(fx(from_cents, from_cur, to_cur).cents).to eq(to_cents.floor)
|
145
|
+
expect(fx(from_cents, from_cur, to_cur).cents).to eq(to_cents.floor)
|
83
146
|
end
|
84
147
|
end
|
85
148
|
end
|
@@ -106,48 +169,9 @@ describe 'ECB' do
|
|
106
169
|
end
|
107
170
|
end
|
108
171
|
|
109
|
-
describe '#new' do
|
110
|
-
before(:each) { bank.auto_update = false }
|
111
|
-
|
112
|
-
let(:good_rates) do
|
113
|
-
{
|
114
|
-
'USD' => 1.3574, 'JPY' => 139.28, 'BGN' => 1.9558, 'CZK' => 27.594,
|
115
|
-
'DKK' => 7.4622, 'GBP' => 0.82380, 'HUF' => 310.97, 'LTL' => 3.4528,
|
116
|
-
'PLN' => 4.2312, 'RON' => 4.5110, 'SEK' => 8.8347, 'CHF' => 1.2233,
|
117
|
-
'NOK' => 8.4680, 'HRK' => 7.6605, 'RUB' => 47.8025, 'TRY' => 3.0808,
|
118
|
-
'AUD' => 1.5459, 'BRL' => 3.2955, 'CAD' => 1.5176, 'CNY' => 8.2302,
|
119
|
-
'HKD' => 10.5421, 'IDR' => 16551.39, 'INR' => 85.0840, 'KRW' => 1469.53,
|
120
|
-
'MXN' => 18.1111, 'MYR' => 4.5417, 'NZD' => 1.6624, 'PHP' => 61.527,
|
121
|
-
'SGD' => 1.7323, 'THB' => 44.745, 'ZAR' => 15.2700, 'ILS' => 4.7416,
|
122
|
-
}
|
123
|
-
end
|
124
|
-
|
125
|
-
context 'when cache file is good' do
|
126
|
-
it 'should use rates from cache' do
|
127
|
-
expect(bank.rates_date).to eq(Time.utc(2014, 01, 30, 14))
|
128
|
-
bank.currencies.each do |cur|
|
129
|
-
expect(bank.rates['EUR_TO_' + cur]).to eq(good_rates[cur])
|
130
|
-
end
|
131
|
-
end
|
132
|
-
end
|
133
|
-
|
134
|
-
context 'when cache file is bogus' do
|
135
|
-
it 'should fetch rates from ECB' do
|
136
|
-
expect{
|
137
|
-
Money::Bank::ECB::RATES_URL = File.expand_path(@tmpdir + '/eurofxref.zip')
|
138
|
-
}.to write(/warning: already initialized constant .*RATES_URL/).to(:stderr)
|
139
|
-
|
140
|
-
bogus = Money::Bank::ECB.new(@tmpdir + '/bogus_rates.csv')
|
141
|
-
bogus.auto_update = false
|
142
|
-
|
143
|
-
expect(bogus.rates_date).to eq(Time.utc(2014, 01, 31, 14))
|
144
|
-
end
|
145
|
-
end
|
146
|
-
end
|
147
|
-
|
148
172
|
describe '#auto_update' do
|
149
173
|
it 'should be on by default' do
|
150
|
-
expect(Money::Bank::ECB.new(@tmpdir + '/good_rates.csv').auto_update).to be_true
|
174
|
+
expect(Money::Bank::ECB.new(Money::Bank::ECB::CacheFile.new(@tmpdir + '/good_rates.csv')).auto_update).to be_true
|
151
175
|
end
|
152
176
|
end
|
153
177
|
|
@@ -158,8 +182,8 @@ describe 'ECB' do
|
|
158
182
|
|
159
183
|
expect(time).to be_a(Time)
|
160
184
|
expect(time).to eq(Time.utc(2014, 1, 30, 14))
|
161
|
-
expect(quotations).to be_a(
|
162
|
-
expect(quotations.
|
185
|
+
expect(quotations).to be_a(Array)
|
186
|
+
expect(quotations.map{|key,_| key}).to include('USD', 'DKK', 'JPY', 'ILS')
|
163
187
|
end
|
164
188
|
end
|
165
189
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: money-ecb
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Casper Thomsen
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-02-
|
11
|
+
date: 2014-02-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: money
|
@@ -60,13 +60,18 @@ files:
|
|
60
60
|
- .gitignore
|
61
61
|
- .travis.yml
|
62
62
|
- Gemfile
|
63
|
+
- Gemfile.lock
|
63
64
|
- README.rst
|
64
65
|
- Rakefile
|
65
66
|
- lib/money/bank/ecb.rb
|
67
|
+
- lib/money/bank/ecb/cache.rb
|
68
|
+
- lib/money/bank/ecb/cache_file.rb
|
69
|
+
- lib/money/bank/ecb/simple_cache.rb
|
66
70
|
- money-ecb.gemspec
|
67
71
|
- spec/assets/bogus_rates.csv
|
68
72
|
- spec/assets/eurofxref.zip
|
69
73
|
- spec/assets/good_rates.csv
|
74
|
+
- spec/ecb/cache_spec.rb
|
70
75
|
- spec/ecb_spec.rb
|
71
76
|
- spec/support/custom_expectations/write_expectation.rb
|
72
77
|
homepage: https://github.com/ct-clearhaus/money-ecb
|