money 3.6.1 → 3.6.2
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/CHANGELOG.md +335 -319
- data/LICENSE +21 -21
- data/README.md +214 -209
- data/Rakefile +49 -49
- data/lib/money.rb +27 -27
- data/lib/money/bank/base.rb +131 -131
- data/lib/money/bank/variable_exchange.rb +252 -251
- data/lib/money/core_extensions.rb +82 -63
- data/lib/money/currency.rb +422 -415
- data/lib/money/money.rb +387 -1210
- data/lib/money/money/arithmetic.rb +246 -0
- data/lib/money/money/formatting.rb +234 -0
- data/lib/money/money/parsing.rb +350 -0
- data/money.gemspec +34 -27
- data/spec/bank/base_spec.rb +72 -72
- data/spec/bank/variable_exchange_spec.rb +238 -238
- data/spec/core_extensions_spec.rb +158 -142
- data/spec/currency_spec.rb +133 -128
- data/spec/money/arithmetic_spec.rb +479 -0
- data/spec/money/formatting_spec.rb +352 -0
- data/spec/money/parsing_spec.rb +197 -0
- data/spec/money_spec.rb +271 -1268
- data/spec/spec_helper.rb +28 -17
- metadata +33 -23
- data/lib/money.rbc +0 -170
- data/lib/money/bank/base.rbc +0 -800
- data/lib/money/bank/variable_exchange.rbc +0 -2496
- data/lib/money/core_extensions.rbc +0 -474
- data/lib/money/currency.rbc +0 -22600
- data/lib/money/money.rbc +0 -10070
- data/spec/bank/base_spec.rbc +0 -2409
- data/spec/bank/variable_exchange_spec.rbc +0 -7389
- data/spec/core_extensions_spec.rbc +0 -5215
- data/spec/currency_spec.rbc +0 -4341
- data/spec/money_spec.rbc +0 -50121
- data/spec/spec_helper.rbc +0 -346
data/spec/money_spec.rb
CHANGED
@@ -1,1268 +1,271 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
require "spec_helper"
|
4
|
-
|
5
|
-
describe Money do
|
6
|
-
|
7
|
-
describe "#new" do
|
8
|
-
it "rounds the given cents to an integer" do
|
9
|
-
Money.new(1.00, "USD").cents.should == 1
|
10
|
-
Money.new(1.01, "USD").cents.should == 1
|
11
|
-
Money.new(1.50, "USD").cents.should == 2
|
12
|
-
end
|
13
|
-
|
14
|
-
it "is associated to the singleton instance of Bank::VariableExchange by default" do
|
15
|
-
Money.new(0).bank.should be_equal(Money::Bank::VariableExchange.instance)
|
16
|
-
end
|
17
|
-
|
18
|
-
end
|
19
|
-
|
20
|
-
describe "#cents" do
|
21
|
-
it "returns the amount of cents passed to the constructor" do
|
22
|
-
Money.new(200_00, "USD").cents.should == 200_00
|
23
|
-
end
|
24
|
-
|
25
|
-
it "stores cents as an integer regardless of what is passed into the constructor" do
|
26
|
-
[ Money.new(100), 1.to_money, 1.00.to_money, BigDecimal('1.00').to_money ].each do |m|
|
27
|
-
m.cents.should == 100
|
28
|
-
m.cents.should be_an_instance_of(Fixnum)
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
describe "#dollars" do
|
34
|
-
it "gets cents as dollars" do
|
35
|
-
Money.new_with_dollars(1).should == Money.new(100)
|
36
|
-
Money.new_with_dollars(1, "USD").should == Money.new(100, "USD")
|
37
|
-
Money.new_with_dollars(1, "EUR").should == Money.new(100, "EUR")
|
38
|
-
end
|
39
|
-
|
40
|
-
it "should respect :subunit_to_unit currency property" do
|
41
|
-
Money.new(1_00, "USD").dollars.should == 1
|
42
|
-
Money.new(1_000, "TND").dollars.should == 1
|
43
|
-
Money.new(1, "CLP").dollars.should == 1
|
44
|
-
end
|
45
|
-
|
46
|
-
it "should not loose precision" do
|
47
|
-
Money.new(100_37).dollars.should == 100.37
|
48
|
-
Money.new_with_dollars(100.37).dollars.should == 100.37
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
|
-
specify "#currency returns the currency passed to the constructor" do
|
53
|
-
Money.new(200_00, "USD").currency.should == Money::Currency.new("USD")
|
54
|
-
end
|
55
|
-
|
56
|
-
specify "#currency_string returns the iso_code of the currency object" do
|
57
|
-
Money.new(200_00, "USD").currency_as_string.should == Money::Currency.new("USD").to_s
|
58
|
-
Money.new(200_00, "USD").currency_as_string.should == "USD"
|
59
|
-
Money.new(200_00, "EUR").currency_as_string.should == "EUR"
|
60
|
-
Money.new(200_00, "YEN").currency_as_string.should == "YEN"
|
61
|
-
end
|
62
|
-
|
63
|
-
specify "#currency_string= set the currency object using the provided string" do
|
64
|
-
obj = Money.new(200_00, "USD")
|
65
|
-
obj.currency_as_string = "EUR"
|
66
|
-
obj.currency.should == Money::Currency.new("EUR")
|
67
|
-
obj.currency_as_string = "YEN"
|
68
|
-
obj.currency.should == Money::Currency.new("YEN")
|
69
|
-
obj.currency_as_string = "USD"
|
70
|
-
obj.currency.should == Money::Currency.new("USD")
|
71
|
-
end
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
Money.new(
|
76
|
-
Money.new(
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
Money.new(
|
83
|
-
Money.new(
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
Money.new(
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
Money.new(
|
113
|
-
end
|
114
|
-
|
115
|
-
specify "
|
116
|
-
Money.new(
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
Money.new(
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
end
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
it "
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
describe "#/" do
|
274
|
-
it "divides current money amount by the divisor while retaining the currency" do
|
275
|
-
(Money.new(10_00, "USD") / 10).should == Money.new(1_00, "USD")
|
276
|
-
end
|
277
|
-
|
278
|
-
it "divides Money by Fixnum and returns Money" do
|
279
|
-
ts = [
|
280
|
-
{:a => Money.new( 13, :USD), :b => 4, :c => Money.new( 3, :USD)},
|
281
|
-
{:a => Money.new( 13, :USD), :b => -4, :c => Money.new(-4, :USD)},
|
282
|
-
{:a => Money.new(-13, :USD), :b => 4, :c => Money.new(-4, :USD)},
|
283
|
-
{:a => Money.new(-13, :USD), :b => -4, :c => Money.new( 3, :USD)},
|
284
|
-
]
|
285
|
-
ts.each do |t|
|
286
|
-
(t[:a] / t[:b]).should == t[:c]
|
287
|
-
end
|
288
|
-
end
|
289
|
-
|
290
|
-
it "divides Money by Money (same currency) and returns Float" do
|
291
|
-
ts = [
|
292
|
-
{:a => Money.new( 13, :USD), :b => Money.new( 4, :USD), :c => 3.25},
|
293
|
-
{:a => Money.new( 13, :USD), :b => Money.new(-4, :USD), :c => -3.25},
|
294
|
-
{:a => Money.new(-13, :USD), :b => Money.new( 4, :USD), :c => -3.25},
|
295
|
-
{:a => Money.new(-13, :USD), :b => Money.new(-4, :USD), :c => 3.25},
|
296
|
-
]
|
297
|
-
ts.each do |t|
|
298
|
-
(t[:a] / t[:b]).should == t[:c]
|
299
|
-
end
|
300
|
-
end
|
301
|
-
|
302
|
-
it "divides Money by Money (different currency) and returns Float" do
|
303
|
-
ts = [
|
304
|
-
{:a => Money.new( 13, :USD), :b => Money.new( 4, :EUR), :c => 1.625},
|
305
|
-
{:a => Money.new( 13, :USD), :b => Money.new(-4, :EUR), :c => -1.625},
|
306
|
-
{:a => Money.new(-13, :USD), :b => Money.new( 4, :EUR), :c => -1.625},
|
307
|
-
{:a => Money.new(-13, :USD), :b => Money.new(-4, :EUR), :c => 1.625},
|
308
|
-
]
|
309
|
-
ts.each do |t|
|
310
|
-
t[:b].should_receive(:exchange_to).once.with(t[:a].currency).and_return(Money.new(t[:b].cents * 2, :USD))
|
311
|
-
(t[:a] / t[:b]).should == t[:c]
|
312
|
-
end
|
313
|
-
end
|
314
|
-
end
|
315
|
-
|
316
|
-
specify "#div -> money / fixnum" do
|
317
|
-
ts = [
|
318
|
-
{:a => Money.new( 13, :USD), :b => 4, :c => Money.new( 3, :USD)},
|
319
|
-
{:a => Money.new( 13, :USD), :b => -4, :c => Money.new(-4, :USD)},
|
320
|
-
{:a => Money.new(-13, :USD), :b => 4, :c => Money.new(-4, :USD)},
|
321
|
-
{:a => Money.new(-13, :USD), :b => -4, :c => Money.new( 3, :USD)},
|
322
|
-
]
|
323
|
-
ts.each do |t|
|
324
|
-
t[:a].div(t[:b]).should == t[:c]
|
325
|
-
end
|
326
|
-
end
|
327
|
-
|
328
|
-
specify "#div -> money / money (same currency)" do
|
329
|
-
ts = [
|
330
|
-
{:a => Money.new( 13, :USD), :b => Money.new( 4, :USD), :c => 3.25},
|
331
|
-
{:a => Money.new( 13, :USD), :b => Money.new(-4, :USD), :c => -3.25},
|
332
|
-
{:a => Money.new(-13, :USD), :b => Money.new( 4, :USD), :c => -3.25},
|
333
|
-
{:a => Money.new(-13, :USD), :b => Money.new(-4, :USD), :c => 3.25},
|
334
|
-
]
|
335
|
-
ts.each do |t|
|
336
|
-
t[:a].div(t[:b]).should == t[:c]
|
337
|
-
end
|
338
|
-
end
|
339
|
-
|
340
|
-
specify "#div -> money / money (different currency)" do
|
341
|
-
ts = [
|
342
|
-
{:a => Money.new( 13, :USD), :b => Money.new( 4, :EUR), :c => 1.625},
|
343
|
-
{:a => Money.new( 13, :USD), :b => Money.new(-4, :EUR), :c => -1.625},
|
344
|
-
{:a => Money.new(-13, :USD), :b => Money.new( 4, :EUR), :c => -1.625},
|
345
|
-
{:a => Money.new(-13, :USD), :b => Money.new(-4, :EUR), :c => 1.625},
|
346
|
-
]
|
347
|
-
ts.each do |t|
|
348
|
-
t[:b].should_receive(:exchange_to).once.with(t[:a].currency).and_return(Money.new(t[:b].cents * 2, :USD))
|
349
|
-
t[:a].div(t[:b]).should == t[:c]
|
350
|
-
end
|
351
|
-
end
|
352
|
-
|
353
|
-
specify "#divmod -> money `divmod` fixnum" do
|
354
|
-
ts = [
|
355
|
-
{:a => Money.new( 13, :USD), :b => 4, :c => [Money.new( 3, :USD), Money.new( 1, :USD)]},
|
356
|
-
{:a => Money.new( 13, :USD), :b => -4, :c => [Money.new(-4, :USD), Money.new(-3, :USD)]},
|
357
|
-
{:a => Money.new(-13, :USD), :b => 4, :c => [Money.new(-4, :USD), Money.new( 3, :USD)]},
|
358
|
-
{:a => Money.new(-13, :USD), :b => -4, :c => [Money.new( 3, :USD), Money.new(-1, :USD)]},
|
359
|
-
]
|
360
|
-
ts.each do |t|
|
361
|
-
t[:a].divmod(t[:b]).should == t[:c]
|
362
|
-
end
|
363
|
-
end
|
364
|
-
|
365
|
-
specify "#divmod -> money `divmod` money (same currency)" do
|
366
|
-
ts = [
|
367
|
-
{:a => Money.new( 13, :USD), :b => Money.new( 4, :USD), :c => [ 3, Money.new( 1, :USD)]},
|
368
|
-
{:a => Money.new( 13, :USD), :b => Money.new(-4, :USD), :c => [-4, Money.new(-3, :USD)]},
|
369
|
-
{:a => Money.new(-13, :USD), :b => Money.new( 4, :USD), :c => [-4, Money.new( 3, :USD)]},
|
370
|
-
{:a => Money.new(-13, :USD), :b => Money.new(-4, :USD), :c => [ 3, Money.new(-1, :USD)]},
|
371
|
-
]
|
372
|
-
ts.each do |t|
|
373
|
-
t[:a].divmod(t[:b]).should == t[:c]
|
374
|
-
end
|
375
|
-
end
|
376
|
-
|
377
|
-
specify "#divmod -> money `divmod` money (different currency)" do
|
378
|
-
ts = [
|
379
|
-
{:a => Money.new( 13, :USD), :b => Money.new( 4, :EUR), :c => [ 1, Money.new( 5, :USD)]},
|
380
|
-
{:a => Money.new( 13, :USD), :b => Money.new(-4, :EUR), :c => [-2, Money.new(-3, :USD)]},
|
381
|
-
{:a => Money.new(-13, :USD), :b => Money.new( 4, :EUR), :c => [-2, Money.new( 3, :USD)]},
|
382
|
-
{:a => Money.new(-13, :USD), :b => Money.new(-4, :EUR), :c => [ 1, Money.new(-5, :USD)]},
|
383
|
-
]
|
384
|
-
ts.each do |t|
|
385
|
-
t[:b].should_receive(:exchange_to).once.with(t[:a].currency).and_return(Money.new(t[:b].cents * 2, :USD))
|
386
|
-
t[:a].divmod(t[:b]).should == t[:c]
|
387
|
-
end
|
388
|
-
end
|
389
|
-
|
390
|
-
specify "#modulo -> money `modulo` fixnum" do
|
391
|
-
ts = [
|
392
|
-
{:a => Money.new( 13, :USD), :b => 4, :c => Money.new( 1, :USD)},
|
393
|
-
{:a => Money.new( 13, :USD), :b => -4, :c => Money.new(-3, :USD)},
|
394
|
-
{:a => Money.new(-13, :USD), :b => 4, :c => Money.new( 3, :USD)},
|
395
|
-
{:a => Money.new(-13, :USD), :b => -4, :c => Money.new(-1, :USD)},
|
396
|
-
]
|
397
|
-
ts.each do |t|
|
398
|
-
t[:a].modulo(t[:b]).should == t[:c]
|
399
|
-
end
|
400
|
-
end
|
401
|
-
|
402
|
-
specify "#modulo -> money `modulo` money (same currency)" do
|
403
|
-
ts = [
|
404
|
-
{:a => Money.new( 13, :USD), :b => Money.new( 4, :USD), :c => Money.new( 1, :USD)},
|
405
|
-
{:a => Money.new( 13, :USD), :b => Money.new(-4, :USD), :c => Money.new(-3, :USD)},
|
406
|
-
{:a => Money.new(-13, :USD), :b => Money.new( 4, :USD), :c => Money.new( 3, :USD)},
|
407
|
-
{:a => Money.new(-13, :USD), :b => Money.new(-4, :USD), :c => Money.new(-1, :USD)},
|
408
|
-
]
|
409
|
-
ts.each do |t|
|
410
|
-
t[:a].modulo(t[:b]).should == t[:c]
|
411
|
-
end
|
412
|
-
end
|
413
|
-
|
414
|
-
specify "#modulo -> money `modulo` money (different currency)" do
|
415
|
-
ts = [
|
416
|
-
{:a => Money.new( 13, :USD), :b => Money.new( 4, :EUR), :c => Money.new( 5, :USD)},
|
417
|
-
{:a => Money.new( 13, :USD), :b => Money.new(-4, :EUR), :c => Money.new(-3, :USD)},
|
418
|
-
{:a => Money.new(-13, :USD), :b => Money.new( 4, :EUR), :c => Money.new( 3, :USD)},
|
419
|
-
{:a => Money.new(-13, :USD), :b => Money.new(-4, :EUR), :c => Money.new(-5, :USD)},
|
420
|
-
]
|
421
|
-
ts.each do |t|
|
422
|
-
t[:b].should_receive(:exchange_to).once.with(t[:a].currency).and_return(Money.new(t[:b].cents * 2, :USD))
|
423
|
-
t[:a].modulo(t[:b]).should == t[:c]
|
424
|
-
end
|
425
|
-
end
|
426
|
-
|
427
|
-
specify "#% -> money % fixnum" do
|
428
|
-
ts = [
|
429
|
-
{:a => Money.new( 13, :USD), :b => 4, :c => Money.new( 1, :USD)},
|
430
|
-
{:a => Money.new( 13, :USD), :b => -4, :c => Money.new(-3, :USD)},
|
431
|
-
{:a => Money.new(-13, :USD), :b => 4, :c => Money.new( 3, :USD)},
|
432
|
-
{:a => Money.new(-13, :USD), :b => -4, :c => Money.new(-1, :USD)},
|
433
|
-
]
|
434
|
-
ts.each do |t|
|
435
|
-
(t[:a] % t[:b]).should == t[:c]
|
436
|
-
end
|
437
|
-
end
|
438
|
-
|
439
|
-
specify "#% -> money % money (same currency)" do
|
440
|
-
ts = [
|
441
|
-
{:a => Money.new( 13, :USD), :b => Money.new( 4, :USD), :c => Money.new( 1, :USD)},
|
442
|
-
{:a => Money.new( 13, :USD), :b => Money.new(-4, :USD), :c => Money.new(-3, :USD)},
|
443
|
-
{:a => Money.new(-13, :USD), :b => Money.new( 4, :USD), :c => Money.new( 3, :USD)},
|
444
|
-
{:a => Money.new(-13, :USD), :b => Money.new(-4, :USD), :c => Money.new(-1, :USD)},
|
445
|
-
]
|
446
|
-
ts.each do |t|
|
447
|
-
(t[:a] % t[:b]).should == t[:c]
|
448
|
-
end
|
449
|
-
end
|
450
|
-
|
451
|
-
specify "#% -> money % money (different currency)" do
|
452
|
-
ts = [
|
453
|
-
{:a => Money.new( 13, :USD), :b => Money.new( 4, :EUR), :c => Money.new( 5, :USD)},
|
454
|
-
{:a => Money.new( 13, :USD), :b => Money.new(-4, :EUR), :c => Money.new(-3, :USD)},
|
455
|
-
{:a => Money.new(-13, :USD), :b => Money.new( 4, :EUR), :c => Money.new( 3, :USD)},
|
456
|
-
{:a => Money.new(-13, :USD), :b => Money.new(-4, :EUR), :c => Money.new(-5, :USD)},
|
457
|
-
]
|
458
|
-
ts.each do |t|
|
459
|
-
t[:b].should_receive(:exchange_to).once.with(t[:a].currency).and_return(Money.new(t[:b].cents * 2, :USD))
|
460
|
-
(t[:a] % t[:b]).should == t[:c]
|
461
|
-
end
|
462
|
-
end
|
463
|
-
|
464
|
-
specify "#remainder -> money `remainder` fixnum" do
|
465
|
-
ts = [
|
466
|
-
{:a => Money.new( 13, :USD), :b => 4, :c => Money.new( 1, :USD)},
|
467
|
-
{:a => Money.new( 13, :USD), :b => -4, :c => Money.new( 1, :USD)},
|
468
|
-
{:a => Money.new(-13, :USD), :b => 4, :c => Money.new(-1, :USD)},
|
469
|
-
{:a => Money.new(-13, :USD), :b => -4, :c => Money.new(-1, :USD)},
|
470
|
-
]
|
471
|
-
ts.each do |t|
|
472
|
-
t[:a].remainder(t[:b]).should == t[:c]
|
473
|
-
end
|
474
|
-
end
|
475
|
-
|
476
|
-
specify "#remainder -> money `remainder` money (same currency)" do
|
477
|
-
ts = [
|
478
|
-
{:a => Money.new( 13, :USD), :b => Money.new( 4, :USD), :c => Money.new( 1, :USD)},
|
479
|
-
{:a => Money.new( 13, :USD), :b => Money.new(-4, :USD), :c => Money.new( 1, :USD)},
|
480
|
-
{:a => Money.new(-13, :USD), :b => Money.new( 4, :USD), :c => Money.new(-1, :USD)},
|
481
|
-
{:a => Money.new(-13, :USD), :b => Money.new(-4, :USD), :c => Money.new(-1, :USD)},
|
482
|
-
]
|
483
|
-
ts.each do |t|
|
484
|
-
t[:a].remainder(t[:b]).should == t[:c]
|
485
|
-
end
|
486
|
-
end
|
487
|
-
|
488
|
-
specify "#remainder -> money `remainder` money (different currency)" do
|
489
|
-
ts = [
|
490
|
-
{:a => Money.new( 13, :USD), :b => Money.new( 4, :EUR), :c => Money.new( 5, :USD)},
|
491
|
-
{:a => Money.new( 13, :USD), :b => Money.new(-4, :EUR), :c => Money.new( 5, :USD)},
|
492
|
-
{:a => Money.new(-13, :USD), :b => Money.new( 4, :EUR), :c => Money.new(-5, :USD)},
|
493
|
-
{:a => Money.new(-13, :USD), :b => Money.new(-4, :EUR), :c => Money.new(-5, :USD)},
|
494
|
-
]
|
495
|
-
ts.each do |t|
|
496
|
-
t[:b].should_receive(:exchange_to).once.with(t[:a].currency).and_return(Money.new(t[:b].cents * 2, :USD))
|
497
|
-
t[:a].remainder(t[:b]).should == t[:c]
|
498
|
-
end
|
499
|
-
end
|
500
|
-
|
501
|
-
specify "#abs correctly returns the absolute value as a new Money object" do
|
502
|
-
n = Money.new(-1, :USD)
|
503
|
-
n.abs.should == Money.new( 1, :USD)
|
504
|
-
n.should == Money.new(-1, :USD)
|
505
|
-
end
|
506
|
-
|
507
|
-
specify "Money.format brute force :subunit_to_unit = 1" do
|
508
|
-
("0".."9").each do |amt|
|
509
|
-
amt.to_money("VUV").format(:symbol => false).should == amt
|
510
|
-
end
|
511
|
-
("-1".."-9").each do |amt|
|
512
|
-
amt.to_money("VUV").format(:symbol => false).should == amt
|
513
|
-
end
|
514
|
-
"1000".to_money("VUV").format(:symbol => false).should == "1,000"
|
515
|
-
"-1000".to_money("VUV").format(:symbol => false).should == "-1,000"
|
516
|
-
end
|
517
|
-
|
518
|
-
specify "Money.format brute force :subunit_to_unit = 5" do
|
519
|
-
("0.0".."9.4").each do |amt|
|
520
|
-
next if amt[-1].to_i > 4
|
521
|
-
amt.to_money("MGA").format(:symbol => false).should == amt
|
522
|
-
end
|
523
|
-
("-0.1".."-9.4").each do |amt|
|
524
|
-
next if amt[-1].to_i > 4
|
525
|
-
amt.to_money("MGA").format(:symbol => false).should == amt
|
526
|
-
end
|
527
|
-
"1000.0".to_money("MGA").format(:symbol => false).should == "1,000.0"
|
528
|
-
"-1000.0".to_money("MGA").format(:symbol => false).should == "-1,000.0"
|
529
|
-
end
|
530
|
-
|
531
|
-
specify "Money.format brute force :subunit_to_unit = 10" do
|
532
|
-
("0.0".."9.9").each do |amt|
|
533
|
-
amt.to_money("VND").format(:symbol => false).should == amt.to_s.gsub(/\./, ",")
|
534
|
-
end
|
535
|
-
("-0.1".."-9.9").each do |amt|
|
536
|
-
amt.to_money("VND").format(:symbol => false).should == amt.to_s.gsub(/\./, ",")
|
537
|
-
end
|
538
|
-
"1000.0".to_money("VND").format(:symbol => false).should == "1.000,0"
|
539
|
-
"-1000.0".to_money("VND").format(:symbol => false).should == "-1.000,0"
|
540
|
-
end
|
541
|
-
|
542
|
-
specify "Money.format brute force :subunit_to_unit = 100" do
|
543
|
-
("0.00".."9.99").each do |amt|
|
544
|
-
amt.to_money("USD").format(:symbol => false).should == amt
|
545
|
-
end
|
546
|
-
("-0.01".."-9.99").each do |amt|
|
547
|
-
amt.to_money("USD").format(:symbol => false).should == amt
|
548
|
-
end
|
549
|
-
"1000.00".to_money("USD").format(:symbol => false).should == "1,000.00"
|
550
|
-
"-1000.00".to_money("USD").format(:symbol => false).should == "-1,000.00"
|
551
|
-
end
|
552
|
-
|
553
|
-
specify "Money.format brute force :subunit_to_unit = 1000" do
|
554
|
-
("0.000".."9.999").each do |amt|
|
555
|
-
amt.to_money("IQD").format(:symbol => false).should == amt
|
556
|
-
end
|
557
|
-
("-0.001".."-9.999").each do |amt|
|
558
|
-
amt.to_money("IQD").format(:symbol => false).should == amt
|
559
|
-
end
|
560
|
-
"1000.000".to_money("IQD").format(:symbol => false).should == "1,000.000"
|
561
|
-
"-1000.000".to_money("IQD").format(:symbol => false).should == "-1,000.000"
|
562
|
-
end
|
563
|
-
|
564
|
-
specify "Money.to_s works" do
|
565
|
-
Money.new(10_00).to_s.should == "10.00"
|
566
|
-
Money.new(400_08).to_s.should == "400.08"
|
567
|
-
Money.new(-237_43).to_s.should == "-237.43"
|
568
|
-
end
|
569
|
-
|
570
|
-
specify "Money.to_s should respect :subunit_to_unit currency property" do
|
571
|
-
Money.new(10_00, "BHD").to_s.should == "1.000"
|
572
|
-
Money.new(10_00, "CNY").to_s.should == "10.00"
|
573
|
-
end
|
574
|
-
|
575
|
-
specify "Money.to_s shouldn't have decimal when :subunit_to_unit is 1" do
|
576
|
-
Money.new(10_00, "CLP").to_s.should == "1000"
|
577
|
-
end
|
578
|
-
|
579
|
-
specify "Money.to_s should work with :subunit_to_unit == 5" do
|
580
|
-
Money.new(10_00, "MGA").to_s.should == "200.0"
|
581
|
-
end
|
582
|
-
|
583
|
-
specify "Money.to_s should respect :decimal_mark" do
|
584
|
-
Money.new(10_00, "BRL").to_s.should == "10,00"
|
585
|
-
end
|
586
|
-
|
587
|
-
specify "Money.to_f works" do
|
588
|
-
Money.new(10_00).to_f.should == 10.0
|
589
|
-
end
|
590
|
-
|
591
|
-
specify "Money.to_f should respect :subunit_to_unit currency property" do
|
592
|
-
Money.new(10_00, "BHD").to_f.should == 1.0
|
593
|
-
end
|
594
|
-
|
595
|
-
specify "#symbol works as documented" do
|
596
|
-
currency = Money::Currency.new("EUR")
|
597
|
-
currency.should_receive(:symbol).and_return("€")
|
598
|
-
Money.empty(currency).symbol.should == "€"
|
599
|
-
|
600
|
-
currency = Money::Currency.new("EUR")
|
601
|
-
currency.should_receive(:symbol).and_return(nil)
|
602
|
-
Money.empty(currency).symbol.should == "¤"
|
603
|
-
end
|
604
|
-
|
605
|
-
{
|
606
|
-
:thousands_separator => { :default => ",", :other => "." },
|
607
|
-
:decimal_mark => { :default => ".", :other => "," }
|
608
|
-
}.each do |method, options|
|
609
|
-
describe "##{method}" do
|
610
|
-
context "without I18n" do
|
611
|
-
it "works as documented" do
|
612
|
-
Money.empty("USD").send(method).should == options[:default]
|
613
|
-
Money.empty("EUR").send(method).should == options[:other]
|
614
|
-
Money.empty("BRL").send(method).should == options[:other]
|
615
|
-
end
|
616
|
-
end
|
617
|
-
|
618
|
-
if Object.const_defined?("I18n")
|
619
|
-
context "with I18n" do
|
620
|
-
before :all do
|
621
|
-
reset_i18n
|
622
|
-
store_number_formats(:en, method => options[:default])
|
623
|
-
store_number_formats(:de, method => options[:other])
|
624
|
-
end
|
625
|
-
|
626
|
-
it "looks up #{method} for current locale" do
|
627
|
-
I18n.locale = :en
|
628
|
-
Money.empty("USD").send(method).should == options[:default]
|
629
|
-
I18n.locale = :de
|
630
|
-
Money.empty("USD").send(method).should == options[:other]
|
631
|
-
end
|
632
|
-
|
633
|
-
it "fallbacks to default behaviour for missing translations" do
|
634
|
-
I18n.locale = :de
|
635
|
-
Money.empty("USD").send(method).should == options[:other]
|
636
|
-
I18n.locale = :fr
|
637
|
-
Money.empty("USD").send(method).should == options[:default]
|
638
|
-
end
|
639
|
-
|
640
|
-
after :all do
|
641
|
-
reset_i18n
|
642
|
-
end
|
643
|
-
end
|
644
|
-
else
|
645
|
-
puts "can't test ##{method} with I18n because it isn't loaded"
|
646
|
-
end
|
647
|
-
end
|
648
|
-
end
|
649
|
-
|
650
|
-
describe "#format" do
|
651
|
-
it "returns the monetary value as a string" do
|
652
|
-
Money.ca_dollar(100).format.should == "$1.00"
|
653
|
-
Money.new(40008).format.should == "$400.08"
|
654
|
-
end
|
655
|
-
|
656
|
-
it "should respect :subunit_to_unit currency property" do
|
657
|
-
Money.new(10_00, "BHD").format.should == "ب.د1.000"
|
658
|
-
end
|
659
|
-
|
660
|
-
it "doesn't display a decimal when :subunit_to_unit is 1" do
|
661
|
-
Money.new(10_00, "CLP").format.should == "$1.000"
|
662
|
-
end
|
663
|
-
|
664
|
-
it "respects the thousands_separator and decimal_mark defaults" do
|
665
|
-
one_thousand = Proc.new do |currency|
|
666
|
-
Money.new(1000_00, currency).format
|
667
|
-
end
|
668
|
-
|
669
|
-
# Pounds
|
670
|
-
one_thousand["GBP"].should == "£1,000.00"
|
671
|
-
|
672
|
-
# Dollars
|
673
|
-
one_thousand["USD"].should == "$1,000.00"
|
674
|
-
one_thousand["CAD"].should == "$1,000.00"
|
675
|
-
one_thousand["AUD"].should == "$1,000.00"
|
676
|
-
one_thousand["NZD"].should == "$1,000.00"
|
677
|
-
one_thousand["ZWD"].should == "$1,000.00"
|
678
|
-
|
679
|
-
# Yen
|
680
|
-
one_thousand["JPY"].should == "¥1,000.00"
|
681
|
-
one_thousand["CNY"].should == "¥1,000.00"
|
682
|
-
|
683
|
-
# Euro
|
684
|
-
one_thousand["EUR"].should == "1.000,00 €"
|
685
|
-
|
686
|
-
# Rupees
|
687
|
-
one_thousand["INR"].should == "₨1,000.00"
|
688
|
-
one_thousand["NPR"].should == "₨1,000.00"
|
689
|
-
one_thousand["SCR"].should == "1,000.00 ₨"
|
690
|
-
one_thousand["LKR"].should == "1,000.00 ₨"
|
691
|
-
|
692
|
-
# Brazilian Real
|
693
|
-
one_thousand["BRL"].should == "R$ 1.000,00"
|
694
|
-
|
695
|
-
# Other
|
696
|
-
one_thousand["SEK"].should == "kr1,000.00"
|
697
|
-
one_thousand["GHC"].should == "₵1,000.00"
|
698
|
-
end
|
699
|
-
|
700
|
-
describe "if the monetary value is 0" do
|
701
|
-
before :each do
|
702
|
-
@money = Money.us_dollar(0)
|
703
|
-
end
|
704
|
-
|
705
|
-
it "returns 'free' when :display_free is true" do
|
706
|
-
@money.format(:display_free => true).should == 'free'
|
707
|
-
end
|
708
|
-
|
709
|
-
it "returns '$0.00' when :display_free is false or not given" do
|
710
|
-
@money.format.should == '$0.00'
|
711
|
-
@money.format(:display_free => false).should == '$0.00'
|
712
|
-
@money.format(:display_free => nil).should == '$0.00'
|
713
|
-
end
|
714
|
-
|
715
|
-
it "returns the value specified by :display_free if it's a string-like object" do
|
716
|
-
@money.format(:display_free => 'gratis').should == 'gratis'
|
717
|
-
end
|
718
|
-
end
|
719
|
-
|
720
|
-
specify "#format(:with_currency => true) works as documented" do
|
721
|
-
Money.ca_dollar(100).format(:with_currency => true).should == "$1.00 CAD"
|
722
|
-
Money.us_dollar(85).format(:with_currency => true).should == "$0.85 USD"
|
723
|
-
end
|
724
|
-
|
725
|
-
specify "#format(:no_cents => true) works as documented" do
|
726
|
-
Money.ca_dollar(100).format(:no_cents => true).should == "$1"
|
727
|
-
Money.ca_dollar(599).format(:no_cents => true).should == "$5"
|
728
|
-
Money.ca_dollar(570).format(:no_cents => true, :with_currency => true).should == "$5 CAD"
|
729
|
-
Money.ca_dollar(39000).format(:no_cents => true).should == "$390"
|
730
|
-
end
|
731
|
-
|
732
|
-
specify "#format(:no_cents => true) should respect :subunit_to_unit currency property" do
|
733
|
-
Money.new(10_00, "BHD").format(:no_cents => true).should == "ب.د1"
|
734
|
-
end
|
735
|
-
|
736
|
-
specify "#format(:symbol => a symbol string) uses the given value as the money symbol" do
|
737
|
-
Money.new(100, "GBP").format(:symbol => "£").should == "£1.00"
|
738
|
-
end
|
739
|
-
|
740
|
-
specify "#format(:symbol => true) returns symbol based on the given currency code" do
|
741
|
-
one = Proc.new do |currency|
|
742
|
-
Money.new(100, currency).format(:symbol => true)
|
743
|
-
end
|
744
|
-
|
745
|
-
# Pounds
|
746
|
-
one["GBP"].should == "£1.00"
|
747
|
-
|
748
|
-
# Dollars
|
749
|
-
one["USD"].should == "$1.00"
|
750
|
-
one["CAD"].should == "$1.00"
|
751
|
-
one["AUD"].should == "$1.00"
|
752
|
-
one["NZD"].should == "$1.00"
|
753
|
-
one["ZWD"].should == "$1.00"
|
754
|
-
|
755
|
-
# Yen
|
756
|
-
one["JPY"].should == "¥1.00"
|
757
|
-
one["CNY"].should == "¥1.00"
|
758
|
-
|
759
|
-
# Euro
|
760
|
-
one["EUR"].should == "1,00 €"
|
761
|
-
|
762
|
-
# Rupees
|
763
|
-
one["INR"].should == "₨1.00"
|
764
|
-
one["NPR"].should == "₨1.00"
|
765
|
-
one["SCR"].should == "1.00 ₨"
|
766
|
-
one["LKR"].should == "1.00 ₨"
|
767
|
-
|
768
|
-
# Brazilian Real
|
769
|
-
one["BRL"].should == "R$ 1,00"
|
770
|
-
|
771
|
-
# Other
|
772
|
-
one["SEK"].should == "kr1.00"
|
773
|
-
one["GHC"].should == "₵1.00"
|
774
|
-
end
|
775
|
-
|
776
|
-
specify "#format(:symbol => true) returns $ when currency code is not recognized" do
|
777
|
-
currency = Money::Currency.new("EUR")
|
778
|
-
currency.should_receive(:symbol).and_return(nil)
|
779
|
-
Money.new(100, currency).format(:symbol => true).should == "1,00 ¤"
|
780
|
-
end
|
781
|
-
|
782
|
-
specify "#format(:symbol => some non-Boolean value that evaluates to true) returns symbol based on the given currency code" do
|
783
|
-
Money.new(100, "GBP").format(:symbol => true).should == "£1.00"
|
784
|
-
Money.new(100, "EUR").format(:symbol => true).should == "1,00 €"
|
785
|
-
Money.new(100, "SEK").format(:symbol => true).should == "kr1.00"
|
786
|
-
end
|
787
|
-
|
788
|
-
specify "#format with :symbol == "", nil or false returns the amount without a symbol" do
|
789
|
-
money = Money.new(100, "GBP")
|
790
|
-
money.format(:symbol => "").should == "1.00"
|
791
|
-
money.format(:symbol => nil).should == "1.00"
|
792
|
-
money.format(:symbol => false).should == "1.00"
|
793
|
-
end
|
794
|
-
|
795
|
-
specify "#format without :symbol assumes that :symbol is set to true" do
|
796
|
-
money = Money.new(100)
|
797
|
-
money.format.should == "$1.00"
|
798
|
-
|
799
|
-
money = Money.new(100, "GBP")
|
800
|
-
money.format.should == "£1.00"
|
801
|
-
|
802
|
-
money = Money.new(100, "EUR")
|
803
|
-
money.format.should == "1,00 €"
|
804
|
-
end
|
805
|
-
|
806
|
-
specify "#format(:decimal_mark => a decimal_mark string) works as documented" do
|
807
|
-
Money.us_dollar(100).format(:decimal_mark => ",").should == "$1,00"
|
808
|
-
end
|
809
|
-
|
810
|
-
specify "#format will default decimal_mark to '.' if currency isn't recognized" do
|
811
|
-
Money.new(100, "ZWD").format.should == "$1.00"
|
812
|
-
end
|
813
|
-
|
814
|
-
specify "#format(:separator => a separator string) works as documented" do
|
815
|
-
Money.us_dollar(100).format(:separator => ",").should == "$1,00"
|
816
|
-
end
|
817
|
-
|
818
|
-
specify "#format(:thousands_separator => a thousands_separator string) works as documented" do
|
819
|
-
Money.us_dollar(100000).format(:thousands_separator => ".").should == "$1.000.00"
|
820
|
-
Money.us_dollar(200000).format(:thousands_separator => "").should == "$2000.00"
|
821
|
-
end
|
822
|
-
|
823
|
-
specify "#format(:thousands_separator => false or nil) works as documented" do
|
824
|
-
Money.us_dollar(100000).format(:thousands_separator => false).should == "$1000.00"
|
825
|
-
Money.us_dollar(200000).format(:thousands_separator => nil).should == "$2000.00"
|
826
|
-
end
|
827
|
-
|
828
|
-
specify "#format(:delimiter => a delimiter string) works as documented" do
|
829
|
-
Money.us_dollar(100000).format(:delimiter => ".").should == "$1.000.00"
|
830
|
-
Money.us_dollar(200000).format(:delimiter => "").should == "$2000.00"
|
831
|
-
end
|
832
|
-
|
833
|
-
specify "#format(:delimiter => false or nil) works as documented" do
|
834
|
-
Money.us_dollar(100000).format(:delimiter => false).should == "$1000.00"
|
835
|
-
Money.us_dollar(200000).format(:delimiter => nil).should == "$2000.00"
|
836
|
-
end
|
837
|
-
|
838
|
-
specify "#format will default thousands_separator to ',' if currency isn't recognized" do
|
839
|
-
Money.new(100000, "ZWD").format.should == "$1,000.00"
|
840
|
-
end
|
841
|
-
|
842
|
-
specify "#format(:html => true) works as documented" do
|
843
|
-
string = Money.ca_dollar(570).format(:html => true, :with_currency => true)
|
844
|
-
string.should == "$5.70 <span class=\"currency\">CAD</span>"
|
845
|
-
end
|
846
|
-
|
847
|
-
it "should insert commas into the result if the amount is sufficiently large" do
|
848
|
-
Money.us_dollar(1_000_000_000_12).format.should == "$1,000,000,000.12"
|
849
|
-
Money.us_dollar(1_000_000_000_12).format(:no_cents => true).should == "$1,000,000,000"
|
850
|
-
end
|
851
|
-
|
852
|
-
it "inserts thousands separator into the result if the amount is sufficiently large and the currency symbol is at the end" do
|
853
|
-
Money.euro(1_234_567_12).format.should == "1.234.567,12 €"
|
854
|
-
Money.euro(1_234_567_12).format(:no_cents => true).should == "1.234.567 €"
|
855
|
-
end
|
856
|
-
|
857
|
-
it "inserts currency symbol before the amount when :symbol_position is set to :before" do
|
858
|
-
Money.euro(1_234_567_12).format(:symbol_position => :before).should == "€1.234.567,12"
|
859
|
-
end
|
860
|
-
|
861
|
-
it "inserts currency symbol after the amount when :symbol_position is set to :after" do
|
862
|
-
Money.us_dollar(1_000_000_000_12).format(:symbol_position => :after).should == "1,000,000,000.12 $"
|
863
|
-
end
|
864
|
-
end
|
865
|
-
|
866
|
-
|
867
|
-
describe "Money.empty" do
|
868
|
-
it "Money.empty creates a new Money object of 0 cents" do
|
869
|
-
Money.empty.should == Money.new(0)
|
870
|
-
end
|
871
|
-
end
|
872
|
-
|
873
|
-
describe "Money.ca_dollar" do
|
874
|
-
it "creates a new Money object of the given value in CAD" do
|
875
|
-
Money.ca_dollar(50).should == Money.new(50, "CAD")
|
876
|
-
end
|
877
|
-
end
|
878
|
-
|
879
|
-
describe "Money.us_dollar" do
|
880
|
-
it "creates a new Money object of the given value in USD" do
|
881
|
-
Money.us_dollar(50).should == Money.new(50, "USD")
|
882
|
-
end
|
883
|
-
end
|
884
|
-
|
885
|
-
describe "Money.euro" do
|
886
|
-
it "creates a new Money object of the given value in EUR" do
|
887
|
-
Money.euro(50).should == Money.new(50, "EUR")
|
888
|
-
end
|
889
|
-
end
|
890
|
-
|
891
|
-
|
892
|
-
describe "Money.new_with_dollars" do
|
893
|
-
it "converts given amount to cents" do
|
894
|
-
Money.new_with_dollars(1).should == Money.new(100)
|
895
|
-
Money.new_with_dollars(1, "USD").should == Money.new(100, "USD")
|
896
|
-
Money.new_with_dollars(1, "EUR").should == Money.new(100, "EUR")
|
897
|
-
end
|
898
|
-
|
899
|
-
it "should respect :subunit_to_unit currency property" do
|
900
|
-
Money.new_with_dollars(1, "USD").should == Money.new(1_00, "USD")
|
901
|
-
Money.new_with_dollars(1, "TND").should == Money.new(1_000, "TND")
|
902
|
-
Money.new_with_dollars(1, "CLP").should == Money.new(1, "CLP")
|
903
|
-
end
|
904
|
-
|
905
|
-
it "should not loose precision" do
|
906
|
-
Money.new_with_dollars(1234).cents.should == 1234_00
|
907
|
-
Money.new_with_dollars(100.37).cents.should == 100_37
|
908
|
-
Money.new_with_dollars(BigDecimal.new('1234')).cents.should == 1234_00
|
909
|
-
end
|
910
|
-
|
911
|
-
it "accepts a currency options" do
|
912
|
-
m = Money.new_with_dollars(1)
|
913
|
-
m.currency.should == Money.default_currency
|
914
|
-
|
915
|
-
m = Money.new_with_dollars(1, Money::Currency.wrap("EUR"))
|
916
|
-
m.currency.should == Money::Currency.wrap("EUR")
|
917
|
-
|
918
|
-
m = Money.new_with_dollars(1, "EUR")
|
919
|
-
m.currency.should == Money::Currency.wrap("EUR")
|
920
|
-
end
|
921
|
-
|
922
|
-
it "accepts a bank options" do
|
923
|
-
m = Money.new_with_dollars(1)
|
924
|
-
m.bank.should == Money.default_bank
|
925
|
-
|
926
|
-
m = Money.new_with_dollars(1, "EUR", bank = Object.new)
|
927
|
-
m.bank.should == bank
|
928
|
-
end
|
929
|
-
|
930
|
-
it "is associated to the singleton instance of Bank::VariableExchange by default" do
|
931
|
-
Money.new_with_dollars(0).bank.should be_equal(Money::Bank::VariableExchange.instance)
|
932
|
-
end
|
933
|
-
end
|
934
|
-
|
935
|
-
describe "Money.from_string" do
|
936
|
-
it "converts given amount to cents" do
|
937
|
-
Money.from_string("1").should == Money.new(1_00)
|
938
|
-
Money.from_string("1").should == Money.new(1_00, "USD")
|
939
|
-
Money.from_string("1", "EUR").should == Money.new(1_00, "EUR")
|
940
|
-
end
|
941
|
-
|
942
|
-
it "should respect :subunit_to_unit currency property" do
|
943
|
-
Money.from_string("1", "USD").should == Money.new(1_00, "USD")
|
944
|
-
Money.from_string("1", "TND").should == Money.new(1_000, "TND")
|
945
|
-
Money.from_string("1", "CLP").should == Money.new(1, "CLP")
|
946
|
-
end
|
947
|
-
|
948
|
-
it "accepts a currency options" do
|
949
|
-
m = Money.from_string("1")
|
950
|
-
m.currency.should == Money.default_currency
|
951
|
-
|
952
|
-
m = Money.from_string("1", Money::Currency.wrap("EUR"))
|
953
|
-
m.currency.should == Money::Currency.wrap("EUR")
|
954
|
-
|
955
|
-
m = Money.from_string("1", "EUR")
|
956
|
-
m.currency.should == Money::Currency.wrap("EUR")
|
957
|
-
end
|
958
|
-
end
|
959
|
-
|
960
|
-
describe "Money.from_fixnum" do
|
961
|
-
it "converts given amount to cents" do
|
962
|
-
Money.from_fixnum(1).should == Money.new(1_00)
|
963
|
-
Money.from_fixnum(1).should == Money.new(1_00, "USD")
|
964
|
-
Money.from_fixnum(1, "EUR").should == Money.new(1_00, "EUR")
|
965
|
-
end
|
966
|
-
|
967
|
-
it "should respect :subunit_to_unit currency property" do
|
968
|
-
Money.from_fixnum(1, "USD").should == Money.new(1_00, "USD")
|
969
|
-
Money.from_fixnum(1, "TND").should == Money.new(1_000, "TND")
|
970
|
-
Money.from_fixnum(1, "CLP").should == Money.new(1, "CLP")
|
971
|
-
end
|
972
|
-
|
973
|
-
it "accepts a currency options" do
|
974
|
-
m = Money.from_fixnum(1)
|
975
|
-
m.currency.should == Money.default_currency
|
976
|
-
|
977
|
-
m = Money.from_fixnum(1, Money::Currency.wrap("EUR"))
|
978
|
-
m.currency.should == Money::Currency.wrap("EUR")
|
979
|
-
|
980
|
-
m = Money.from_fixnum(1, "EUR")
|
981
|
-
m.currency.should == Money::Currency.wrap("EUR")
|
982
|
-
end
|
983
|
-
end
|
984
|
-
|
985
|
-
describe "Money.from_float" do
|
986
|
-
it "converts given amount to cents" do
|
987
|
-
Money.from_float(1.2).should == Money.new(1_20)
|
988
|
-
Money.from_float(1.2).should == Money.new(1_20, "USD")
|
989
|
-
Money.from_float(1.2, "EUR").should == Money.new(1_20, "EUR")
|
990
|
-
end
|
991
|
-
|
992
|
-
it "should respect :subunit_to_unit currency property" do
|
993
|
-
Money.from_float(1.2, "USD").should == Money.new(1_20, "USD")
|
994
|
-
Money.from_float(1.2, "TND").should == Money.new(1_200, "TND")
|
995
|
-
Money.from_float(1.2, "CLP").should == Money.new(1, "CLP")
|
996
|
-
end
|
997
|
-
|
998
|
-
it "accepts a currency options" do
|
999
|
-
m = Money.from_float(1.2)
|
1000
|
-
m.currency.should == Money.default_currency
|
1001
|
-
|
1002
|
-
m = Money.from_float(1.2, Money::Currency.wrap("EUR"))
|
1003
|
-
m.currency.should == Money::Currency.wrap("EUR")
|
1004
|
-
|
1005
|
-
m = Money.from_float(1.2, "EUR")
|
1006
|
-
m.currency.should == Money::Currency.wrap("EUR")
|
1007
|
-
end
|
1008
|
-
end
|
1009
|
-
|
1010
|
-
describe "Money.from_bigdecimal" do
|
1011
|
-
it "converts given amount to cents" do
|
1012
|
-
Money.from_bigdecimal(BigDecimal.new("1")).should == Money.new(1_00)
|
1013
|
-
Money.from_bigdecimal(BigDecimal.new("1")).should == Money.new(1_00, "USD")
|
1014
|
-
Money.from_bigdecimal(BigDecimal.new("1"), "EUR").should == Money.new(1_00, "EUR")
|
1015
|
-
end
|
1016
|
-
|
1017
|
-
it "should respect :subunit_to_unit currency property" do
|
1018
|
-
Money.from_bigdecimal(BigDecimal.new("1"), "USD").should == Money.new(1_00, "USD")
|
1019
|
-
Money.from_bigdecimal(BigDecimal.new("1"), "TND").should == Money.new(1_000, "TND")
|
1020
|
-
Money.from_bigdecimal(BigDecimal.new("1"), "CLP").should == Money.new(1, "CLP")
|
1021
|
-
end
|
1022
|
-
|
1023
|
-
it "accepts a currency options" do
|
1024
|
-
m = Money.from_bigdecimal(BigDecimal.new("1"))
|
1025
|
-
m.currency.should == Money.default_currency
|
1026
|
-
|
1027
|
-
m = Money.from_bigdecimal(BigDecimal.new("1"), Money::Currency.wrap("EUR"))
|
1028
|
-
m.currency.should == Money::Currency.wrap("EUR")
|
1029
|
-
|
1030
|
-
m = Money.from_bigdecimal(BigDecimal.new("1"), "EUR")
|
1031
|
-
m.currency.should == Money::Currency.wrap("EUR")
|
1032
|
-
end
|
1033
|
-
end
|
1034
|
-
|
1035
|
-
describe "Money.from_numeric" do
|
1036
|
-
it "converts given amount to cents" do
|
1037
|
-
Money.from_numeric(1).should == Money.new(1_00)
|
1038
|
-
Money.from_numeric(1.0).should == Money.new(1_00)
|
1039
|
-
Money.from_numeric(BigDecimal.new("1")).should == Money.new(1_00)
|
1040
|
-
end
|
1041
|
-
|
1042
|
-
it "should raise ArgumentError with unsupported argument" do
|
1043
|
-
lambda { Money.from_numeric("100") }.should raise_error(ArgumentError)
|
1044
|
-
end
|
1045
|
-
|
1046
|
-
it "should optimize workload" do
|
1047
|
-
Money.should_receive(:from_fixnum).with(1, "USD").and_return(Money.new(1_00, "USD"))
|
1048
|
-
Money.from_numeric(1, "USD").should == Money.new(1_00, "USD")
|
1049
|
-
Money.should_receive(:from_bigdecimal).with(BigDecimal.new("1.0"), "USD").and_return(Money.new(1_00, "USD"))
|
1050
|
-
Money.from_numeric(1.0, "USD").should == Money.new(1_00, "USD")
|
1051
|
-
end
|
1052
|
-
|
1053
|
-
it "should respect :subunit_to_unit currency property" do
|
1054
|
-
Money.from_numeric(1, "USD").should == Money.new(1_00, "USD")
|
1055
|
-
Money.from_numeric(1, "TND").should == Money.new(1_000, "TND")
|
1056
|
-
Money.from_numeric(1, "CLP").should == Money.new(1, "CLP")
|
1057
|
-
end
|
1058
|
-
|
1059
|
-
it "accepts a bank option" do
|
1060
|
-
Money.from_numeric(1).should == Money.new(1_00)
|
1061
|
-
Money.from_numeric(1).should == Money.new(1_00, "USD")
|
1062
|
-
Money.from_numeric(1, "EUR").should == Money.new(1_00, "EUR")
|
1063
|
-
end
|
1064
|
-
|
1065
|
-
it "accepts a currency options" do
|
1066
|
-
m = Money.from_numeric(1)
|
1067
|
-
m.currency.should == Money.default_currency
|
1068
|
-
|
1069
|
-
m = Money.from_numeric(1, Money::Currency.wrap("EUR"))
|
1070
|
-
m.currency.should == Money::Currency.wrap("EUR")
|
1071
|
-
|
1072
|
-
m = Money.from_numeric(1, "EUR")
|
1073
|
-
m.currency.should == Money::Currency.wrap("EUR")
|
1074
|
-
end
|
1075
|
-
end
|
1076
|
-
|
1077
|
-
describe "split" do
|
1078
|
-
specify "#split needs at least one party" do
|
1079
|
-
lambda {Money.us_dollar(1).split(0)}.should raise_error(ArgumentError)
|
1080
|
-
lambda {Money.us_dollar(1).split(-1)}.should raise_error(ArgumentError)
|
1081
|
-
end
|
1082
|
-
|
1083
|
-
|
1084
|
-
specify "#gives 1 cent to both people if we start with 2" do
|
1085
|
-
Money.us_dollar(2).split(2).should == [Money.us_dollar(1), Money.us_dollar(1)]
|
1086
|
-
end
|
1087
|
-
|
1088
|
-
specify "#split may distribute no money to some parties if there isnt enough to go around" do
|
1089
|
-
Money.us_dollar(2).split(3).should == [Money.us_dollar(1), Money.us_dollar(1), Money.us_dollar(0)]
|
1090
|
-
end
|
1091
|
-
|
1092
|
-
specify "#split does not lose pennies" do
|
1093
|
-
Money.us_dollar(5).split(2).should == [Money.us_dollar(3), Money.us_dollar(2)]
|
1094
|
-
end
|
1095
|
-
|
1096
|
-
specify "#split a dollar" do
|
1097
|
-
moneys = Money.us_dollar(100).split(3)
|
1098
|
-
moneys[0].cents.should == 34
|
1099
|
-
moneys[1].cents.should == 33
|
1100
|
-
moneys[2].cents.should == 33
|
1101
|
-
end
|
1102
|
-
end
|
1103
|
-
|
1104
|
-
describe "allocation" do
|
1105
|
-
specify "#allocate takes no action when one gets all" do
|
1106
|
-
Money.us_dollar(005).allocate([1.0]).should == [Money.us_dollar(5)]
|
1107
|
-
end
|
1108
|
-
|
1109
|
-
specify "#allocate keeps currencies intact" do
|
1110
|
-
Money.ca_dollar(005).allocate([1]).should == [Money.ca_dollar(5)]
|
1111
|
-
end
|
1112
|
-
|
1113
|
-
specify "#allocate does not loose pennies" do
|
1114
|
-
moneys = Money.us_dollar(5).allocate([0.3,0.7])
|
1115
|
-
moneys[0].should == Money.us_dollar(2)
|
1116
|
-
moneys[1].should == Money.us_dollar(3)
|
1117
|
-
end
|
1118
|
-
|
1119
|
-
specify "#allocate does not loose pennies" do
|
1120
|
-
moneys = Money.us_dollar(100).allocate([0.333,0.333, 0.333])
|
1121
|
-
moneys[0].cents.should == 34
|
1122
|
-
moneys[1].cents.should == 33
|
1123
|
-
moneys[2].cents.should == 33
|
1124
|
-
end
|
1125
|
-
|
1126
|
-
specify "#allocate requires total to be less then 1" do
|
1127
|
-
lambda { Money.us_dollar(0.05).allocate([0.5,0.6]) }.should raise_error(ArgumentError)
|
1128
|
-
end
|
1129
|
-
end
|
1130
|
-
|
1131
|
-
describe "Money.add_rate" do
|
1132
|
-
it "saves rate into current bank" do
|
1133
|
-
Money.add_rate("EUR", "USD", 10)
|
1134
|
-
Money.new(10_00, "EUR").exchange_to("USD").should == Money.new(100_00, "USD")
|
1135
|
-
end
|
1136
|
-
end
|
1137
|
-
|
1138
|
-
|
1139
|
-
# Sets $VERBOSE to nil for the duration of the block and back to its original value afterwards.
|
1140
|
-
#
|
1141
|
-
# silence_warnings do
|
1142
|
-
# value = noisy_call # no warning voiced
|
1143
|
-
# end
|
1144
|
-
#
|
1145
|
-
# noisy_call # warning voiced
|
1146
|
-
def silence_warnings
|
1147
|
-
old_verbose, $VERBOSE = $VERBOSE, nil
|
1148
|
-
yield
|
1149
|
-
ensure
|
1150
|
-
$VERBOSE = old_verbose
|
1151
|
-
end
|
1152
|
-
|
1153
|
-
end
|
1154
|
-
|
1155
|
-
describe "Actions involving two Money objects" do
|
1156
|
-
describe "if the other Money object has the same currency" do
|
1157
|
-
specify "#<=> compares the two object amounts" do
|
1158
|
-
(Money.new(1_00, "USD") <=> Money.new(1_00, "USD")).should == 0
|
1159
|
-
(Money.new(1_00, "USD") <=> Money.new(99, "USD")).should > 0
|
1160
|
-
(Money.new(1_00, "USD") <=> Money.new(2_00, "USD")).should < 0
|
1161
|
-
end
|
1162
|
-
|
1163
|
-
specify "#+ adds other amount to current amount and returns a Money while retaining the currency" do
|
1164
|
-
(Money.new(10_00, "USD") + Money.new(90, "USD")).should == Money.new(10_90, "USD")
|
1165
|
-
end
|
1166
|
-
|
1167
|
-
specify "#- subtracts other amount from current amount and returns a Money while retaining the currency" do
|
1168
|
-
(Money.new(10_00, "USD") - Money.new(90, "USD")).should == Money.new(9_10, "USD")
|
1169
|
-
end
|
1170
|
-
|
1171
|
-
specify "#* should raise ArgumentError" do
|
1172
|
-
lambda { Money.new(10_00, "USD") * Money.new(2, "USD") }.should raise_error(ArgumentError)
|
1173
|
-
end
|
1174
|
-
|
1175
|
-
specify "#/ divides current amount by other amount and returns a Float" do
|
1176
|
-
(Money.new(10_00, "USD") / Money.new(100_00, "USD")).should == 0.1
|
1177
|
-
end
|
1178
|
-
end
|
1179
|
-
|
1180
|
-
describe "if the other Money object has a different currency" do
|
1181
|
-
specify "#<=> converts other object amount to current currency, then compares the two object amounts" do
|
1182
|
-
target = Money.new(200_00, "EUR")
|
1183
|
-
target.should_receive(:exchange_to).with(Money::Currency.new("USD")).and_return(Money.new(300_00, "USD"))
|
1184
|
-
(Money.new(100_00, "USD") <=> target).should < 0
|
1185
|
-
|
1186
|
-
target = Money.new(200_00, "EUR")
|
1187
|
-
target.should_receive(:exchange_to).with(Money::Currency.new("USD")).and_return(Money.new(100_00, "USD"))
|
1188
|
-
(Money.new(100_00, "USD") <=> target).should == 0
|
1189
|
-
|
1190
|
-
target = Money.new(200_00, "EUR")
|
1191
|
-
target.should_receive(:exchange_to).with(Money::Currency.new("USD")).and_return(Money.new(99_00, "USD"))
|
1192
|
-
(Money.new(100_00, "USD") <=> target).should > 0
|
1193
|
-
end
|
1194
|
-
|
1195
|
-
specify "#+ converts other object amount to current currency, then adds other amount to current amount and returns a Money" do
|
1196
|
-
other = Money.new(90, "EUR")
|
1197
|
-
other.should_receive(:exchange_to).with(Money::Currency.new("USD")).and_return(Money.new(9_00, "USD"))
|
1198
|
-
(Money.new(10_00, "USD") + other).should == Money.new(19_00, "USD")
|
1199
|
-
end
|
1200
|
-
|
1201
|
-
specify "#- converts other object amount to current currency, then subtracts other amount from current amount and returns a Money" do
|
1202
|
-
other = Money.new(90, "EUR")
|
1203
|
-
other.should_receive(:exchange_to).with(Money::Currency.new("USD")).and_return(Money.new(9_00, "USD"))
|
1204
|
-
(Money.new(10_00, "USD") - other).should == Money.new(1_00, "USD")
|
1205
|
-
end
|
1206
|
-
|
1207
|
-
specify "#* should raise ArgumentError" do
|
1208
|
-
lambda { Money.new(10_00, "USD") * Money.new(10, "EUR") }.should raise_error(ArgumentError)
|
1209
|
-
end
|
1210
|
-
|
1211
|
-
specify "#/ converts other object amount to current currency, then divides current amount by other amount and returns a Float" do
|
1212
|
-
other = Money.new(1000, "EUR")
|
1213
|
-
other.should_receive(:exchange_to).with(Money::Currency.new("USD")).and_return(Money.new(100_00, "USD"))
|
1214
|
-
(Money.new(10_00, "USD") / other).should == 0.1
|
1215
|
-
end
|
1216
|
-
end
|
1217
|
-
end
|
1218
|
-
|
1219
|
-
|
1220
|
-
describe "Money.parse" do
|
1221
|
-
|
1222
|
-
it "should be able to parse european-formatted inputs under 10EUR" do
|
1223
|
-
five_ninety_five = Money.new(595, 'EUR')
|
1224
|
-
|
1225
|
-
Money.parse('EUR 5,95').should == five_ninety_five
|
1226
|
-
#TODO: try and handle these
|
1227
|
-
#Money.parse('€5,95').should == five_ninety_five
|
1228
|
-
#Money.parse('$5.95').should == five_ninety_five
|
1229
|
-
end
|
1230
|
-
|
1231
|
-
it "should be able to parse european-formatted inputs with multiple thousands-seperators" do
|
1232
|
-
Money.parse('EUR 1.234.567,89').should == Money.new(123456789, 'EUR')
|
1233
|
-
Money.parse('EUR 1.111.234.567,89').should == Money.new(111123456789, 'EUR')
|
1234
|
-
end
|
1235
|
-
|
1236
|
-
it "should be able to parse USD-formatted inputs under $10" do
|
1237
|
-
five_ninety_five = Money.new(595, 'USD')
|
1238
|
-
|
1239
|
-
Money.parse(5.95).should == five_ninety_five
|
1240
|
-
Money.parse('5.95').should == five_ninety_five
|
1241
|
-
Money.parse('$5.95').should == five_ninety_five
|
1242
|
-
Money.parse("\n $5.95 \n").should == five_ninety_five
|
1243
|
-
Money.parse('$ 5.95').should == five_ninety_five
|
1244
|
-
Money.parse('$5.95 ea.').should == five_ninety_five
|
1245
|
-
Money.parse('$5.95, each').should == five_ninety_five
|
1246
|
-
end
|
1247
|
-
|
1248
|
-
it "should be able to parse USD-formatted inputs with multiple thousands-seperators" do
|
1249
|
-
Money.parse('1,234,567.89').should == Money.new(123456789, 'USD')
|
1250
|
-
Money.parse('1,111,234,567.89').should == Money.new(111123456789, 'USD')
|
1251
|
-
end
|
1252
|
-
|
1253
|
-
it "should not return a price if there is a price range" do
|
1254
|
-
lambda {Money.parse('$5.95-10.95')}.should raise_error ArgumentError
|
1255
|
-
lambda {Money.parse('$5.95 - 10.95')}.should raise_error ArgumentError
|
1256
|
-
lambda {Money.parse('$5.95 - $10.95')}.should raise_error ArgumentError
|
1257
|
-
end
|
1258
|
-
|
1259
|
-
it "should not return a price for completely invalid input" do
|
1260
|
-
# TODO: shouldn't these throw an error instead of being considered
|
1261
|
-
# equal to $0.0?
|
1262
|
-
empty_price = Money.new(0, 'USD')
|
1263
|
-
|
1264
|
-
Money.parse(nil).should == empty_price
|
1265
|
-
Money.parse('hellothere').should == empty_price
|
1266
|
-
Money.parse('').should == empty_price
|
1267
|
-
end
|
1268
|
-
end
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require "spec_helper"
|
4
|
+
|
5
|
+
describe Money do
|
6
|
+
|
7
|
+
describe "#new" do
|
8
|
+
it "rounds the given cents to an integer" do
|
9
|
+
Money.new(1.00, "USD").cents.should == 1
|
10
|
+
Money.new(1.01, "USD").cents.should == 1
|
11
|
+
Money.new(1.50, "USD").cents.should == 2
|
12
|
+
end
|
13
|
+
|
14
|
+
it "is associated to the singleton instance of Bank::VariableExchange by default" do
|
15
|
+
Money.new(0).bank.should be_equal(Money::Bank::VariableExchange.instance)
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
|
20
|
+
describe "#cents" do
|
21
|
+
it "returns the amount of cents passed to the constructor" do
|
22
|
+
Money.new(200_00, "USD").cents.should == 200_00
|
23
|
+
end
|
24
|
+
|
25
|
+
it "stores cents as an integer regardless of what is passed into the constructor" do
|
26
|
+
[ Money.new(100), 1.to_money, 1.00.to_money, BigDecimal('1.00').to_money ].each do |m|
|
27
|
+
m.cents.should == 100
|
28
|
+
m.cents.should be_an_instance_of(Fixnum)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
describe "#dollars" do
|
34
|
+
it "gets cents as dollars" do
|
35
|
+
Money.new_with_dollars(1).should == Money.new(100)
|
36
|
+
Money.new_with_dollars(1, "USD").should == Money.new(100, "USD")
|
37
|
+
Money.new_with_dollars(1, "EUR").should == Money.new(100, "EUR")
|
38
|
+
end
|
39
|
+
|
40
|
+
it "should respect :subunit_to_unit currency property" do
|
41
|
+
Money.new(1_00, "USD").dollars.should == 1
|
42
|
+
Money.new(1_000, "TND").dollars.should == 1
|
43
|
+
Money.new(1, "CLP").dollars.should == 1
|
44
|
+
end
|
45
|
+
|
46
|
+
it "should not loose precision" do
|
47
|
+
Money.new(100_37).dollars.should == 100.37
|
48
|
+
Money.new_with_dollars(100.37).dollars.should == 100.37
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
specify "#currency returns the currency passed to the constructor" do
|
53
|
+
Money.new(200_00, "USD").currency.should == Money::Currency.new("USD")
|
54
|
+
end
|
55
|
+
|
56
|
+
specify "#currency_string returns the iso_code of the currency object" do
|
57
|
+
Money.new(200_00, "USD").currency_as_string.should == Money::Currency.new("USD").to_s
|
58
|
+
Money.new(200_00, "USD").currency_as_string.should == "USD"
|
59
|
+
Money.new(200_00, "EUR").currency_as_string.should == "EUR"
|
60
|
+
Money.new(200_00, "YEN").currency_as_string.should == "YEN"
|
61
|
+
end
|
62
|
+
|
63
|
+
specify "#currency_string= set the currency object using the provided string" do
|
64
|
+
obj = Money.new(200_00, "USD")
|
65
|
+
obj.currency_as_string = "EUR"
|
66
|
+
obj.currency.should == Money::Currency.new("EUR")
|
67
|
+
obj.currency_as_string = "YEN"
|
68
|
+
obj.currency.should == Money::Currency.new("YEN")
|
69
|
+
obj.currency_as_string = "USD"
|
70
|
+
obj.currency.should == Money::Currency.new("USD")
|
71
|
+
end
|
72
|
+
|
73
|
+
|
74
|
+
specify "#exchange_to exchanges the amount via its exchange bank" do
|
75
|
+
money = Money.new(100_00, "USD")
|
76
|
+
money.bank.should_receive(:exchange_with).with(Money.new(100_00, Money::Currency.new("USD")), Money::Currency.new("EUR")).and_return(Money.new(200_00, Money::Currency.new('EUR')))
|
77
|
+
money.exchange_to("EUR")
|
78
|
+
end
|
79
|
+
|
80
|
+
specify "#exchange_to exchanges the amount properly" do
|
81
|
+
money = Money.new(100_00, "USD")
|
82
|
+
money.bank.should_receive(:exchange_with).with(Money.new(100_00, Money::Currency.new("USD")), Money::Currency.new("EUR")).and_return(Money.new(200_00, Money::Currency.new('EUR')))
|
83
|
+
money.exchange_to("EUR").should == Money.new(200_00, "EUR")
|
84
|
+
end
|
85
|
+
|
86
|
+
specify "#hash should return the same value for equal objects" do
|
87
|
+
Money.new(1_00, :eur).hash.should == Money.new(1_00, :eur).hash
|
88
|
+
Money.new(2_00, :usd).hash.should == Money.new(2_00, :usd).hash
|
89
|
+
Money.new(1_00, :eur).hash.should_not == Money.new(2_00, :eur).hash
|
90
|
+
Money.new(1_00, :eur).hash.should_not == Money.new(1_00, :usd).hash
|
91
|
+
Money.new(1_00, :eur).hash.should_not == Money.new(2_00, :usd).hash
|
92
|
+
end
|
93
|
+
|
94
|
+
specify "#hash can be used to return the intersection of Money object arrays" do
|
95
|
+
intersection = [Money.new(1_00, :eur), Money.new(1_00, :usd)] & [Money.new(1_00, :eur)]
|
96
|
+
intersection.should == [Money.new(1_00, :eur)]
|
97
|
+
end
|
98
|
+
|
99
|
+
|
100
|
+
specify "Money.to_s works" do
|
101
|
+
Money.new(10_00).to_s.should == "10.00"
|
102
|
+
Money.new(400_08).to_s.should == "400.08"
|
103
|
+
Money.new(-237_43).to_s.should == "-237.43"
|
104
|
+
end
|
105
|
+
|
106
|
+
specify "Money.to_s should respect :subunit_to_unit currency property" do
|
107
|
+
Money.new(10_00, "BHD").to_s.should == "1.000"
|
108
|
+
Money.new(10_00, "CNY").to_s.should == "10.00"
|
109
|
+
end
|
110
|
+
|
111
|
+
specify "Money.to_s shouldn't have decimal when :subunit_to_unit is 1" do
|
112
|
+
Money.new(10_00, "CLP").to_s.should == "1000"
|
113
|
+
end
|
114
|
+
|
115
|
+
specify "Money.to_s should work with :subunit_to_unit == 5" do
|
116
|
+
Money.new(10_00, "MGA").to_s.should == "200.0"
|
117
|
+
end
|
118
|
+
|
119
|
+
specify "Money.to_s should respect :decimal_mark" do
|
120
|
+
Money.new(10_00, "BRL").to_s.should == "10,00"
|
121
|
+
end
|
122
|
+
|
123
|
+
specify "Money.to_f works" do
|
124
|
+
Money.new(10_00).to_f.should == 10.0
|
125
|
+
end
|
126
|
+
|
127
|
+
specify "Money.to_f should respect :subunit_to_unit currency property" do
|
128
|
+
Money.new(10_00, "BHD").to_f.should == 1.0
|
129
|
+
end
|
130
|
+
|
131
|
+
specify "#symbol works as documented" do
|
132
|
+
currency = Money::Currency.new("EUR")
|
133
|
+
currency.should_receive(:symbol).and_return("€")
|
134
|
+
Money.empty(currency).symbol.should == "€"
|
135
|
+
|
136
|
+
currency = Money::Currency.new("EUR")
|
137
|
+
currency.should_receive(:symbol).and_return(nil)
|
138
|
+
Money.empty(currency).symbol.should == "¤"
|
139
|
+
end
|
140
|
+
|
141
|
+
describe "Money.empty" do
|
142
|
+
it "Money.empty creates a new Money object of 0 cents" do
|
143
|
+
Money.empty.should == Money.new(0)
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
describe "Money.ca_dollar" do
|
148
|
+
it "creates a new Money object of the given value in CAD" do
|
149
|
+
Money.ca_dollar(50).should == Money.new(50, "CAD")
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
describe "Money.us_dollar" do
|
154
|
+
it "creates a new Money object of the given value in USD" do
|
155
|
+
Money.us_dollar(50).should == Money.new(50, "USD")
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
describe "Money.euro" do
|
160
|
+
it "creates a new Money object of the given value in EUR" do
|
161
|
+
Money.euro(50).should == Money.new(50, "EUR")
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
|
166
|
+
describe "Money.new_with_dollars" do
|
167
|
+
it "converts given amount to cents" do
|
168
|
+
Money.new_with_dollars(1).should == Money.new(100)
|
169
|
+
Money.new_with_dollars(1, "USD").should == Money.new(100, "USD")
|
170
|
+
Money.new_with_dollars(1, "EUR").should == Money.new(100, "EUR")
|
171
|
+
end
|
172
|
+
|
173
|
+
it "should respect :subunit_to_unit currency property" do
|
174
|
+
Money.new_with_dollars(1, "USD").should == Money.new(1_00, "USD")
|
175
|
+
Money.new_with_dollars(1, "TND").should == Money.new(1_000, "TND")
|
176
|
+
Money.new_with_dollars(1, "CLP").should == Money.new(1, "CLP")
|
177
|
+
end
|
178
|
+
|
179
|
+
it "should not loose precision" do
|
180
|
+
Money.new_with_dollars(1234).cents.should == 1234_00
|
181
|
+
Money.new_with_dollars(100.37).cents.should == 100_37
|
182
|
+
Money.new_with_dollars(BigDecimal.new('1234')).cents.should == 1234_00
|
183
|
+
end
|
184
|
+
|
185
|
+
it "accepts a currency options" do
|
186
|
+
m = Money.new_with_dollars(1)
|
187
|
+
m.currency.should == Money.default_currency
|
188
|
+
|
189
|
+
m = Money.new_with_dollars(1, Money::Currency.wrap("EUR"))
|
190
|
+
m.currency.should == Money::Currency.wrap("EUR")
|
191
|
+
|
192
|
+
m = Money.new_with_dollars(1, "EUR")
|
193
|
+
m.currency.should == Money::Currency.wrap("EUR")
|
194
|
+
end
|
195
|
+
|
196
|
+
it "accepts a bank options" do
|
197
|
+
m = Money.new_with_dollars(1)
|
198
|
+
m.bank.should == Money.default_bank
|
199
|
+
|
200
|
+
m = Money.new_with_dollars(1, "EUR", bank = Object.new)
|
201
|
+
m.bank.should == bank
|
202
|
+
end
|
203
|
+
|
204
|
+
it "is associated to the singleton instance of Bank::VariableExchange by default" do
|
205
|
+
Money.new_with_dollars(0).bank.should be_equal(Money::Bank::VariableExchange.instance)
|
206
|
+
end
|
207
|
+
end
|
208
|
+
|
209
|
+
describe "split" do
|
210
|
+
specify "#split needs at least one party" do
|
211
|
+
lambda {Money.us_dollar(1).split(0)}.should raise_error(ArgumentError)
|
212
|
+
lambda {Money.us_dollar(1).split(-1)}.should raise_error(ArgumentError)
|
213
|
+
end
|
214
|
+
|
215
|
+
|
216
|
+
specify "#gives 1 cent to both people if we start with 2" do
|
217
|
+
Money.us_dollar(2).split(2).should == [Money.us_dollar(1), Money.us_dollar(1)]
|
218
|
+
end
|
219
|
+
|
220
|
+
specify "#split may distribute no money to some parties if there isnt enough to go around" do
|
221
|
+
Money.us_dollar(2).split(3).should == [Money.us_dollar(1), Money.us_dollar(1), Money.us_dollar(0)]
|
222
|
+
end
|
223
|
+
|
224
|
+
specify "#split does not lose pennies" do
|
225
|
+
Money.us_dollar(5).split(2).should == [Money.us_dollar(3), Money.us_dollar(2)]
|
226
|
+
end
|
227
|
+
|
228
|
+
specify "#split a dollar" do
|
229
|
+
moneys = Money.us_dollar(100).split(3)
|
230
|
+
moneys[0].cents.should == 34
|
231
|
+
moneys[1].cents.should == 33
|
232
|
+
moneys[2].cents.should == 33
|
233
|
+
end
|
234
|
+
end
|
235
|
+
|
236
|
+
describe "allocation" do
|
237
|
+
specify "#allocate takes no action when one gets all" do
|
238
|
+
Money.us_dollar(005).allocate([1.0]).should == [Money.us_dollar(5)]
|
239
|
+
end
|
240
|
+
|
241
|
+
specify "#allocate keeps currencies intact" do
|
242
|
+
Money.ca_dollar(005).allocate([1]).should == [Money.ca_dollar(5)]
|
243
|
+
end
|
244
|
+
|
245
|
+
specify "#allocate does not loose pennies" do
|
246
|
+
moneys = Money.us_dollar(5).allocate([0.3,0.7])
|
247
|
+
moneys[0].should == Money.us_dollar(2)
|
248
|
+
moneys[1].should == Money.us_dollar(3)
|
249
|
+
end
|
250
|
+
|
251
|
+
specify "#allocate does not loose pennies" do
|
252
|
+
moneys = Money.us_dollar(100).allocate([0.333,0.333, 0.333])
|
253
|
+
moneys[0].cents.should == 34
|
254
|
+
moneys[1].cents.should == 33
|
255
|
+
moneys[2].cents.should == 33
|
256
|
+
end
|
257
|
+
|
258
|
+
specify "#allocate requires total to be less then 1" do
|
259
|
+
lambda { Money.us_dollar(0.05).allocate([0.5,0.6]) }.should raise_error(ArgumentError)
|
260
|
+
end
|
261
|
+
end
|
262
|
+
|
263
|
+
describe "Money.add_rate" do
|
264
|
+
it "saves rate into current bank" do
|
265
|
+
Money.add_rate("EUR", "USD", 10)
|
266
|
+
Money.new(10_00, "EUR").exchange_to("USD").should == Money.new(100_00, "USD")
|
267
|
+
end
|
268
|
+
end
|
269
|
+
|
270
|
+
end
|
271
|
+
|