exchange 0.8.0 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +1 -0
- data/.rspec +1 -1
- data/Gemfile.lock +3 -3
- data/README.rdoc +115 -47
- data/benchmark/benchmark.rb +49 -0
- data/changelog.rdoc +8 -1
- data/lib/exchange.rb +4 -4
- data/lib/exchange/base.rb +1 -1
- data/lib/exchange/cache.rb +2 -0
- data/lib/exchange/cache/base.rb +20 -6
- data/lib/exchange/cache/configuration.rb +24 -0
- data/lib/exchange/cache/file.rb +24 -9
- data/lib/exchange/cache/memcached.rb +3 -3
- data/lib/exchange/cache/memory.rb +89 -0
- data/lib/exchange/cache/rails.rb +1 -1
- data/lib/exchange/cache/redis.rb +4 -4
- data/lib/exchange/configurable.rb +53 -0
- data/lib/exchange/configuration.rb +32 -26
- data/lib/exchange/core_extensions.rb +3 -0
- data/lib/exchange/core_extensions/cachify.rb +25 -0
- data/lib/exchange/core_extensions/float/error_safe.rb +25 -0
- data/lib/{core_extensions → exchange/core_extensions/numeric}/conversability.rb +12 -12
- data/lib/exchange/external_api.rb +2 -1
- data/lib/exchange/external_api/base.rb +34 -9
- data/lib/exchange/external_api/call.rb +6 -8
- data/lib/exchange/external_api/configuration.rb +25 -0
- data/lib/exchange/external_api/ecb.rb +16 -25
- data/lib/exchange/external_api/json.rb +11 -1
- data/lib/exchange/external_api/open_exchange_rates.rb +65 -0
- data/lib/exchange/external_api/xavier_media.rb +7 -7
- data/lib/exchange/iso_4217.rb +32 -5
- data/lib/exchange/{currency.rb → money.rb} +112 -110
- data/lib/exchange/typecasting.rb +94 -0
- data/spec/exchange/cache/base_spec.rb +2 -2
- data/spec/exchange/cache/configuration_spec.rb +56 -0
- data/spec/exchange/cache/file_spec.rb +10 -8
- data/spec/exchange/cache/memcached_spec.rb +9 -18
- data/spec/exchange/cache/memory_spec.rb +122 -0
- data/spec/exchange/cache/no_cache_spec.rb +5 -15
- data/spec/exchange/cache/rails_spec.rb +2 -6
- data/spec/exchange/cache/redis_spec.rb +8 -18
- data/spec/exchange/configuration_spec.rb +31 -7
- data/spec/exchange/core_extensions/array/cachify_spec.rb +12 -0
- data/spec/exchange/core_extensions/float/error_safe_spec.rb +49 -0
- data/spec/exchange/core_extensions/hash/cachify_spec.rb +12 -0
- data/spec/exchange/core_extensions/numeric/cachify_spec.rb +26 -0
- data/spec/{core_extensions → exchange/core_extensions/numeric}/conversability_spec.rb +22 -22
- data/spec/exchange/core_extensions/string/cachify_spec.rb +59 -0
- data/spec/exchange/core_extensions/symbol/cachify_spec.rb +12 -0
- data/spec/exchange/external_api/base_spec.rb +10 -7
- data/spec/exchange/external_api/call_spec.rb +3 -0
- data/spec/exchange/external_api/configuration_spec.rb +52 -0
- data/spec/exchange/external_api/ecb_spec.rb +8 -5
- data/spec/exchange/external_api/open_exchange_rates_spec.rb +70 -0
- data/spec/exchange/external_api/xavier_media_spec.rb +8 -5
- data/spec/exchange/iso_4217_spec.rb +208 -20
- data/spec/exchange/{currency_spec.rb → money_spec.rb} +102 -82
- data/spec/exchange/typecasting_spec.rb +86 -0
- metadata +117 -71
- data/exchange-0.7.5.gem +0 -0
- data/exchange-0.7.6.gem +0 -0
- data/lib/exchange/external_api/currency_bot.rb +0 -61
- data/spec/exchange/external_api/currency_bot_spec.rb +0 -63
@@ -1,11 +1,11 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
describe "Exchange::
|
4
|
-
subject { Exchange::
|
3
|
+
describe "Exchange::Money" do
|
4
|
+
subject { Exchange::Money.new(40, :usd) }
|
5
5
|
before(:all) do
|
6
6
|
Exchange.configuration = Exchange::Configuration.new do |c|
|
7
7
|
c.api = {
|
8
|
-
:subclass => :
|
8
|
+
:subclass => :open_exchange_rates
|
9
9
|
}
|
10
10
|
c.cache = {
|
11
11
|
:subclass => :no_cache
|
@@ -14,22 +14,30 @@ describe "Exchange::Currency" do
|
|
14
14
|
end
|
15
15
|
end
|
16
16
|
after(:all) do
|
17
|
-
Exchange.configuration
|
18
|
-
c.api = {
|
19
|
-
:subclass => :memcached
|
20
|
-
}
|
21
|
-
end
|
17
|
+
Exchange.configuration.reset
|
22
18
|
end
|
23
19
|
it "should initialize with a number and a currency" do
|
24
20
|
subject.value.should == 40
|
25
21
|
subject.currency.should == :usd
|
26
22
|
end
|
23
|
+
describe "initializing with a block" do
|
24
|
+
it "should be possible" do
|
25
|
+
currency = Exchange::Money.new(40) do |c|
|
26
|
+
c.currency = :usd
|
27
|
+
c.time = Time.gm(2012,9,9)
|
28
|
+
end
|
29
|
+
|
30
|
+
currency.value.should == 40
|
31
|
+
currency.currency.should == :usd
|
32
|
+
currency.time.should == Time.gm(2012,9,9)
|
33
|
+
end
|
34
|
+
end
|
27
35
|
describe "convert_to" do
|
28
36
|
it "should be able to convert itself to other currencies" do
|
29
37
|
mock_api("http://openexchangerates.org/api/latest.json?app_id=", fixture('api_responses/example_json_api.json'), 3)
|
30
38
|
subject.convert_to(:chf).value.round(2).should == 36.5
|
31
39
|
subject.convert_to(:chf).currency.should == :chf
|
32
|
-
subject.convert_to(:chf).should be_kind_of Exchange::
|
40
|
+
subject.convert_to(:chf).should be_kind_of Exchange::Money
|
33
41
|
end
|
34
42
|
end
|
35
43
|
describe "operations" do
|
@@ -46,20 +54,20 @@ describe "Exchange::Currency" do
|
|
46
54
|
end
|
47
55
|
it "should be able to add another currency value" do
|
48
56
|
mock_api("http://openexchangerates.org/api/latest.json?app_id=", fixture('api_responses/example_json_api.json'), 2)
|
49
|
-
(subject + Exchange::
|
50
|
-
(subject + Exchange::
|
57
|
+
(subject + Exchange::Money.new(30, :chf)).value.round(2).should == 72.87
|
58
|
+
(subject + Exchange::Money.new(30, :sek)).currency.should == :usd
|
51
59
|
subject.value.round(2).should == 40
|
52
60
|
subject.currency.should == :usd
|
53
61
|
end
|
54
62
|
it "should raise when currencies get mixed and the configuration does not allow it" do
|
55
63
|
Exchange.configuration.allow_mixed_operations = false
|
56
|
-
lambda { subject + Exchange::
|
64
|
+
lambda { subject + Exchange::Money.new(30, :chf) }.should raise_error(Exchange::CurrencyMixError)
|
57
65
|
Exchange.configuration.allow_mixed_operations = true
|
58
66
|
end
|
59
67
|
it "should not raise when currencies get mixed and the configuration does not allow if the other currency is the same" do
|
60
68
|
Exchange.configuration.allow_mixed_operations = false
|
61
69
|
mock_api("http://openexchangerates.org/api/latest.json?app_id=", fixture('api_responses/example_json_api.json'), 2)
|
62
|
-
lambda { subject + Exchange::
|
70
|
+
lambda { subject + Exchange::Money.new(30, :usd) }.should_not raise_error
|
63
71
|
Exchange.configuration.allow_mixed_operations = true
|
64
72
|
end
|
65
73
|
context "modifying the base value" do
|
@@ -79,7 +87,7 @@ describe "Exchange::Currency" do
|
|
79
87
|
end
|
80
88
|
it "should be able to add another currency value" do
|
81
89
|
mock_api("http://openexchangerates.org/api/latest.json?app_id=", fixture('api_responses/example_json_api.json'), 2)
|
82
|
-
added = (@instantiated += Exchange::
|
90
|
+
added = (@instantiated += Exchange::Money.new(30, :chf))
|
83
91
|
added.value.round(2).should == 72.87
|
84
92
|
added.currency.should == :usd
|
85
93
|
@instantiated.value.round(2).should == 72.87
|
@@ -87,13 +95,13 @@ describe "Exchange::Currency" do
|
|
87
95
|
end
|
88
96
|
it "should raise when currencies get mixed and the configuration does not allow it" do
|
89
97
|
Exchange.configuration.allow_mixed_operations = false
|
90
|
-
lambda { @instantiated += Exchange::
|
98
|
+
lambda { @instantiated += Exchange::Money.new(30, :chf) }.should raise_error(Exchange::CurrencyMixError)
|
91
99
|
Exchange.configuration.allow_mixed_operations = true
|
92
100
|
end
|
93
101
|
it "should not raise when currencies get mixed and the configuration does not allow if the other currency is the same" do
|
94
102
|
Exchange.configuration.allow_mixed_operations = false
|
95
103
|
mock_api("http://openexchangerates.org/api/latest.json?app_id=", fixture('api_responses/example_json_api.json'), 2)
|
96
|
-
lambda { @instantiated += Exchange::
|
104
|
+
lambda { @instantiated += Exchange::Money.new(30, :usd) }.should_not raise_error
|
97
105
|
Exchange.configuration.allow_mixed_operations = true
|
98
106
|
end
|
99
107
|
end
|
@@ -112,18 +120,18 @@ describe "Exchange::Currency" do
|
|
112
120
|
it "should be able to subtract another currency value" do
|
113
121
|
mock_api("http://openexchangerates.org/api/latest.json?app_id=", fixture('api_responses/example_json_api.json'), 2)
|
114
122
|
Exchange.configuration.allow_mixed_operations = true
|
115
|
-
(subject - Exchange::
|
116
|
-
(subject - Exchange::
|
123
|
+
(subject - Exchange::Money.new(10, :chf)).value.round(2).should == 29.04
|
124
|
+
(subject - Exchange::Money.new(23.3, :eur)).currency.should == :usd
|
117
125
|
end
|
118
126
|
it "should raise when currencies get mixed and the configuration does not allow it" do
|
119
127
|
Exchange.configuration.allow_mixed_operations = false
|
120
|
-
lambda { subject - Exchange::
|
128
|
+
lambda { subject - Exchange::Money.new(30, :chf) }.should raise_error(Exchange::CurrencyMixError)
|
121
129
|
Exchange.configuration.allow_mixed_operations = true
|
122
130
|
end
|
123
131
|
it "should not raise when currencies get mixed and the configuration does not allow if the other currency is the same" do
|
124
132
|
Exchange.configuration.allow_mixed_operations = false
|
125
133
|
mock_api("http://openexchangerates.org/api/latest.json?app_id=", fixture('api_responses/example_json_api.json'), 2)
|
126
|
-
lambda { subject - Exchange::
|
134
|
+
lambda { subject - Exchange::Money.new(30, :usd) }.should_not raise_error
|
127
135
|
Exchange.configuration.allow_mixed_operations = true
|
128
136
|
end
|
129
137
|
context "modifying the base value" do
|
@@ -144,7 +152,7 @@ describe "Exchange::Currency" do
|
|
144
152
|
it "should be able to subtract another currency value" do
|
145
153
|
mock_api("http://openexchangerates.org/api/latest.json?app_id=", fixture('api_responses/example_json_api.json'), 2)
|
146
154
|
Exchange.configuration.allow_mixed_operations = true
|
147
|
-
added = (@instantiated -= Exchange::
|
155
|
+
added = (@instantiated -= Exchange::Money.new(10, :chf))
|
148
156
|
added.value.round(2).should == 29.04
|
149
157
|
added.currency.should == :usd
|
150
158
|
@instantiated.value.round(2).should == 29.04
|
@@ -152,13 +160,13 @@ describe "Exchange::Currency" do
|
|
152
160
|
end
|
153
161
|
it "should raise when currencies get mixed and the configuration does not allow it" do
|
154
162
|
Exchange.configuration.allow_mixed_operations = false
|
155
|
-
lambda { @instantiated -= Exchange::
|
163
|
+
lambda { @instantiated -= Exchange::Money.new(30, :chf) }.should raise_error(Exchange::CurrencyMixError)
|
156
164
|
Exchange.configuration.allow_mixed_operations = true
|
157
165
|
end
|
158
166
|
it "should not raise when currencies get mixed and the configuration does not allow if the other currency is the same" do
|
159
167
|
Exchange.configuration.allow_mixed_operations = false
|
160
168
|
mock_api("http://openexchangerates.org/api/latest.json?app_id=", fixture('api_responses/example_json_api.json'), 2)
|
161
|
-
lambda { @instantiated -= Exchange::
|
169
|
+
lambda { @instantiated -= Exchange::Money.new(30, :usd) }.should_not raise_error
|
162
170
|
Exchange.configuration.allow_mixed_operations = true
|
163
171
|
end
|
164
172
|
end
|
@@ -167,28 +175,33 @@ describe "Exchange::Currency" do
|
|
167
175
|
it "should be able to multiply by an integer" do
|
168
176
|
(subject * 40).value.should == 1600
|
169
177
|
end
|
170
|
-
|
171
|
-
|
178
|
+
context "with a float" do
|
179
|
+
subject { Exchange::Money.new(50, :usd) }
|
180
|
+
it "should be able to multiply a float" do
|
181
|
+
(subject * 40.5).value.should == 2025
|
182
|
+
end
|
183
|
+
it "should not fall for rounding errors" do
|
184
|
+
(subject * 0.29).round(0).value.should == 15
|
185
|
+
end
|
172
186
|
end
|
173
|
-
it "should not
|
174
|
-
(subject * 40)
|
175
|
-
subject.value.should == 40.0
|
187
|
+
it "should not fall for float rounding errors" do
|
188
|
+
(subject * 40.5)
|
176
189
|
end
|
177
190
|
it "should be able to multiply by another currency value" do
|
178
191
|
mock_api("http://openexchangerates.org/api/latest.json?app_id=", fixture('api_responses/example_json_api.json'), 2)
|
179
192
|
Exchange.configuration.allow_mixed_operations = true
|
180
|
-
(subject * Exchange::
|
181
|
-
(subject * Exchange::
|
193
|
+
(subject * Exchange::Money.new(10, :chf)).value.round(1).should == 438.3
|
194
|
+
(subject * Exchange::Money.new(23.3, :eur)).currency.should == :usd
|
182
195
|
end
|
183
196
|
it "should raise when currencies get mixed and the configuration does not allow it" do
|
184
197
|
Exchange.configuration.allow_mixed_operations = false
|
185
|
-
lambda { subject * Exchange::
|
198
|
+
lambda { subject * Exchange::Money.new(30, :chf) }.should raise_error(Exchange::CurrencyMixError)
|
186
199
|
Exchange.configuration.allow_mixed_operations = true
|
187
200
|
end
|
188
201
|
it "should not raise when currencies get mixed and the configuration does not allow if the other currency is the same" do
|
189
202
|
Exchange.configuration.allow_mixed_operations = false
|
190
203
|
mock_api("http://openexchangerates.org/api/latest.json?app_id=", fixture('api_responses/example_json_api.json'), 2)
|
191
|
-
lambda { subject * Exchange::
|
204
|
+
lambda { subject * Exchange::Money.new(30, :usd) }.should_not raise_error
|
192
205
|
Exchange.configuration.allow_mixed_operations = true
|
193
206
|
end
|
194
207
|
context "modifying the base value" do
|
@@ -209,7 +222,7 @@ describe "Exchange::Currency" do
|
|
209
222
|
it "should be able to multiply by another currency value" do
|
210
223
|
mock_api("http://openexchangerates.org/api/latest.json?app_id=", fixture('api_responses/example_json_api.json'), 2)
|
211
224
|
Exchange.configuration.allow_mixed_operations = true
|
212
|
-
added = (@instantiated *= Exchange::
|
225
|
+
added = (@instantiated *= Exchange::Money.new(9, :chf))
|
213
226
|
added.value.round(1).should == 394.50
|
214
227
|
added.currency.should == :usd
|
215
228
|
@instantiated.value.round(1).should == 394.50
|
@@ -217,13 +230,13 @@ describe "Exchange::Currency" do
|
|
217
230
|
end
|
218
231
|
it "should raise when currencies get mixed and the configuration does not allow it" do
|
219
232
|
Exchange.configuration.allow_mixed_operations = false
|
220
|
-
lambda { @instantiated *= Exchange::
|
233
|
+
lambda { @instantiated *= Exchange::Money.new(30, :chf) }.should raise_error(Exchange::CurrencyMixError)
|
221
234
|
Exchange.configuration.allow_mixed_operations = true
|
222
235
|
end
|
223
236
|
it "should not raise when currencies get mixed and the configuration does not allow if the other currency is the same" do
|
224
237
|
Exchange.configuration.allow_mixed_operations = false
|
225
238
|
mock_api("http://openexchangerates.org/api/latest.json?app_id=", fixture('api_responses/example_json_api.json'), 2)
|
226
|
-
lambda { @instantiated *= Exchange::
|
239
|
+
lambda { @instantiated *= Exchange::Money.new(30, :usd) }.should_not raise_error
|
227
240
|
Exchange.configuration.allow_mixed_operations = true
|
228
241
|
end
|
229
242
|
end
|
@@ -232,9 +245,16 @@ describe "Exchange::Currency" do
|
|
232
245
|
it "should be able to divide by an integer" do
|
233
246
|
(subject / 40).value.should == 1
|
234
247
|
end
|
235
|
-
|
236
|
-
|
248
|
+
context "with a float" do
|
249
|
+
subject { Exchange::Money.new(1829.82, :omr) }
|
250
|
+
it "should be able to divide by a float" do
|
251
|
+
(subject / 40.5).value.round(4).should == 45.1807
|
252
|
+
end
|
253
|
+
it "should not fall for floating point errors" do
|
254
|
+
(subject / 12.0).round(2).value.should == 152.49
|
255
|
+
end
|
237
256
|
end
|
257
|
+
|
238
258
|
it "should not modify the base value" do
|
239
259
|
(subject / 40).value.should == 1
|
240
260
|
subject.value.should == 40.0
|
@@ -247,18 +267,18 @@ describe "Exchange::Currency" do
|
|
247
267
|
it "should be able to divide by another currency value" do
|
248
268
|
mock_api("http://openexchangerates.org/api/latest.json?app_id=", fixture('api_responses/example_json_api.json'), 2)
|
249
269
|
Exchange.configuration.allow_mixed_operations = true
|
250
|
-
(subject / Exchange::
|
251
|
-
(subject / Exchange::
|
270
|
+
(subject / Exchange::Money.new(10, :chf)).value.round(2).should == BigDecimal.new("3.65")
|
271
|
+
(subject / Exchange::Money.new(23.3, :eur)).currency.should == :usd
|
252
272
|
end
|
253
273
|
it "should raise when currencies get mixed and the configuration does not allow it" do
|
254
274
|
Exchange.configuration.allow_mixed_operations = false
|
255
|
-
lambda { subject / Exchange::
|
275
|
+
lambda { subject / Exchange::Money.new(30, :chf) }.should raise_error(Exchange::CurrencyMixError)
|
256
276
|
Exchange.configuration.allow_mixed_operations = true
|
257
277
|
end
|
258
278
|
it "should not raise when currencies get mixed and the configuration does not allow if the other currency is the same" do
|
259
279
|
Exchange.configuration.allow_mixed_operations = false
|
260
280
|
mock_api("http://openexchangerates.org/api/latest.json?app_id=", fixture('api_responses/example_json_api.json'), 2)
|
261
|
-
lambda { subject / Exchange::
|
281
|
+
lambda { subject / Exchange::Money.new(30, :usd) }.should_not raise_error
|
262
282
|
Exchange.configuration.allow_mixed_operations = true
|
263
283
|
end
|
264
284
|
context "modifying the base value" do
|
@@ -279,7 +299,7 @@ describe "Exchange::Currency" do
|
|
279
299
|
it "should be able to divide by another currency value" do
|
280
300
|
mock_api("http://openexchangerates.org/api/latest.json?app_id=", fixture('api_responses/example_json_api.json'), 2)
|
281
301
|
Exchange.configuration.allow_mixed_operations = true
|
282
|
-
added = (@instantiated /= Exchange::
|
302
|
+
added = (@instantiated /= Exchange::Money.new(10, :chf))
|
283
303
|
added.value.round(2).should == 3.65
|
284
304
|
added.currency.should == :usd
|
285
305
|
@instantiated.value.round(2).should == 3.65
|
@@ -287,25 +307,25 @@ describe "Exchange::Currency" do
|
|
287
307
|
end
|
288
308
|
it "should raise when currencies get mixed and the configuration does not allow it" do
|
289
309
|
Exchange.configuration.allow_mixed_operations = false
|
290
|
-
lambda { @instantiated /= Exchange::
|
310
|
+
lambda { @instantiated /= Exchange::Money.new(30, :chf) }.should raise_error(Exchange::CurrencyMixError)
|
291
311
|
Exchange.configuration.allow_mixed_operations = true
|
292
312
|
end
|
293
313
|
it "should not raise when currencies get mixed and the configuration does not allow if the other currency is the same" do
|
294
314
|
Exchange.configuration.allow_mixed_operations = false
|
295
315
|
mock_api("http://openexchangerates.org/api/latest.json?app_id=", fixture('api_responses/example_json_api.json'), 2)
|
296
|
-
lambda { @instantiated /= Exchange::
|
316
|
+
lambda { @instantiated /= Exchange::Money.new(30, :usd) }.should_not raise_error
|
297
317
|
Exchange.configuration.allow_mixed_operations = true
|
298
318
|
end
|
299
319
|
end
|
300
320
|
end
|
301
321
|
describe "comparison" do
|
302
|
-
subject { Exchange::
|
303
|
-
let(:comp1) { Exchange::
|
304
|
-
let(:comp2) { Exchange::
|
305
|
-
let(:comp3) { Exchange::
|
306
|
-
let(:comp4) { Exchange::
|
307
|
-
let(:comp5) { Exchange::
|
308
|
-
let(:comp6) { Exchange::
|
322
|
+
subject { Exchange::Money.new(40.123, :usd) }
|
323
|
+
let(:comp1) { Exchange::Money.new(40.123, :usd) }
|
324
|
+
let(:comp2) { Exchange::Money.new(40, :usd) }
|
325
|
+
let(:comp3) { Exchange::Money.new(50, :eur) }
|
326
|
+
let(:comp4) { Exchange::Money.new(45, :eur) }
|
327
|
+
let(:comp5) { Exchange::Money.new(50, :eur).to_usd }
|
328
|
+
let(:comp6) { Exchange::Money.new(66.1, :usd, :at => Time.gm(2011,1,1)) }
|
309
329
|
before(:each) do
|
310
330
|
mock_api("http://openexchangerates.org/api/latest.json?app_id=", fixture('api_responses/example_json_api.json'), 2)
|
311
331
|
end
|
@@ -331,11 +351,11 @@ describe "Exchange::Currency" do
|
|
331
351
|
end
|
332
352
|
end
|
333
353
|
describe "sorting" do
|
334
|
-
subject { Exchange::
|
335
|
-
let(:comp1) { Exchange::
|
336
|
-
let(:comp2) { Exchange::
|
337
|
-
let(:comp3) { Exchange::
|
338
|
-
let(:comp4) { Exchange::
|
354
|
+
subject { Exchange::Money.new(40.123, :usd) }
|
355
|
+
let(:comp1) { Exchange::Money.new(40.123, :usd) }
|
356
|
+
let(:comp2) { Exchange::Money.new(40, :usd) }
|
357
|
+
let(:comp3) { Exchange::Money.new(50, :eur) }
|
358
|
+
let(:comp4) { Exchange::Money.new(45, :eur) }
|
339
359
|
before(:each) do
|
340
360
|
mock_api("http://openexchangerates.org/api/latest.json?app_id=", fixture('api_responses/example_json_api.json'), 6)
|
341
361
|
end
|
@@ -344,12 +364,12 @@ describe "Exchange::Currency" do
|
|
344
364
|
end
|
345
365
|
end
|
346
366
|
describe "round" do
|
347
|
-
subject { Exchange::
|
367
|
+
subject { Exchange::Money.new(40.123, :usd) }
|
348
368
|
context "without arguments" do
|
349
369
|
it "should apply it to its number in the iso certified format" do
|
350
370
|
subject.round.value.should == 40.12
|
351
371
|
subject.round.currency.should == :usd
|
352
|
-
subject.round.should be_kind_of Exchange::
|
372
|
+
subject.round.should be_kind_of Exchange::Money
|
353
373
|
end
|
354
374
|
it "should not modify the base value" do
|
355
375
|
subject.round.value.should == 40.12
|
@@ -360,22 +380,22 @@ describe "Exchange::Currency" do
|
|
360
380
|
it "should apply it to its number" do
|
361
381
|
subject.round(0).value.should == 40
|
362
382
|
subject.round(0).currency.should == :usd
|
363
|
-
subject.round(0).should be_kind_of Exchange::
|
383
|
+
subject.round(0).should be_kind_of Exchange::Money
|
364
384
|
end
|
365
385
|
it "should allow to round to whatever number of decimals" do
|
366
386
|
subject.round(2).value.should == 40.12
|
367
387
|
subject.round(2).currency.should == :usd
|
368
|
-
subject.round(2).should be_kind_of Exchange::
|
388
|
+
subject.round(2).should be_kind_of Exchange::Money
|
369
389
|
end
|
370
390
|
end
|
371
391
|
end
|
372
392
|
describe "ceil" do
|
373
|
-
subject { Exchange::
|
393
|
+
subject { Exchange::Money.new(40.1236, :omr) }
|
374
394
|
context "without arguments" do
|
375
395
|
it "should apply it to its number in the iso certified format" do
|
376
396
|
subject.ceil.value.should == 40.124
|
377
397
|
subject.ceil.currency.should == :omr
|
378
|
-
subject.ceil.should be_kind_of Exchange::
|
398
|
+
subject.ceil.should be_kind_of Exchange::Money
|
379
399
|
end
|
380
400
|
it "should not modify the base value" do
|
381
401
|
subject.ceil.value.should == 40.124
|
@@ -386,22 +406,22 @@ describe "Exchange::Currency" do
|
|
386
406
|
it "should apply it to its number" do
|
387
407
|
subject.ceil(0).value.should == 41
|
388
408
|
subject.ceil(0).currency.should == :omr
|
389
|
-
subject.ceil(0).should be_kind_of Exchange::
|
409
|
+
subject.ceil(0).should be_kind_of Exchange::Money
|
390
410
|
end
|
391
411
|
it "should allow to round to whatever number of decimals" do
|
392
412
|
subject.ceil(2).value.should == 40.13
|
393
413
|
subject.ceil(2).currency.should == :omr
|
394
|
-
subject.ceil(2).should be_kind_of Exchange::
|
414
|
+
subject.ceil(2).should be_kind_of Exchange::Money
|
395
415
|
end
|
396
416
|
end
|
397
417
|
end
|
398
418
|
describe "floor" do
|
399
|
-
subject { Exchange::
|
419
|
+
subject { Exchange::Money.new(40.723, :jpy) }
|
400
420
|
context "without arguments" do
|
401
421
|
it "should apply it to its number in the iso certified format" do
|
402
422
|
subject.floor.value.should == 40
|
403
423
|
subject.floor.currency.should == :jpy
|
404
|
-
subject.floor.should be_kind_of Exchange::
|
424
|
+
subject.floor.should be_kind_of Exchange::Money
|
405
425
|
end
|
406
426
|
it "should not modify the base value" do
|
407
427
|
subject.floor.value.should == 40
|
@@ -412,38 +432,38 @@ describe "Exchange::Currency" do
|
|
412
432
|
it "should apply it to its number" do
|
413
433
|
subject.floor(1).value.should == 40.7
|
414
434
|
subject.floor(1).currency.should == :jpy
|
415
|
-
subject.floor(1).should be_kind_of Exchange::
|
435
|
+
subject.floor(1).should be_kind_of Exchange::Money
|
416
436
|
end
|
417
437
|
it "should allow to round to whatever number of decimals" do
|
418
438
|
subject.floor(2).value.should == 40.72
|
419
439
|
subject.floor(2).currency.should == :jpy
|
420
|
-
subject.floor(2).should be_kind_of Exchange::
|
440
|
+
subject.floor(2).should be_kind_of Exchange::Money
|
421
441
|
end
|
422
442
|
end
|
423
443
|
end
|
424
444
|
end
|
425
445
|
describe "to_s" do
|
426
446
|
it "should render the currency according to ISO 4217 Definitions" do
|
427
|
-
Exchange::
|
428
|
-
Exchange::
|
429
|
-
Exchange::
|
430
|
-
Exchange::
|
431
|
-
Exchange::
|
432
|
-
Exchange::
|
447
|
+
Exchange::Money.new(23.232524, :tnd).to_s.should == "TND 23.233"
|
448
|
+
Exchange::Money.new(23.23252423, :sar).to_s.should == "SAR 23.23"
|
449
|
+
Exchange::Money.new(23.23252423, :clp).to_s.should == "CLP 23"
|
450
|
+
Exchange::Money.new(23.2, :tnd).to_s.should == "TND 23.200"
|
451
|
+
Exchange::Money.new(23.4, :sar).to_s.should == "SAR 23.40"
|
452
|
+
Exchange::Money.new(23.0, :clp).to_s.should == "CLP 23"
|
433
453
|
end
|
434
454
|
it "should render only the currency amount if the argument amount is passed" do
|
435
|
-
Exchange::
|
436
|
-
Exchange::
|
437
|
-
Exchange::
|
438
|
-
Exchange::
|
439
|
-
Exchange::
|
440
|
-
Exchange::
|
455
|
+
Exchange::Money.new(23.232524, :tnd).to_s(:amount).should == "23.233"
|
456
|
+
Exchange::Money.new(23.23252423, :sar).to_s(:amount).should == "23.23"
|
457
|
+
Exchange::Money.new(23.23252423, :clp).to_s(:amount).should == "23"
|
458
|
+
Exchange::Money.new(23.2, :tnd).to_s(:amount).should == "23.200"
|
459
|
+
Exchange::Money.new(23.4, :sar).to_s(:amount).should == "23.40"
|
460
|
+
Exchange::Money.new(23.0, :clp).to_s(:amount).should == "23"
|
441
461
|
end
|
442
462
|
end
|
443
463
|
describe "methods via method missing" do
|
444
464
|
it "should be able to convert via to_currency to other currencies" do
|
445
465
|
mock_api("http://openexchangerates.org/api/latest.json?app_id=", fixture('api_responses/example_json_api.json'), 6)
|
446
|
-
{
|
466
|
+
{:chf => 36.5, :usd => 40.0, :dkk => 225.12, :sek => 269.85, :nok => 232.06, :rub => 1205.24}.each do |currency, value|
|
447
467
|
c = subject.send(:"to_#{currency}")
|
448
468
|
c.value.round(2).should == value
|
449
469
|
c.currency.should == currency
|
@@ -451,7 +471,7 @@ describe "Exchange::Currency" do
|
|
451
471
|
end
|
452
472
|
it "should be able to convert via to_currency to other currencies and use historic data" do
|
453
473
|
mock_api("http://openexchangerates.org/api/historical/2011-10-09.json?app_id=", fixture('api_responses/example_json_api.json'), 6)
|
454
|
-
{
|
474
|
+
{:chf => 36.5, :usd => 40.0, :dkk => 225.12, :sek => 269.85, :nok => 232.06, :rub => 1205.24}.each do |currency, value|
|
455
475
|
c = subject.send(:"to_#{currency}", :at => Time.gm(2011,10,9))
|
456
476
|
c.value.round(2).should == value
|
457
477
|
c.currency.should == currency
|
@@ -0,0 +1,86 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "Exchange::Typecasting" do
|
4
|
+
|
5
|
+
class Manager
|
6
|
+
|
7
|
+
attr_accessor :currency
|
8
|
+
|
9
|
+
def initialize *args
|
10
|
+
self.currency = :eur
|
11
|
+
|
12
|
+
super
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
16
|
+
|
17
|
+
class MyClass
|
18
|
+
extend Exchange::Typecasting
|
19
|
+
|
20
|
+
attr_accessor :price, :manager
|
21
|
+
|
22
|
+
def initialize *args
|
23
|
+
self.manager = Manager.new
|
24
|
+
|
25
|
+
super
|
26
|
+
end
|
27
|
+
|
28
|
+
def created_at
|
29
|
+
Time.gm(2012,8,8)
|
30
|
+
end
|
31
|
+
|
32
|
+
money :price, :at => :created_at, :currency => lambda { |s| s.manager.currency }
|
33
|
+
|
34
|
+
end
|
35
|
+
|
36
|
+
describe "get" do
|
37
|
+
subject { MyClass.new }
|
38
|
+
before(:each) do
|
39
|
+
subject.price = 0.77
|
40
|
+
end
|
41
|
+
it "should instantiate the attribute as a currency" do
|
42
|
+
subject.price.should be_instance_of(Exchange::Money)
|
43
|
+
end
|
44
|
+
it "should instantiate the currency with the right currency" do
|
45
|
+
subject.price.currency.should == :eur
|
46
|
+
end
|
47
|
+
it "should instantiate with the right value" do
|
48
|
+
subject.price.value.should == 0.77
|
49
|
+
end
|
50
|
+
it "should instantiate the currency with the right time" do
|
51
|
+
subject.price.time.should == Time.gm(2012,8,8)
|
52
|
+
end
|
53
|
+
context "when changing the currency value" do
|
54
|
+
before(:each) do
|
55
|
+
subject.manager.currency = :usd
|
56
|
+
end
|
57
|
+
it "should instantiate with the new currency" do
|
58
|
+
subject.price.currency.should == :usd
|
59
|
+
end
|
60
|
+
it "should leave the value unchanged" do
|
61
|
+
subject.price.value.should == 0.77
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
describe "set" do
|
67
|
+
subject { MyClass.new }
|
68
|
+
before(:each) do
|
69
|
+
subject.price = 0.77
|
70
|
+
end
|
71
|
+
it "should set the value if the given value is numeric" do
|
72
|
+
subject.price = 0.83
|
73
|
+
subject.price.should == 0.83.eur
|
74
|
+
end
|
75
|
+
it "should not convert the value if the given value is in the same currency" do
|
76
|
+
subject.price = 0.83.eur
|
77
|
+
subject.price.should == 0.83.eur
|
78
|
+
end
|
79
|
+
it "should convert the value if the given value is in another currency" do
|
80
|
+
mock_api("http://api.finance.xaviermedia.com/api/#{Time.now.strftime("%Y/%m/%d")}.xml", fixture('api_responses/example_xml_api.xml'))
|
81
|
+
subject.price = 0.83.usd
|
82
|
+
subject.price.should == 0.62.eur
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
end
|