acvwilson-acvwilson-currency 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (58) 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 +48 -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 +50 -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 +300 -0
  38. data/lib/currency/macro.rb +321 -0
  39. data/lib/currency/money.rb +296 -0
  40. data/lib/currency/money_helper.rb +13 -0
  41. data/lib/currency/parser.rb +193 -0
  42. data/spec/ar_base_spec.rb +140 -0
  43. data/spec/ar_column_spec.rb +69 -0
  44. data/spec/ar_core_spec.rb +64 -0
  45. data/spec/ar_simple_spec.rb +31 -0
  46. data/spec/config_spec.rb +29 -0
  47. data/spec/federal_reserve_spec.rb +75 -0
  48. data/spec/formatter_spec.rb +72 -0
  49. data/spec/historical_writer_spec.rb +187 -0
  50. data/spec/macro_spec.rb +109 -0
  51. data/spec/money_spec.rb +347 -0
  52. data/spec/new_york_fed_spec.rb +73 -0
  53. data/spec/parser_spec.rb +105 -0
  54. data/spec/spec_helper.rb +25 -0
  55. data/spec/time_quantitizer_spec.rb +115 -0
  56. data/spec/timed_cache_spec.rb +95 -0
  57. data/spec/xe_spec.rb +50 -0
  58. metadata +117 -0
@@ -0,0 +1,187 @@
1
+ # Copyright (C) 2006-2007 Kurt Stephens <ruby-currency(at)umleta.com>
2
+ # See LICENSE.txt for details.
3
+
4
+ require 'test/ar_test_base'
5
+
6
+ require 'rubygems'
7
+ require 'active_record'
8
+ require 'active_record/migration'
9
+
10
+ require 'currency' # For :type => :money
11
+
12
+ require 'currency/exchange/rate/source/historical'
13
+ require 'currency/exchange/rate/source/historical/writer'
14
+ require 'currency/exchange/rate/source/xe'
15
+ require 'currency/exchange/rate/source/new_york_fed'
16
+
17
+
18
+ module Currency
19
+
20
+ class HistoricalWriterTest < ArTestBase
21
+
22
+ RATE_CLASS = Exchange::Rate::Source::Historical::Rate
23
+ TABLE_NAME = RATE_CLASS.table_name
24
+
25
+ class HistoricalRateMigration < AR_M
26
+ def self.up
27
+ RATE_CLASS.__create_table(self)
28
+ end
29
+
30
+ def self.down
31
+ drop_table TABLE_NAME.intern
32
+ end
33
+ end
34
+
35
+
36
+ def initialize(*args)
37
+ @currency_test_migration = HistoricalRateMigration
38
+ super
39
+
40
+ @src = Exchange::Rate::Source::Xe.new
41
+ @src2 = Exchange::Rate::Source::NewYorkFed.new
42
+ end
43
+
44
+
45
+ before do
46
+ super
47
+
48
+ end
49
+
50
+
51
+ it "writer" do
52
+ src = @src.should.not == nil
53
+ writer = Exchange::Rate::Source::Historical::Writer.new().should.not == nil
54
+ writer.time_quantitizer = :current
55
+ writer.required_currencies = [ :USD, :GBP, :EUR, :CAD ]
56
+ writer.base_currencies = [ :USD ]
57
+ writer.preferred_currencies = writer.required_currencies
58
+ writer.reciprocal_rates = true
59
+ writer.all_rates = true
60
+ writer.identity_rates = false
61
+
62
+ writer
63
+ end
64
+
65
+
66
+ def writer_src
67
+ writer = test_writer
68
+ writer.source = @src
69
+ rates = writer.write_rates
70
+ rates.should.not == nil
71
+ rates.size.should > 0
72
+ 12, rates.size.should.not == nil
73
+ assert_h_rates(rates, writer)
74
+ end
75
+
76
+
77
+ def writer_src2
78
+ writer = test_writer
79
+ writer.source = @src2
80
+ return unless writer.source.available?
81
+ rates = writer.write_rates
82
+ rates.should.not == nil
83
+ rates.size.should > 0
84
+ rates.size.should == 12
85
+ assert_h_rates(rates, writer)
86
+ end
87
+
88
+
89
+ def xxx_test_required_failure
90
+ writer = Exchange::Rate::Source::Historical::Writer.new().should.not == nil
91
+ src = @src.should.not == nil
92
+ writer.source = src
93
+ writer.required_currencies = [ :USD, :GBP, :EUR, :CAD, :ZZZ ]
94
+ writer.preferred_currencies = writer.required_currencies
95
+ assert_raises(::RuntimeError) { writer.selected_rates }
96
+ end
97
+
98
+
99
+ it "historical rates" do
100
+ # Make sure there are historical Rates avail for today.
101
+ writer_src
102
+ writer_src2
103
+
104
+ # Force Historical Rate Source.
105
+ source = Exchange::Rate::Source::Historical.new
106
+ deriver = Exchange::Rate::Deriver.new(:source => source)
107
+ Exchange::Rate::Source.default = deriver
108
+
109
+ rates = source.get_raw_rates.should.not == nil
110
+ rates.empty?.should.not == true
111
+ # $stderr.puts "historical rates = #{rates.inspect}"
112
+
113
+ rates = source.get_rates.should.not == nil
114
+ rates.empty?.should.not == true
115
+ # $stderr.puts "historical rates = #{rates.inspect}"
116
+
117
+ m_usd = ::Currency.Money('1234.56', :USD, :now).should.not == nil
118
+ # $stderr.puts "m_usd = #{m_usd.to_s(:code => true)}"
119
+ m_eur = m_usd.convert(:EUR).should.not == nil
120
+ # $stderr.puts "m_eur = #{m_eur.to_s(:code => true)}"
121
+
122
+ end
123
+
124
+
125
+ def assert_h_rates(rates, writer = nil)
126
+ hr0 = rates[0].should.not == nil
127
+ rates.each do | hr |
128
+ found_hr = nil
129
+ begin
130
+ found_hr = hr.find_matching_this(:first).should.not == nil
131
+ rescue Object => err
132
+ raise "#{hr.inspect}: #{err}:\n#{err.backtrace.inspect}"
133
+ end
134
+
135
+ hr0.should.not == nil
136
+
137
+ hr.date.should == hr0.date
138
+ hr.date_0.should == hr0.date_0
139
+ hr.date_1.should == hr0.date_1
140
+ hr.source.should == hr0.source
141
+
142
+ assert_equal_rate(hr, found_hr)
143
+ assert_rate_defaults(hr, writer)
144
+ end
145
+ end
146
+
147
+
148
+ def assert_equal_rate(hr0, hr)
149
+ hr.c1.to_s.should == hr0.c1.to_s
150
+ hr.c2.to_s.should == hr0.c2.to_s
151
+ hr.source.should == hr0.source
152
+ assert_equal_float hr0.rate, hr.rate
153
+ assert_equal_float hr0.rate_avg, hr.rate_avg
154
+ hr.rate_samples.should == hr0.rate_samples
155
+ assert_equal_float hr0.rate_lo, hr.rate_lo
156
+ assert_equal_float hr0.rate_hi, hr.rate_hi
157
+ assert_equal_float hr0.rate_date_0, hr.rate_date_0
158
+ assert_equal_float hr0.rate_date_1, hr.rate_date_1
159
+ hr.date.should == hr0.date
160
+ hr.date_0.should == hr0.date_0
161
+ hr.date_1.should == hr0.date_1
162
+ hr.derived.should == hr0.derived
163
+ end
164
+
165
+
166
+ def assert_rate_defaults(hr, writer)
167
+ hr.source if writer.should == writer.source.name
168
+ hr.rate_avg.should == hr.rate
169
+ 1.should == hr.rate_samples
170
+ hr.rate_lo.should == hr.rate
171
+ hr.rate_hi.should == hr.rate
172
+ hr.rate_date_0.should == hr.rate
173
+ hr.rate_date_1.should == hr.rate
174
+ end
175
+
176
+
177
+ def assert_equal_float(x1, x2, eps = 0.00001)
178
+ eps = (x1 * eps).abs
179
+ assert((x1 - eps) <= x2)
180
+ assert((x1 + eps) >= x2)
181
+ end
182
+
183
+
184
+ end
185
+
186
+ end # module
187
+
@@ -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,347 @@
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
+ end
42
+
43
+ def zero_money
44
+ @zero_money ||= Currency::Money.new(0)
45
+ end
46
+
47
+ it "zero" do
48
+ zero_money.negative?.should_not == true
49
+ zero_money.zero?.should_not == nil
50
+ zero_money.positive?.should_not == true
51
+ end
52
+
53
+ def negative_money
54
+ @negative_money ||= Currency::Money.new(-1.00, :USD)
55
+ end
56
+
57
+ it "negative" do
58
+ negative_money.negative?.should_not == nil
59
+ negative_money.zero?.should_not == true
60
+ negative_money.positive?.should_not == true
61
+ end
62
+
63
+ def positive_money
64
+ @positive_money ||= Currency::Money.new(2.99, :USD)
65
+ end
66
+ it "positive" do
67
+ positive_money.negative?.should_not == true
68
+ positive_money.zero?.should_not == true
69
+ positive_money.positive?.should_not == nil
70
+ end
71
+
72
+ it "relational" do
73
+ n = negative_money
74
+ z = zero_money
75
+ p = positive_money
76
+
77
+ (n.should < p)
78
+ (n > p).should_not == true
79
+ (p < n).should_not == true
80
+ (p.should > n)
81
+ (p != n).should_not == nil
82
+
83
+ (z.should <= z)
84
+ (z.should >= z)
85
+
86
+ (z.should <= p)
87
+ (n.should <= z)
88
+ (z.should >= n)
89
+
90
+ n.should == n
91
+ p.should == p
92
+
93
+ z.should == zero_money
94
+ end
95
+
96
+ it "compare" do
97
+ n = negative_money
98
+ z = zero_money
99
+ p = positive_money
100
+
101
+ (n <=> p).should == -1
102
+ (p <=> n).should == 1
103
+ (p <=> z).should == 1
104
+
105
+ (n <=> n).should == 0
106
+ (z <=> z).should == 0
107
+ (p <=> p).should == 0
108
+ end
109
+
110
+ it "rep" do
111
+ m = Currency::Money.new(123, :USD)
112
+ m.should_not == nil
113
+ m.rep.should == 123000000
114
+
115
+ m = Currency::Money.new(123.45, :USD)
116
+ m.should_not == nil
117
+ m.rep.should == 123450000
118
+
119
+ m = Currency::Money.new("123.456", :USD)
120
+ m.should_not == nil
121
+ m.rep.should == 123456000
122
+ end
123
+
124
+ it "convert" do
125
+ m = Currency::Money.new("123.456", :USD)
126
+ m.should_not == nil
127
+ m.rep.should == 123456000
128
+
129
+ m.to_i.should == 123
130
+ m.to_f.should == 123.456
131
+ m.to_s.should == "$123.456000"
132
+ end
133
+
134
+ it "eql" do
135
+ usd1 = Currency::Money.new(123, :USD)
136
+ usd1.should_not == nil
137
+ usd2 = Currency::Money.new("123", :USD)
138
+ usd2.should_not == nil
139
+
140
+ usd1.currency.code.should == :USD
141
+ usd2.currency.code.should == :USD
142
+
143
+ usd2.rep.should == usd1.rep
144
+
145
+ usd1.should == usd2
146
+
147
+ end
148
+
149
+ it "not eql" do
150
+
151
+ usd1 = Currency::Money.new(123, :USD)
152
+ usd1.should_not == nil
153
+ usd2 = Currency::Money.new("123.01", :USD)
154
+ usd2.should_not == nil
155
+
156
+ usd1.currency.code.should == :USD
157
+ usd2.currency.code.should == :USD
158
+
159
+ usd2.rep.should_not == usd1.rep
160
+
161
+ (usd1 != usd2).should_not == nil
162
+
163
+ ################
164
+ # currency !=
165
+ # rep ==
166
+
167
+ usd = Currency::Money.new(123, :USD)
168
+ usd.should_not == nil
169
+ cad = Currency::Money.new(123, :CAD)
170
+ cad.should_not == nil
171
+
172
+ usd.currency.code.should == :USD
173
+ cad.currency.code.should == :CAD
174
+
175
+ cad.rep.should == usd.rep
176
+ (usd.currency != cad.currency).should_not == nil
177
+
178
+ (usd != cad).should_not == nil
179
+
180
+ end
181
+
182
+ describe "operations" do
183
+ before(:each) do
184
+ @usd = Currency::Money.new(123.45, :USD)
185
+ @cad = Currency::Money.new(123.45, :CAD)
186
+ end
187
+
188
+ it "should work" do
189
+ @usd.should_not == nil
190
+ @cad.should_not == nil
191
+ end
192
+
193
+ it "handle negative money" do
194
+ # - Currency::Money => Currency::Money
195
+ (- @usd).rep.should == -123450000
196
+ (- @usd).currency.code.should == :USD
197
+
198
+ (- @cad).rep.should == -123450000
199
+ (- @cad).currency.code.should == :CAD
200
+ end
201
+
202
+ it "should add monies of the same currency" do
203
+ m = (@usd + @usd)
204
+ m.should be_kind_of(Currency::Money)
205
+ m.rep.should == 246900000
206
+ m.currency.code.should == :USD
207
+ end
208
+
209
+ it "should add monies of different currencies and return USD" do
210
+ m = (@usd + @cad)
211
+ m.should be_kind_of(Currency::Money)
212
+ m.rep.should == 228890724
213
+ m.currency.code.should == :USD
214
+ end
215
+
216
+ it "should add monies of different currencies and return CAD" do
217
+ m = (@cad + @usd)
218
+ m.should be_kind_of(Currency::Money)
219
+ m.rep.should == 267985260
220
+ m.currency.code.should == :CAD
221
+ end
222
+
223
+ it "should subtract monies of the same currency" do
224
+ m = (@usd - @usd)
225
+ m.should be_kind_of(Currency::Money)
226
+ m.rep.should == 0
227
+ m.currency.code.should == :USD
228
+ end
229
+
230
+ it "should subtract monies of different currencies and return USD" do
231
+ m = (@usd - @cad)
232
+ m.should be_kind_of(Currency::Money)
233
+ m.rep.should == 18009276
234
+ m.currency.code.should == :USD
235
+ end
236
+
237
+ it "should subtract monies of different currencies and return CAD" do
238
+ m = (@cad - @usd)
239
+ m.should be_kind_of(Currency::Money)
240
+ m.rep.should == -21085260
241
+ m.currency.code.should == :CAD
242
+ end
243
+
244
+ it "should multiply by numerics and return money" do
245
+ m = (@usd * 0.5)
246
+ m.should be_kind_of(Currency::Money)
247
+ m.rep.should == 61725000
248
+ m.currency.code.should == :USD
249
+ end
250
+
251
+ it "should divide by numerics and return money" do
252
+ m = @usd / 3
253
+ m.should be_kind_of(Currency::Money)
254
+ m.rep.should == 41150000
255
+ m.currency.code.should == :USD
256
+ end
257
+
258
+ it "should divide by monies of the same currency and return numeric" do
259
+ m = @usd / Currency::Money.new("41.15", :USD)
260
+ m.should be_kind_of(Numeric)
261
+ m.should be_close(3.0, 1.0e-8)
262
+ end
263
+
264
+ it "should divide by monies of different currencies and return numeric" do
265
+ m = (@usd / @cad)
266
+ m.should be_kind_of(Numeric)
267
+ m.should be_close(Currency::Exchange::Rate::Source::Test.USD_CAD, 0.0001)
268
+ end
269
+ end
270
+
271
+ it "pivot conversions" do
272
+ # Using default get_rate
273
+ cad = Currency::Money.new(123.45, :CAD)
274
+ cad.should_not == nil
275
+ eur = cad.convert(:EUR)
276
+ eur.should_not == nil
277
+ m = (eur.to_f / cad.to_f)
278
+ m.should be_kind_of(Numeric)
279
+ m_expected = (1.0 / Currency::Exchange::Rate::Source::Test.USD_CAD) * Currency::Exchange::Rate::Source::Test.USD_EUR
280
+ m.should be_close(m_expected, 0.001)
281
+
282
+
283
+ gbp = Currency::Money.new(123.45, :GBP)
284
+ gbp.should_not == nil
285
+ eur = gbp.convert(:EUR)
286
+ eur.should_not == nil
287
+ m = (eur.to_f / gbp.to_f)
288
+ m.should be_kind_of(Numeric)
289
+ m_expected = (1.0 / Currency::Exchange::Rate::Source::Test.USD_GBP) * Currency::Exchange::Rate::Source::Test.USD_EUR
290
+ m.should be_close(m_expected, 0.001)
291
+ end
292
+
293
+
294
+ it "invalid currency code" do
295
+ lambda {Currency::Money.new(123, :asdf)}.should raise_error(Currency::Exception::InvalidCurrencyCode)
296
+ lambda {Currency::Money.new(123, 5)}.should raise_error(Currency::Exception::InvalidCurrencyCode)
297
+ end
298
+
299
+
300
+ it "time default" do
301
+ Currency::Money.default_time = nil
302
+
303
+ usd = Currency::Money.new(123.45, :USD)
304
+ usd.should_not == nil
305
+ usd.time.should == nil
306
+
307
+ Currency::Money.default_time = Time.now
308
+ usd = Currency::Money.new(123.45, :USD)
309
+ usd.should_not == nil
310
+ Currency::Money.default_time.should == usd.time
311
+ end
312
+
313
+
314
+ it "time now" do
315
+ Currency::Money.default_time = :now
316
+
317
+ usd = Currency::Money.new(123.45, :USD)
318
+ usd.should_not == nil
319
+ usd.time.should_not == nil
320
+
321
+ sleep 1
322
+
323
+ usd2 = Currency::Money.new(123.45, :USD)
324
+ usd2.should_not == nil
325
+ usd2.time.should_not == nil
326
+ (usd.time != usd2.time).should_not == nil
327
+
328
+ Currency::Money.default_time = nil
329
+ end
330
+
331
+
332
+ it "time fixed" do
333
+ Currency::Money.default_time = Time.new
334
+
335
+ usd = Currency::Money.new(123.45, :USD)
336
+ usd.should_not == nil
337
+ usd.time.should_not == nil
338
+
339
+ sleep 1
340
+
341
+ usd2 = Currency::Money.new(123.45, :USD)
342
+ usd2.should_not == nil
343
+ usd2.time.should_not == nil
344
+ usd.time.should == usd2.time
345
+ end
346
+ end
347
+