acvwilson-currency 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (57) hide show
  1. data/COPYING.txt +339 -0
  2. data/ChangeLog +8 -0
  3. data/LICENSE.txt +65 -0
  4. data/Manifest.txt +58 -0
  5. data/README.txt +51 -0
  6. data/Releases.txt +155 -0
  7. data/TODO.txt +9 -0
  8. data/currency.gemspec +18 -0
  9. data/examples/ex1.rb +13 -0
  10. data/examples/xe1.rb +20 -0
  11. data/lib/currency.rb +143 -0
  12. data/lib/currency/active_record.rb +265 -0
  13. data/lib/currency/config.rb +91 -0
  14. data/lib/currency/core_extensions.rb +83 -0
  15. data/lib/currency/currency.rb +175 -0
  16. data/lib/currency/currency/factory.rb +121 -0
  17. data/lib/currency/currency_version.rb +6 -0
  18. data/lib/currency/exception.rb +119 -0
  19. data/lib/currency/exchange.rb +48 -0
  20. data/lib/currency/exchange/rate.rb +214 -0
  21. data/lib/currency/exchange/rate/deriver.rb +157 -0
  22. data/lib/currency/exchange/rate/source.rb +89 -0
  23. data/lib/currency/exchange/rate/source/base.rb +166 -0
  24. data/lib/currency/exchange/rate/source/failover.rb +63 -0
  25. data/lib/currency/exchange/rate/source/federal_reserve.rb +160 -0
  26. data/lib/currency/exchange/rate/source/historical.rb +79 -0
  27. data/lib/currency/exchange/rate/source/historical/rate.rb +184 -0
  28. data/lib/currency/exchange/rate/source/historical/rate_loader.rb +186 -0
  29. data/lib/currency/exchange/rate/source/historical/writer.rb +220 -0
  30. data/lib/currency/exchange/rate/source/new_york_fed.rb +127 -0
  31. data/lib/currency/exchange/rate/source/provider.rb +120 -0
  32. data/lib/currency/exchange/rate/source/test.rb +50 -0
  33. data/lib/currency/exchange/rate/source/the_financials.rb +191 -0
  34. data/lib/currency/exchange/rate/source/timed_cache.rb +198 -0
  35. data/lib/currency/exchange/rate/source/xe.rb +165 -0
  36. data/lib/currency/exchange/time_quantitizer.rb +111 -0
  37. data/lib/currency/formatter.rb +310 -0
  38. data/lib/currency/macro.rb +321 -0
  39. data/lib/currency/money.rb +298 -0
  40. data/lib/currency/money_helper.rb +13 -0
  41. data/lib/currency/parser.rb +193 -0
  42. data/spec/ar_column_spec.rb +76 -0
  43. data/spec/ar_core_spec.rb +68 -0
  44. data/spec/ar_simple_spec.rb +23 -0
  45. data/spec/config_spec.rb +29 -0
  46. data/spec/federal_reserve_spec.rb +75 -0
  47. data/spec/formatter_spec.rb +72 -0
  48. data/spec/historical_writer_spec.rb +187 -0
  49. data/spec/macro_spec.rb +109 -0
  50. data/spec/money_spec.rb +355 -0
  51. data/spec/new_york_fed_spec.rb +73 -0
  52. data/spec/parser_spec.rb +105 -0
  53. data/spec/spec_helper.rb +25 -0
  54. data/spec/time_quantitizer_spec.rb +115 -0
  55. data/spec/timed_cache_spec.rb +95 -0
  56. data/spec/xe_spec.rb +50 -0
  57. metadata +117 -0
@@ -0,0 +1,109 @@
1
+ # Copyright (C) 2006-2007 Kurt Stephens <ruby-currency(at)umleta.com>
2
+ # See LICENSE.txt for details.
3
+
4
+ require 'test/test_base'
5
+ require 'currency'
6
+ require 'currency/macro'
7
+
8
+ module Currency
9
+
10
+ class MacroTest < TestBase
11
+ class Record
12
+ include ::Currency::Macro
13
+
14
+ attr_accessor :date
15
+ attr_accessor :gross
16
+ attr_accessor :tax
17
+ attr_accessor :net
18
+ attr_accessor :currency
19
+
20
+ attr_money :gross_money, :value => :gross, :time => :date, :currency => :currency
21
+ attr_money :tax_money, :value => :tax, :time => :date, :currency => :currency
22
+ attr_money :net_money, :value => :net, :time => :date, :currency => :currency
23
+
24
+ def initialize
25
+ self.date = Time.now
26
+ self.currency = :USD
27
+ end
28
+
29
+ def compute_net
30
+ self.net = self.gross - self.tax
31
+ end
32
+
33
+ def compute_net_money
34
+ self.net_money = self.gross_money - self.tax_money
35
+ end
36
+
37
+ end
38
+
39
+ before do
40
+ super
41
+ end
42
+
43
+ ############################################
44
+ # Tests
45
+ #
46
+
47
+ it "read money" do
48
+ assert_kind_of Record, r = Record.new
49
+ r.gross = 10.00.should.not == nil
50
+ r.gross.should == r.gross_money.to_f
51
+ r.currency.should == r.gross_money.currency.code
52
+ r.date.should == r.gross_money.time
53
+
54
+ r
55
+ end
56
+
57
+
58
+ it "write money rep" do
59
+ assert_kind_of Record, r = Record.new
60
+ r.gross_money = 10.00.should.not == nil
61
+ r.gross.should == r.gross_money.to_f
62
+ r.currency.should == r.gross_money.currency.code
63
+ r.date.should == r.gross_money.time
64
+
65
+ r
66
+ end
67
+
68
+
69
+ it "money cache" do
70
+ r = test_read_money
71
+
72
+ r_gross = r.gross.should.not == nil
73
+ r_gross.object_id.should == r.gross.object_id
74
+
75
+ # Cache flush
76
+ r.gross = 12.00.should.not == nil
77
+ r.gross.should == r.gross_money.to_f
78
+ r_gross.object_id != r.gross.object_id.should.not == nil
79
+ end
80
+
81
+
82
+ it "currency" do
83
+ r = test_read_money
84
+
85
+ r.gross_money.currency.should.not == nil
86
+ r.currency.should == r.gross_money.currency.code
87
+
88
+ end
89
+
90
+
91
+ it "compute" do
92
+ assert_kind_of Record, r = Record.new
93
+ r.gross = 10.00.should.not == nil
94
+ r.tax = 1.50.should.not == nil
95
+ r.compute_net
96
+
97
+ r.net.should == 8.50
98
+ r.net_money.to_f.should == r.net
99
+
100
+ r.compute_net_money
101
+
102
+ r.net.should == 8.50
103
+ r.net_money.to_f.should == r.net
104
+ end
105
+
106
+ end # class
107
+
108
+ end # module
109
+
@@ -0,0 +1,355 @@
1
+ require File.dirname(__FILE__) + '/spec_helper'
2
+
3
+
4
+ describe Currency::Money do
5
+
6
+ it "create" do
7
+ m = Currency::Money.new(1.99)
8
+ m.should be_kind_of(Currency::Money)
9
+ Currency::Currency.default.should == m.currency
10
+ :USD.should == m.currency.code
11
+ end
12
+
13
+ describe "object money method" do
14
+ it "works with a float" do
15
+ m = 1.99.money(:USD)
16
+ m.should be_kind_of(Currency::Money)
17
+ :USD.should == m.currency.code
18
+ m.rep.should == 1990000
19
+ end
20
+
21
+ it "works with a FixNum" do
22
+ m = 199.money(:CAD)
23
+ m.should be_kind_of(Currency::Money)
24
+ :CAD.should == m.currency.code
25
+ m.rep.should == 199000000
26
+ end
27
+
28
+ it "works with a string" do
29
+ m = "13.98".money(:CAD)
30
+ m.should be_kind_of(Currency::Money)
31
+ :CAD.should == m.currency.code
32
+ m.rep.should == 13980000
33
+ end
34
+
35
+ it "works with a string again" do
36
+ m = "45.99".money(:EUR)
37
+ m.should be_kind_of(Currency::Money)
38
+ :EUR.should == m.currency.code
39
+ m.rep.should == 45990000
40
+ end
41
+
42
+ it "creates money objects from strings" do
43
+ "12.0001".money(:USD).to_s.should == "$12.0001"
44
+ # "12.000108".money(:USD).to_s(:thousands => false, :decimals => 5).should == "$12.00011"
45
+ @money = Currency::Money.new_rep(1234567890000, :USD, nil)
46
+
47
+ Currency::Money.new("12.000108").to_s(:thousands => false, :decimals => 5).should == "$12.00011"
48
+ end
49
+ end
50
+
51
+ def zero_money
52
+ @zero_money ||= Currency::Money.new(0)
53
+ end
54
+
55
+ it "zero" do
56
+ zero_money.negative?.should_not == true
57
+ zero_money.zero?.should_not == nil
58
+ zero_money.positive?.should_not == true
59
+ end
60
+
61
+ def negative_money
62
+ @negative_money ||= Currency::Money.new(-1.00, :USD)
63
+ end
64
+
65
+ it "negative" do
66
+ negative_money.negative?.should_not == nil
67
+ negative_money.zero?.should_not == true
68
+ negative_money.positive?.should_not == true
69
+ end
70
+
71
+ def positive_money
72
+ @positive_money ||= Currency::Money.new(2.99, :USD)
73
+ end
74
+ it "positive" do
75
+ positive_money.negative?.should_not == true
76
+ positive_money.zero?.should_not == true
77
+ positive_money.positive?.should_not == nil
78
+ end
79
+
80
+ it "relational" do
81
+ n = negative_money
82
+ z = zero_money
83
+ p = positive_money
84
+
85
+ (n.should < p)
86
+ (n > p).should_not == true
87
+ (p < n).should_not == true
88
+ (p.should > n)
89
+ (p != n).should_not == nil
90
+
91
+ (z.should <= z)
92
+ (z.should >= z)
93
+
94
+ (z.should <= p)
95
+ (n.should <= z)
96
+ (z.should >= n)
97
+
98
+ n.should == n
99
+ p.should == p
100
+
101
+ z.should == zero_money
102
+ end
103
+
104
+ it "compare" do
105
+ n = negative_money
106
+ z = zero_money
107
+ p = positive_money
108
+
109
+ (n <=> p).should == -1
110
+ (p <=> n).should == 1
111
+ (p <=> z).should == 1
112
+
113
+ (n <=> n).should == 0
114
+ (z <=> z).should == 0
115
+ (p <=> p).should == 0
116
+ end
117
+
118
+ it "rep" do
119
+ m = Currency::Money.new(123, :USD)
120
+ m.should_not == nil
121
+ m.rep.should == 123000000
122
+
123
+ m = Currency::Money.new(123.45, :USD)
124
+ m.should_not == nil
125
+ m.rep.should == 123450000
126
+
127
+ m = Currency::Money.new("123.456", :USD)
128
+ m.should_not == nil
129
+ m.rep.should == 123456000
130
+ end
131
+
132
+ it "convert" do
133
+ m = Currency::Money.new("123.456", :USD)
134
+ m.should_not == nil
135
+ m.rep.should == 123456000
136
+
137
+ m.to_i.should == 123
138
+ m.to_f.should == 123.456
139
+ m.to_s.should == "$123.456000"
140
+ end
141
+
142
+ it "eql" do
143
+ usd1 = Currency::Money.new(123, :USD)
144
+ usd1.should_not == nil
145
+ usd2 = Currency::Money.new("123", :USD)
146
+ usd2.should_not == nil
147
+
148
+ usd1.currency.code.should == :USD
149
+ usd2.currency.code.should == :USD
150
+
151
+ usd2.rep.should == usd1.rep
152
+
153
+ usd1.should == usd2
154
+
155
+ end
156
+
157
+ it "not eql" do
158
+
159
+ usd1 = Currency::Money.new(123, :USD)
160
+ usd1.should_not == nil
161
+ usd2 = Currency::Money.new("123.01", :USD)
162
+ usd2.should_not == nil
163
+
164
+ usd1.currency.code.should == :USD
165
+ usd2.currency.code.should == :USD
166
+
167
+ usd2.rep.should_not == usd1.rep
168
+
169
+ (usd1 != usd2).should_not == nil
170
+
171
+ ################
172
+ # currency !=
173
+ # rep ==
174
+
175
+ usd = Currency::Money.new(123, :USD)
176
+ usd.should_not == nil
177
+ cad = Currency::Money.new(123, :CAD)
178
+ cad.should_not == nil
179
+
180
+ usd.currency.code.should == :USD
181
+ cad.currency.code.should == :CAD
182
+
183
+ cad.rep.should == usd.rep
184
+ (usd.currency != cad.currency).should_not == nil
185
+
186
+ (usd != cad).should_not == nil
187
+
188
+ end
189
+
190
+ describe "operations" do
191
+ before(:each) do
192
+ @usd = Currency::Money.new(123.45, :USD)
193
+ @cad = Currency::Money.new(123.45, :CAD)
194
+ end
195
+
196
+ it "should work" do
197
+ @usd.should_not == nil
198
+ @cad.should_not == nil
199
+ end
200
+
201
+ it "handle negative money" do
202
+ # - Currency::Money => Currency::Money
203
+ (- @usd).rep.should == -123450000
204
+ (- @usd).currency.code.should == :USD
205
+
206
+ (- @cad).rep.should == -123450000
207
+ (- @cad).currency.code.should == :CAD
208
+ end
209
+
210
+ it "should add monies of the same currency" do
211
+ m = (@usd + @usd)
212
+ m.should be_kind_of(Currency::Money)
213
+ m.rep.should == 246900000
214
+ m.currency.code.should == :USD
215
+ end
216
+
217
+ it "should add monies of different currencies and return USD" do
218
+ m = (@usd + @cad)
219
+ m.should be_kind_of(Currency::Money)
220
+ m.rep.should == 228890724
221
+ m.currency.code.should == :USD
222
+ end
223
+
224
+ it "should add monies of different currencies and return CAD" do
225
+ m = (@cad + @usd)
226
+ m.should be_kind_of(Currency::Money)
227
+ m.rep.should == 267985260
228
+ m.currency.code.should == :CAD
229
+ end
230
+
231
+ it "should subtract monies of the same currency" do
232
+ m = (@usd - @usd)
233
+ m.should be_kind_of(Currency::Money)
234
+ m.rep.should == 0
235
+ m.currency.code.should == :USD
236
+ end
237
+
238
+ it "should subtract monies of different currencies and return USD" do
239
+ m = (@usd - @cad)
240
+ m.should be_kind_of(Currency::Money)
241
+ m.rep.should == 18009276
242
+ m.currency.code.should == :USD
243
+ end
244
+
245
+ it "should subtract monies of different currencies and return CAD" do
246
+ m = (@cad - @usd)
247
+ m.should be_kind_of(Currency::Money)
248
+ m.rep.should == -21085260
249
+ m.currency.code.should == :CAD
250
+ end
251
+
252
+ it "should multiply by numerics and return money" do
253
+ m = (@usd * 0.5)
254
+ m.should be_kind_of(Currency::Money)
255
+ m.rep.should == 61725000
256
+ m.currency.code.should == :USD
257
+ end
258
+
259
+ it "should divide by numerics and return money" do
260
+ m = @usd / 3
261
+ m.should be_kind_of(Currency::Money)
262
+ m.rep.should == 41150000
263
+ m.currency.code.should == :USD
264
+ end
265
+
266
+ it "should divide by monies of the same currency and return numeric" do
267
+ m = @usd / Currency::Money.new("41.15", :USD)
268
+ m.should be_kind_of(Numeric)
269
+ m.should be_close(3.0, 1.0e-8)
270
+ end
271
+
272
+ it "should divide by monies of different currencies and return numeric" do
273
+ m = (@usd / @cad)
274
+ m.should be_kind_of(Numeric)
275
+ m.should be_close(Currency::Exchange::Rate::Source::Test.USD_CAD, 0.0001)
276
+ end
277
+ end
278
+
279
+ it "pivot conversions" do
280
+ # Using default get_rate
281
+ cad = Currency::Money.new(123.45, :CAD)
282
+ cad.should_not == nil
283
+ eur = cad.convert(:EUR)
284
+ eur.should_not == nil
285
+ m = (eur.to_f / cad.to_f)
286
+ m.should be_kind_of(Numeric)
287
+ m_expected = (1.0 / Currency::Exchange::Rate::Source::Test.USD_CAD) * Currency::Exchange::Rate::Source::Test.USD_EUR
288
+ m.should be_close(m_expected, 0.001)
289
+
290
+
291
+ gbp = Currency::Money.new(123.45, :GBP)
292
+ gbp.should_not == nil
293
+ eur = gbp.convert(:EUR)
294
+ eur.should_not == nil
295
+ m = (eur.to_f / gbp.to_f)
296
+ m.should be_kind_of(Numeric)
297
+ m_expected = (1.0 / Currency::Exchange::Rate::Source::Test.USD_GBP) * Currency::Exchange::Rate::Source::Test.USD_EUR
298
+ m.should be_close(m_expected, 0.001)
299
+ end
300
+
301
+
302
+ it "invalid currency code" do
303
+ lambda {Currency::Money.new(123, :asdf)}.should raise_error(Currency::Exception::InvalidCurrencyCode)
304
+ lambda {Currency::Money.new(123, 5)}.should raise_error(Currency::Exception::InvalidCurrencyCode)
305
+ end
306
+
307
+
308
+ it "time default" do
309
+ Currency::Money.default_time = nil
310
+
311
+ usd = Currency::Money.new(123.45, :USD)
312
+ usd.should_not == nil
313
+ usd.time.should == nil
314
+
315
+ Currency::Money.default_time = Time.now
316
+ usd = Currency::Money.new(123.45, :USD)
317
+ usd.should_not == nil
318
+ Currency::Money.default_time.should == usd.time
319
+ end
320
+
321
+
322
+ it "time now" do
323
+ Currency::Money.default_time = :now
324
+
325
+ usd = Currency::Money.new(123.45, :USD)
326
+ usd.should_not == nil
327
+ usd.time.should_not == nil
328
+
329
+ sleep 1
330
+
331
+ usd2 = Currency::Money.new(123.45, :USD)
332
+ usd2.should_not == nil
333
+ usd2.time.should_not == nil
334
+ (usd.time != usd2.time).should_not == nil
335
+
336
+ Currency::Money.default_time = nil
337
+ end
338
+
339
+
340
+ it "time fixed" do
341
+ Currency::Money.default_time = Time.new
342
+
343
+ usd = Currency::Money.new(123.45, :USD)
344
+ usd.should_not == nil
345
+ usd.time.should_not == nil
346
+
347
+ sleep 1
348
+
349
+ usd2 = Currency::Money.new(123.45, :USD)
350
+ usd2.should_not == nil
351
+ usd2.time.should_not == nil
352
+ usd.time.should == usd2.time
353
+ end
354
+ end
355
+