money-open-exchange-rates 0.1.5 → 0.1.7

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
  SHA1:
3
- metadata.gz: 8e229d0e2b11a63d0b4393c6e05514ac21fc7c9b
4
- data.tar.gz: cd7819397cd60f5de0b8d00cb10d83a9081541e7
3
+ metadata.gz: 47727fe9bad23633da19274d859b19a6178fac03
4
+ data.tar.gz: 2ca0a29fd3ac60268bfe16f6bc5ce5245602b5fa
5
5
  SHA512:
6
- metadata.gz: bdc02f9b9ed0f60ab8fa3499428e6bab435f4b1b119dfc43fbb366f52191d7fdb87b1a330e69c1575c930ed10b560b33a1626ffa786c848c98f1d6637998996a
7
- data.tar.gz: 899a474ed72d4638ac0f2dc7b372d963b51cce20b8083b77f15a2807cbb26bdd726ba570dc5f2e5e50ef90e1796a511b6efad7be8e3b310de687821753c9f3c5
6
+ metadata.gz: 1858044994a092557f0f9db8107ed5e6b537efe1d6d95ee8654f0df7734c83805ea906bedda731ce2729a1dbf6b7b3c5d9846292581d2671da1db6f3a8a52a68
7
+ data.tar.gz: 893d31e26b8cf61e5242df6253486f7205bd5ba4af50f04e88ad1bec88243747d9705a95fb1bb3df7aab68d1990835816363d72b78daecf67467c19aca751852
data/README.markdown CHANGED
@@ -12,6 +12,11 @@ moe.cache = 'path/to/file/cache'
12
12
  moe.app_id = 'your app id from https://openexchangerates.org/signup'
13
13
  moe.update_rates
14
14
 
15
+ # (optional)
16
+ # set the seconds after than the current rates are automatically expired
17
+ # by default, they never expire
18
+ moe.ttl_in_seconds = 86400
19
+
15
20
  Money.default_bank = moe
16
21
  ```
17
22
 
@@ -20,7 +25,7 @@ perhaps with Redis or just a thread safe `Hash` (global). For example:
20
25
 
21
26
  ```ruby
22
27
  moe.cache = Proc.new do |v|
23
- key = 'money:exchange_rates']
28
+ key = 'money:exchange_rates'
24
29
  if v
25
30
  Thread.current[key] = v
26
31
  else
@@ -14,7 +14,12 @@ class Money
14
14
  OER_URL = 'http://openexchangerates.org/latest.json'
15
15
 
16
16
  attr_accessor :cache, :app_id
17
- attr_reader :doc, :oer_rates
17
+ attr_reader :doc, :oer_rates, :rates_expiration, :ttl_in_seconds
18
+
19
+ def ttl_in_seconds=(value)
20
+ @ttl_in_seconds = value
21
+ refresh_rates_expiration if ttl_in_seconds
22
+ end
18
23
 
19
24
  def update_rates
20
25
  exchange_rates.each do |exchange_rate|
@@ -42,15 +47,26 @@ class Money
42
47
  def exchange_with(from, to_currency)
43
48
  return from if same_currency?(from.currency, to_currency)
44
49
  rate = get_rate(from.currency, to_currency)
45
- unless rate
46
- from_base_rate = get_rate("USD", from.currency)
47
- to_base_rate = get_rate("USD", to_currency)
48
- raise(Money::Bank::UnknownRateFormat, "No conversion rate known for '#{from.currency.iso_code}' -> '#{to_currency}'") if from_base_rate.nil? || to_base_rate.nil?
49
- rate = to_base_rate.to_f / from_base_rate.to_f
50
- end
51
50
  Money.new(((Money::Currency.wrap(to_currency).subunit_to_unit.to_f / from.currency.subunit_to_unit.to_f) * from.cents * rate).round, to_currency)
52
51
  end
53
52
 
53
+ def get_rate(from_currency, to_currency)
54
+ expire_rates
55
+ super(from_currency, to_currency) || begin
56
+ from_base_rate = super("USD", from_currency)
57
+ to_base_rate = super("USD", to_currency)
58
+ raise(Money::Bank::UnknownRateFormat, "No conversion rate known for '#{from_currency}' -> '#{to_currency}'") if from_base_rate.nil? || to_base_rate.nil?
59
+ to_base_rate.to_f / from_base_rate.to_f
60
+ end
61
+ end
62
+
63
+ def expire_rates
64
+ if ttl_in_seconds && rates_expiration <= Time.now
65
+ update_rates
66
+ refresh_rates_expiration
67
+ end
68
+ end
69
+
54
70
  protected
55
71
 
56
72
  # Store the provided text data by calling the proc method provided
@@ -98,6 +114,10 @@ class Money
98
114
  @oer_rates = @doc['rates']
99
115
  @doc['rates']
100
116
  end
117
+
118
+ def refresh_rates_expiration
119
+ @rates_expiration = Time.now + ttl_in_seconds
120
+ end
101
121
  end
102
122
  end
103
123
  end
@@ -9,8 +9,6 @@ describe Money::Bank::OpenExchangeRatesBank do
9
9
  end
10
10
 
11
11
  describe 'exchange' do
12
- include RR::Adapters::TestUnit
13
-
14
12
  before do
15
13
  @bank = Money::Bank::OpenExchangeRatesBank.new
16
14
  @bank.app_id = TEST_APP_ID
@@ -104,7 +102,6 @@ describe Money::Bank::OpenExchangeRatesBank do
104
102
  end
105
103
 
106
104
  describe 'App ID' do
107
- include RR::Adapters::TestUnit
108
105
 
109
106
  before do
110
107
  @bank = Money::Bank::OpenExchangeRatesBank.new
@@ -123,8 +120,6 @@ describe Money::Bank::OpenExchangeRatesBank do
123
120
  end
124
121
 
125
122
  describe 'no cache' do
126
- include RR::Adapters::TestUnit
127
-
128
123
  before do
129
124
  @bank = Money::Bank::OpenExchangeRatesBank.new
130
125
  @bank.cache = nil
@@ -143,7 +138,6 @@ describe Money::Bank::OpenExchangeRatesBank do
143
138
  end
144
139
 
145
140
  describe 'no valid file for cache' do
146
- include RR::Adapters::TestUnit
147
141
  before do
148
142
  @bank = Money::Bank::OpenExchangeRatesBank.new
149
143
  @bank.cache = "space_dir#{rand(999999999)}/out_space_file.json"
@@ -162,8 +156,6 @@ describe Money::Bank::OpenExchangeRatesBank do
162
156
  end
163
157
 
164
158
  describe 'using proc for cache' do
165
- include RR::Adapters::TestUnit
166
-
167
159
  before :each do
168
160
  $global_rates = nil
169
161
  @bank = Money::Bank::OpenExchangeRatesBank.new
@@ -195,8 +187,6 @@ describe Money::Bank::OpenExchangeRatesBank do
195
187
  end
196
188
 
197
189
  describe 'save rates' do
198
- include RR::Adapters::TestUnit
199
-
200
190
  before do
201
191
  @bank = Money::Bank::OpenExchangeRatesBank.new
202
192
  @bank.app_id = TEST_APP_ID
@@ -239,4 +229,88 @@ describe Money::Bank::OpenExchangeRatesBank do
239
229
  File.delete @temp_cache_path
240
230
  end
241
231
  end
232
+
233
+ describe 'get rate' do
234
+ subject { Money::Bank::OpenExchangeRatesBank.new }
235
+ LVL_TO_LTL = 5
236
+ USD_TO_RUB = 50
237
+ USD_TO_EUR = 1.3
238
+
239
+ before do
240
+ # some kind of stubbing base class
241
+ Money::Bank::VariableExchange.class_eval do
242
+ def get_rate(from, to)
243
+ if from == 'LVL' && to == 'LTL'
244
+ LVL_TO_LTL
245
+ elsif from == 'USD' && to == 'RUB'
246
+ USD_TO_RUB
247
+ elsif from == 'USD' && to == 'EUR'
248
+ USD_TO_EUR
249
+ else
250
+ nil
251
+ end
252
+ end
253
+ end
254
+ end
255
+
256
+ it 'returns rate if Money::Bank::VariableExchange#get_rate returns rate' do
257
+ subject.get_rate('LVL','LTL').must_equal LVL_TO_LTL
258
+ end
259
+
260
+ describe 'calculate cross rate using "USD" rate value if no data was returned by Money::Bank::VariableExchange#get_rate' do
261
+
262
+ it 'returns cross rate if "USD" rates for provided currencies exist' do
263
+ eur_to_rub_cross_rate = USD_TO_RUB / USD_TO_EUR
264
+ subject.get_rate('EUR', 'RUB').must_equal eur_to_rub_cross_rate
265
+ end
266
+
267
+ it 'raises Money::Bank::UnknownRateFormat if no cross rates found' do
268
+ ->{ subject.get_rate('ZAR', 'ZMK') }.must_raise Money::Bank::UnknownRateFormat
269
+ end
270
+ end
271
+ end
272
+
273
+ describe '#expire_rates' do
274
+ before do
275
+ @bank = Money::Bank::OpenExchangeRatesBank.new
276
+ @bank.app_id = TEST_APP_ID
277
+ @bank.ttl_in_seconds = 1000
278
+ @usd_eur_rate = 0.655
279
+ @bank.add_rate('USD', 'EUR', @usd_eur_rate)
280
+ @temp_cache_path = File.expand_path(File.join(File.dirname(__FILE__), 'tmp.json'))
281
+ @bank.cache = @temp_cache_path
282
+ stub(OpenURI::OpenRead).open(Money::Bank::OpenExchangeRatesBank::OER_URL) { File.read @cache_path }
283
+ end
284
+
285
+ describe 'when the ttl has expired' do
286
+ before do
287
+ new_time = Time.now + 1001
288
+ Timecop.freeze(new_time)
289
+ end
290
+
291
+ after do
292
+ Timecop.return
293
+ end
294
+
295
+ it 'should update the rates' do
296
+ @bank.update_rates
297
+ @bank.get_rate('USD', 'EUR').wont_equal @usd_eur_rate
298
+ end
299
+
300
+ it 'updates the next expiration time' do
301
+ exp_time = Time.now + 1000
302
+
303
+ @bank.expire_rates
304
+ @bank.rates_expiration.must_equal exp_time
305
+ end
306
+ end
307
+
308
+ describe 'when the ttl has not expired' do
309
+ it 'not should update the rates' do
310
+ exp_time = @bank.rates_expiration
311
+ @bank.expire_rates
312
+ @bank.rates_expiration.must_equal exp_time
313
+ end
314
+ end
315
+ end
242
316
  end
data/test/test_helper.rb CHANGED
@@ -2,6 +2,10 @@
2
2
  require 'minitest/autorun'
3
3
  require 'rr'
4
4
  require 'money/bank/open_exchange_rates_bank'
5
+ require 'monetize/core_extensions'
6
+ require 'timecop'
7
+ require 'pry'
8
+ Money.silence_core_extensions_deprecations = true
5
9
 
6
10
  TEST_APP_ID_PATH = File.join(File.dirname(__FILE__), '..', 'TEST_APP_ID')
7
11
  TEST_APP_ID = ENV['TEST_APP_ID'] || File.read(TEST_APP_ID_PATH)
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: 0.1.5
4
+ version: 0.1.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Laurent Arnoud
@@ -9,76 +9,104 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-07-11 00:00:00.000000000 Z
12
+ date: 2014-04-15 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: money
16
16
  requirement: !ruby/object:Gem::Requirement
17
17
  requirements:
18
- - - '>='
18
+ - - ">="
19
19
  - !ruby/object:Gem::Version
20
20
  version: 3.7.1
21
21
  type: :runtime
22
22
  prerelease: false
23
23
  version_requirements: !ruby/object:Gem::Requirement
24
24
  requirements:
25
- - - '>='
25
+ - - ">="
26
26
  - !ruby/object:Gem::Version
27
27
  version: 3.7.1
28
28
  - !ruby/object:Gem::Dependency
29
29
  name: minitest
30
30
  requirement: !ruby/object:Gem::Requirement
31
31
  requirements:
32
- - - '>='
32
+ - - ">="
33
33
  - !ruby/object:Gem::Version
34
34
  version: '2.0'
35
35
  type: :development
36
36
  prerelease: false
37
37
  version_requirements: !ruby/object:Gem::Requirement
38
38
  requirements:
39
- - - '>='
39
+ - - ">="
40
40
  - !ruby/object:Gem::Version
41
41
  version: '2.0'
42
+ - !ruby/object:Gem::Dependency
43
+ name: pry
44
+ requirement: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - ">="
47
+ - !ruby/object:Gem::Version
48
+ version: '0'
49
+ type: :development
50
+ prerelease: false
51
+ version_requirements: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ version: '0'
42
56
  - !ruby/object:Gem::Dependency
43
57
  name: rr
44
58
  requirement: !ruby/object:Gem::Requirement
45
59
  requirements:
46
- - - '>='
60
+ - - ">="
47
61
  - !ruby/object:Gem::Version
48
62
  version: 1.0.4
49
63
  type: :development
50
64
  prerelease: false
51
65
  version_requirements: !ruby/object:Gem::Requirement
52
66
  requirements:
53
- - - '>='
67
+ - - ">="
54
68
  - !ruby/object:Gem::Version
55
69
  version: 1.0.4
56
70
  - !ruby/object:Gem::Dependency
57
71
  name: rake
58
72
  requirement: !ruby/object:Gem::Requirement
59
73
  requirements:
60
- - - '>='
74
+ - - ">="
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ type: :development
78
+ prerelease: false
79
+ version_requirements: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - ">="
82
+ - !ruby/object:Gem::Version
83
+ version: '0'
84
+ - !ruby/object:Gem::Dependency
85
+ name: timecop
86
+ requirement: !ruby/object:Gem::Requirement
87
+ requirements:
88
+ - - ">="
61
89
  - !ruby/object:Gem::Version
62
90
  version: '0'
63
91
  type: :development
64
92
  prerelease: false
65
93
  version_requirements: !ruby/object:Gem::Requirement
66
94
  requirements:
67
- - - '>='
95
+ - - ">="
68
96
  - !ruby/object:Gem::Version
69
97
  version: '0'
70
98
  - !ruby/object:Gem::Dependency
71
99
  name: json
72
100
  requirement: !ruby/object:Gem::Requirement
73
101
  requirements:
74
- - - '>='
102
+ - - ">="
75
103
  - !ruby/object:Gem::Version
76
104
  version: '1.7'
77
105
  type: :runtime
78
106
  prerelease: false
79
107
  version_requirements: !ruby/object:Gem::Requirement
80
108
  requirements:
81
- - - '>='
109
+ - - ">="
82
110
  - !ruby/object:Gem::Version
83
111
  version: '1.7'
84
112
  description: A gem that calculates the exchange rate using published rates from open-exchange-rates.
@@ -89,15 +117,16 @@ extensions: []
89
117
  extra_rdoc_files:
90
118
  - README.markdown
91
119
  files:
120
+ - Gemfile
92
121
  - LICENSE
93
122
  - README.markdown
94
- - Gemfile
95
123
  - lib/money/bank/open_exchange_rates_bank.rb
96
124
  - test/latest.json
97
- - test/test_helper.rb
98
125
  - test/open_exchange_rates_bank_test.rb
126
+ - test/test_helper.rb
99
127
  homepage: http://github.com/spk/money-open-exchange-rates
100
- licenses: []
128
+ licenses:
129
+ - MIT
101
130
  metadata: {}
102
131
  post_install_message:
103
132
  rdoc_options: []
@@ -105,17 +134,17 @@ require_paths:
105
134
  - lib
106
135
  required_ruby_version: !ruby/object:Gem::Requirement
107
136
  requirements:
108
- - - '>='
137
+ - - ">="
109
138
  - !ruby/object:Gem::Version
110
139
  version: 1.9.2
111
140
  required_rubygems_version: !ruby/object:Gem::Requirement
112
141
  requirements:
113
- - - '>='
142
+ - - ">="
114
143
  - !ruby/object:Gem::Version
115
144
  version: '0'
116
145
  requirements: []
117
146
  rubyforge_project:
118
- rubygems_version: 2.0.2
147
+ rubygems_version: 2.2.2
119
148
  signing_key:
120
149
  specification_version: 4
121
150
  summary: A gem that calculates the exchange rate using published rates from open-exchange-rates.