money-open-exchange-rates 1.0.0 → 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1cbadeb275d02260424c03168a97965ac705de08b518e2310a58b7dd649a8b53
4
- data.tar.gz: 85467d626de3da3637f10a2e9113899ea3ca40df60c845f3fef2b251c618810b
3
+ metadata.gz: 9409fd168f31d0335f71e0713e1a014ff3d23ae9abe908d6a78b1d13d05b579f
4
+ data.tar.gz: e49b7cecf6992a5a5a08d4998ce5f060dd7dd0d286bbca34dbade198669f12ce
5
5
  SHA512:
6
- metadata.gz: 2082ea6e2ec8df6b788bda461537b1dd70896d1f849b3b4e644b9fd30a2ee3c5fa1c8168999e4555dabd9b2cf4d2a2b1c714b6c0ec61ee730236c7cd6f7426e9
7
- data.tar.gz: 5128bf8ee272026571487a92828550b7e3de82f9d7bd409d014048f1cb2413a26b21fd4261e07df9bfa3105cc0ef1700686427adcfae7adfa37125199a2b056f
6
+ metadata.gz: 5450e1dcb1f9e856d21efa06f02200bbf606b0299727a3c844f44e0709ae5efae2172128420eaaf8dec956793e589bdfb34a7103ba78708a25c24c2c112888c8
7
+ data.tar.gz: 5728bf847be03d84e0c2191cf4f9da05ba2c6b2219aacb11a55f957f14dd207b751258e99518c7a164b8ae91f10f951d9f2566807de4b2e61c8874cd0d03aea2
data/History.md CHANGED
@@ -1,4 +1,9 @@
1
1
 
2
+ v1.0.1 / 2018-03-25
3
+ ===================
4
+
5
+ * Use BigDecimal instead of Float
6
+
2
7
  v1.0.0 / 2018-03-25
3
8
  ===================
4
9
 
data/README.md CHANGED
@@ -96,7 +96,7 @@ With `Rails` cache example:
96
96
 
97
97
  ~~~ ruby
98
98
  OXR_CACHE_KEY = 'money:exchange_rates'.freeze
99
- OXR_CACHE_TTL = 10
99
+ OXR_CACHE_TTL = 86400
100
100
  # using same ttl with refreshing current rates and cache
101
101
  oxr.ttl_in_seconds = OXR_CACHE_TTL
102
102
  oxr.cache = Proc.new do |text|
@@ -113,11 +113,11 @@ or using base currency rate to both currencies forming the pair.
113
113
 
114
114
  ## Full example configuration initializer with Rails and cache
115
115
 
116
- ~~~
116
+ ~~~ ruby
117
117
  require 'money/bank/open_exchange_rates_bank'
118
118
 
119
119
  OXR_CACHE_KEY = 'money:exchange_rates'.freeze
120
- OXR_CACHE_TTL = 10
120
+ OXR_CACHE_TTL = 86400
121
121
  oxr = Money::Bank::OpenExchangeRatesBank.new
122
122
  oxr.ttl_in_seconds = OXR_CACHE_TTL
123
123
  oxr.cache = Proc.new do |text|
@@ -326,7 +326,7 @@ class Money
326
326
  from_base_rate = get_rate_or_calc_inverse(source, from_currency, opts)
327
327
  to_base_rate = get_rate_or_calc_inverse(source, to_currency, opts)
328
328
  if to_base_rate && from_base_rate
329
- rate = to_base_rate.to_f / from_base_rate
329
+ rate = BigDecimal(to_base_rate) / from_base_rate
330
330
  add_rate(from_currency, to_currency, rate)
331
331
  return rate
332
332
  end
@@ -2,5 +2,5 @@
2
2
 
3
3
  # Module for version constant
4
4
  module OpenExchangeRatesBank
5
- VERSION = '1.0.0'.freeze
5
+ VERSION = '1.0.1'.freeze
6
6
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: money-open-exchange-rates
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Laurent Arnoud
@@ -142,7 +142,6 @@ files:
142
142
  - test/integration/Gemfile.lock
143
143
  - test/integration/api.rb
144
144
  - test/open_exchange_rates_bank_test.rb
145
- - test/open_exchange_rates_bank_test.rb.orig
146
145
  - test/test_helper.rb
147
146
  homepage: http://github.com/spk/money-open-exchange-rates
148
147
  licenses:
@@ -1,393 +0,0 @@
1
- require File.expand_path(File.join(File.dirname(__FILE__), 'test_helper'))
2
-
3
- # rubocop:disable Metrics/BlockLength
4
- describe Money::Bank::OpenExchangeRatesBank do
5
- subject { Money::Bank::OpenExchangeRatesBank.new }
6
- let(:oer_url) { Money::Bank::OpenExchangeRatesBank::OER_URL }
7
- let(:oer_historical_url) do
8
- Money::Bank::OpenExchangeRatesBank::OER_HISTORICAL_URL
9
- end
10
-
11
- let(:temp_cache_path) do
12
- data_file('tmp.json')
13
- end
14
- let(:oer_latest_path) do
15
- data_file('latest.json')
16
- end
17
- let(:oer_historical_path) do
18
- data_file('2015-01-01.json')
19
- end
20
-
21
- describe 'exchange' do
22
- before do
23
- add_to_webmock(subject)
24
- subject.cache = temp_cache_path
25
- subject.save_rates
26
- end
27
-
28
- after do
29
- File.unlink(temp_cache_path)
30
- end
31
-
32
- describe 'without rates' do
33
- it 'able to exchange a money to its own currency even without rates' do
34
- money = Money.new(0, 'USD')
35
- subject.exchange_with(money, 'USD').must_equal money
36
- end
37
-
38
- it "raise if it can't find an exchange rate" do
39
- money = Money.new(0, 'USD')
40
- proc { subject.exchange_with(money, 'SSP') }
41
- .must_raise Money::Bank::UnknownRate
42
- end
43
- end
44
-
45
- describe 'with rates' do
46
- before do
47
- subject.update_rates
48
- end
49
-
50
- it 'should be able to exchange money from USD to a known exchange rate' do
51
- money = Money.new(100, 'USD')
52
- subject.exchange_with(money, 'BBD').must_equal Money.new(200, 'BBD')
53
- end
54
-
55
- it 'should be able to exchange money from a known exchange rate to USD' do
56
- money = Money.new(200, 'BBD')
57
- subject.exchange_with(money, 'USD').must_equal Money.new(100, 'USD')
58
- end
59
-
60
- it 'should be able to exchange money when direct rate is unknown' do
61
- money = Money.new(100, 'BBD')
62
- subject.exchange_with(money, 'BMD').must_equal Money.new(50, 'BMD')
63
- end
64
-
65
- it "should raise if it can't find an exchange rate" do
66
- money = Money.new(0, 'USD')
67
- proc { subject.exchange_with(money, 'SSP') }
68
- .must_raise Money::Bank::UnknownRate
69
- end
70
- end
71
- end
72
-
73
- describe 'update_rates' do
74
- before do
75
- subject.app_id = TEST_APP_ID
76
- subject.cache = oer_latest_path
77
- subject.update_rates
78
- end
79
-
80
- it 'should update itself with exchange rates from OpenExchangeRates' do
81
- subject.oer_rates.keys.each do |currency|
82
- next unless Money::Currency.find(currency)
83
- subject.get_rate('USD', currency).must_be :>, 0
84
- end
85
- end
86
-
87
- it 'should not return 0 with integer rate' do
88
- wtf = {
89
- priority: 1,
90
- iso_code: 'WTF',
91
- name: 'WTF',
92
- symbol: 'WTF',
93
- subunit: 'Cent',
94
- subunit_to_unit: 1000,
95
- separator: '.',
96
- delimiter: ','
97
- }
98
- Money::Currency.register(wtf)
99
- subject.add_rate('USD', 'WTF', 2)
100
- subject.add_rate('WTF', 'USD', 2)
101
- subject.exchange_with(5000.to_money('WTF'), 'USD').cents.wont_equal 0
102
- end
103
-
104
- # in response to #4
105
- it 'should exchange btc' do
106
- btc = {
107
- priority: 1,
108
- iso_code: 'BTC',
109
- name: 'Bitcoin',
110
- symbol: 'BTC',
111
- subunit: 'Cent',
112
- subunit_to_unit: 1000,
113
- separator: '.',
114
- delimiter: ','
115
- }
116
- Money::Currency.register(btc)
117
- rate = 13.7603
118
- subject.add_rate('USD', 'BTC', 1 / 13.7603)
119
- subject.add_rate('BTC', 'USD', rate)
120
- subject.exchange_with(100.to_money('BTC'), 'USD').cents.must_equal 137_603
121
- end
122
- end
123
-
124
- describe 'App ID' do
125
- before do
126
- subject.cache = temp_cache_path
127
- end
128
-
129
- it 'should raise an error if no App ID is set' do
130
- proc { subject.save_rates }.must_raise Money::Bank::NoAppId
131
- end
132
-
133
- # TODO: As App IDs are compulsory soon, need to add more tests handle
134
- # app_id-specific errors from
135
- # https://openexchangerates.org/documentation#errors
136
- end
137
-
138
- describe 'no cache' do
139
- before do
140
- subject.cache = nil
141
- add_to_webmock(subject)
142
- end
143
-
144
- it 'should get from url' do
145
- subject.update_rates
146
- subject.oer_rates.wont_be_empty
147
- end
148
-
149
- it 'should raise an error if invalid path is given to save_rates' do
150
- proc { subject.save_rates }.must_raise Money::Bank::InvalidCache
151
- end
152
- end
153
-
154
- describe 'secure_connection' do
155
- before do
156
- subject.app_id = TEST_APP_ID
157
- end
158
-
159
- describe 'historical' do
160
- before do
161
- subject.date = '2015-01-01'
162
- end
163
-
164
- <<<<<<< HEAD
165
- let(:historical_url) do
166
- "#{oer_historical_url}#{subject.date}.json?app_id=#{TEST_APP_ID}&show_alternative=false"
167
- end
168
-
169
- it 'should use the secure https url' do
170
- =======
171
- def historical_url
172
- "#{oer_historical_url}#{subject.date}.json?" \
173
- "app_id=#{TEST_APP_ID}&show_alternative=false"
174
- end
175
-
176
- def historical_secure_url
177
- "#{oer_historical_secure_url}#{subject.date}.json?" \
178
- "app_id=#{TEST_APP_ID}&show_alternative=false"
179
- end
180
-
181
- it 'should use the non-secure http url if secure_connection is nil' do
182
- subject.secure_connection = nil
183
- subject.source_url.must_equal historical_url
184
- subject.source_url.must_include 'http://'
185
- subject.source_url.must_include "/api/historical/#{subject.date}.json"
186
- end
187
-
188
- it 'should use the non-secure http url if secure_connection is false' do
189
- subject.secure_connection = false
190
- >>>>>>> Fix offenses
191
- subject.source_url.must_equal historical_url
192
- subject.source_url.must_include 'https://'
193
- subject.source_url.must_include "/api/historical/#{subject.date}.json"
194
- end
195
- end
196
-
197
- describe 'latest' do
198
- it 'should use the secure https url' do
199
- subject.source_url.must_equal source_secure_url
200
- subject.source_url.must_include 'https://'
201
- subject.source_url.must_include '/api/latest.json'
202
- end
203
- end
204
- end
205
-
206
- describe 'no valid file for cache' do
207
- before do
208
- subject.cache = "space_dir#{rand(999_999_999)}/out_space_file.json"
209
- add_to_webmock(subject)
210
- end
211
-
212
- it 'should get from url' do
213
- subject.update_rates
214
- subject.oer_rates.wont_be_empty
215
- end
216
-
217
- it 'should raise an error if invalid path is given to save_rates' do
218
- proc { subject.save_rates }.must_raise Money::Bank::InvalidCache
219
- end
220
- end
221
-
222
- describe 'using proc for cache' do
223
- before do
224
- @global_rates = nil
225
- subject.cache = proc do |v|
226
- if v
227
- @global_rates = v
228
- else
229
- @global_rates
230
- end
231
- end
232
- add_to_webmock(subject)
233
- end
234
-
235
- it 'should get from url normally' do
236
- subject.update_rates
237
- subject.oer_rates.wont_be_empty
238
- end
239
-
240
- it 'should save from url and get from cache' do
241
- subject.save_rates
242
- @global_rates.wont_be_empty
243
- dont_allow(subject).source_url
244
- subject.update_rates
245
- subject.oer_rates.wont_be_empty
246
- end
247
- end
248
-
249
- describe 'save rates' do
250
- before do
251
- add_to_webmock(subject)
252
- subject.cache = temp_cache_path
253
- subject.save_rates
254
- end
255
-
256
- after do
257
- File.unlink(temp_cache_path)
258
- end
259
-
260
- it 'should allow update after save' do
261
- begin
262
- subject.update_rates
263
- rescue
264
- assert false, 'Should allow updating after saving'
265
- end
266
- end
267
-
268
- it 'should not break an existing file if save fails to read' do
269
- initial_size = File.read(temp_cache_path).size
270
- stub(subject).read_from_url { '' }
271
- subject.save_rates
272
- File.open(temp_cache_path).read.size.must_equal initial_size
273
- end
274
-
275
- it 'should not break an existing file if save returns json without rates' do
276
- initial_size = File.read(temp_cache_path).size
277
- stub(subject).read_from_url { '{"error": "An error"}' }
278
- subject.save_rates
279
- File.open(temp_cache_path).read.size.must_equal initial_size
280
- end
281
-
282
- it 'should not break an existing file if save returns a invalid json' do
283
- initial_size = File.read(temp_cache_path).size
284
- stub(subject).read_from_url { '{invalid_json: "An error"}' }
285
- subject.save_rates
286
- File.open(temp_cache_path).read.size.must_equal initial_size
287
- end
288
- end
289
-
290
- describe '#expire_rates' do
291
- before do
292
- add_to_webmock(subject)
293
- subject.ttl_in_seconds = 1000
294
- @old_usd_eur_rate = 0.655
295
- # see test/latest.json +52
296
- @new_usd_eur_rate = 0.79085
297
- subject.add_rate('USD', 'EUR', @old_usd_eur_rate)
298
- subject.cache = temp_cache_path
299
- subject.save_rates
300
- end
301
-
302
- after do
303
- File.unlink(temp_cache_path)
304
- end
305
-
306
- describe 'when the ttl has expired' do
307
- it 'should update the rates' do
308
- subject.get_rate('USD', 'EUR').must_equal @old_usd_eur_rate
309
- Timecop.freeze(Time.now + 1001) do
310
- subject.get_rate('USD', 'EUR').wont_equal @old_usd_eur_rate
311
- subject.get_rate('USD', 'EUR').must_equal @new_usd_eur_rate
312
- end
313
- end
314
-
315
- it 'updates the next expiration time' do
316
- Timecop.freeze(Time.now + 1001) do
317
- exp_time = Time.now + 1000
318
- subject.expire_rates
319
- subject.rates_expiration.must_equal exp_time
320
- end
321
- end
322
- end
323
-
324
- describe 'when the ttl has not expired' do
325
- it 'not should update the rates' do
326
- exp_time = subject.rates_expiration
327
- subject.expire_rates
328
- subject.rates_expiration.must_equal exp_time
329
- end
330
- end
331
- end
332
-
333
- describe 'historical' do
334
- before do
335
- add_to_webmock(subject)
336
- # see test/latest.json +52
337
- @latest_usd_eur_rate = 0.79085
338
- # see test/2015-01-01.json +52
339
- @old_usd_eur_rate = 0.830151
340
- subject.update_rates
341
- end
342
-
343
- it 'should be different than the latest' do
344
- subject.get_rate('USD', 'EUR').must_equal @latest_usd_eur_rate
345
- subject.date = '2015-01-01'
346
- add_to_webmock(subject, oer_historical_path)
347
- subject.update_rates
348
- subject.get_rate('USD', 'EUR').must_equal @old_usd_eur_rate
349
- end
350
- end
351
-
352
- describe 'source currency' do
353
- it 'should be changed when a known currency is given' do
354
- subject.source = 'EUR'
355
- subject.source.must_equal 'EUR'
356
- end
357
-
358
- it 'should use USD when given unknown currency' do
359
- subject.source = 'invalid'
360
- subject.source.must_equal 'USD'
361
- end
362
- end
363
-
364
- describe 'show alternative' do
365
- describe 'when no value given' do
366
- before do
367
- subject.show_alternative = nil
368
- end
369
-
370
- it 'should return the default value' do
371
- subject.show_alternative.must_equal false
372
- end
373
-
374
- it 'should include show_alternative param as false' do
375
- subject.source_url.must_include 'show_alternative=false'
376
- end
377
- end
378
-
379
- describe 'when value is given' do
380
- before do
381
- subject.show_alternative = true
382
- end
383
-
384
- it 'should return the value' do
385
- subject.show_alternative.must_equal true
386
- end
387
-
388
- it 'should include show_alternative param as true' do
389
- subject.source_url.must_include 'show_alternative=true'
390
- end
391
- end
392
- end
393
- end