money 6.5.1 → 6.16.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +209 -5
  3. data/LICENSE +18 -16
  4. data/README.md +321 -70
  5. data/config/currency_backwards_compatible.json +65 -0
  6. data/config/currency_iso.json +280 -94
  7. data/config/currency_non_iso.json +101 -3
  8. data/lib/money/bank/base.rb +1 -3
  9. data/lib/money/bank/variable_exchange.rb +88 -96
  10. data/lib/money/currency/heuristics.rb +1 -143
  11. data/lib/money/currency/loader.rb +15 -13
  12. data/lib/money/currency.rb +98 -81
  13. data/lib/money/locale_backend/base.rb +7 -0
  14. data/lib/money/locale_backend/currency.rb +11 -0
  15. data/lib/money/locale_backend/errors.rb +6 -0
  16. data/lib/money/locale_backend/i18n.rb +25 -0
  17. data/lib/money/locale_backend/legacy.rb +28 -0
  18. data/lib/money/money/allocation.rb +46 -0
  19. data/lib/money/money/arithmetic.rb +97 -52
  20. data/lib/money/money/constructors.rb +5 -6
  21. data/lib/money/money/formatter.rb +399 -0
  22. data/lib/money/money/formatting_rules.rb +142 -0
  23. data/lib/money/money/locale_backend.rb +22 -0
  24. data/lib/money/money.rb +268 -194
  25. data/lib/money/rates_store/memory.rb +120 -0
  26. data/lib/money/version.rb +1 -1
  27. data/money.gemspec +15 -20
  28. metadata +36 -59
  29. data/.coveralls.yml +0 -1
  30. data/.gitignore +0 -22
  31. data/.travis.yml +0 -13
  32. data/AUTHORS +0 -116
  33. data/CONTRIBUTING.md +0 -17
  34. data/Gemfile +0 -7
  35. data/Rakefile +0 -17
  36. data/lib/money/money/formatting.rb +0 -386
  37. data/spec/bank/base_spec.rb +0 -77
  38. data/spec/bank/single_currency_spec.rb +0 -11
  39. data/spec/bank/variable_exchange_spec.rb +0 -275
  40. data/spec/currency/heuristics_spec.rb +0 -84
  41. data/spec/currency_spec.rb +0 -321
  42. data/spec/money/arithmetic_spec.rb +0 -568
  43. data/spec/money/constructors_spec.rb +0 -75
  44. data/spec/money/formatting_spec.rb +0 -667
  45. data/spec/money_spec.rb +0 -745
  46. data/spec/spec_helper.rb +0 -23
data/spec/money_spec.rb DELETED
@@ -1,745 +0,0 @@
1
- # encoding: utf-8
2
-
3
- require "spec_helper"
4
-
5
- describe Money do
6
- describe ".new" do
7
- let(:initializing_value) { 1 }
8
- subject(:money) { Money.new(initializing_value) }
9
-
10
- it "should be an instance of `Money::Bank::VariableExchange`" do
11
- expect(money.bank).to be Money::Bank::VariableExchange.instance
12
- end
13
-
14
- context 'given the initializing value is an integer' do
15
- let(:initializing_value) { Integer(1) }
16
- it 'stores the integer as the number of cents' do
17
- expect(money.cents).to eq initializing_value
18
- end
19
- end
20
-
21
- context 'given the initializing value is a float' do
22
- context 'and the value is 1.00' do
23
- let(:initializing_value) { 1.00 }
24
- it { is_expected.to eq Money.new(1) }
25
- end
26
-
27
- context 'and the value is 1.01' do
28
- let(:initializing_value) { 1.01 }
29
- it { is_expected.to eq Money.new(1) }
30
- end
31
-
32
- context 'and the value is 1.50' do
33
- let(:initializing_value) { 1.50 }
34
- it { is_expected.to eq Money.new(2) }
35
- end
36
- end
37
-
38
- context 'given the initializing value is a rational' do
39
- let(:initializing_value) { Rational(1) }
40
- it { is_expected.to eq Money.new(1) }
41
- end
42
-
43
- context 'given the initializing value is money' do
44
- let(:initializing_value) { Money.new(1_00, Money::Currency.new('NZD')) }
45
- it { is_expected.to eq initializing_value }
46
- end
47
-
48
- context "given the initializing value doesn't respond to .to_d" do
49
- let(:initializing_value) { :"1" }
50
- it { is_expected.to eq Money.new(1) }
51
- end
52
-
53
- context 'given a currency is not provided' do
54
- subject(:money) { Money.new(initializing_value) }
55
-
56
- it "should have the default currency" do
57
- expect(money.currency).to eq Money.default_currency
58
- end
59
- end
60
-
61
- context 'given a currency is provided' do
62
- subject(:money) { Money.new(initializing_value, currency) }
63
-
64
- context 'and the currency is NZD' do
65
- let(:currency) { Money::Currency.new('NZD') }
66
-
67
- it "should have NZD currency" do
68
- expect(money.currency).to eq Money::Currency.new('NZD')
69
- end
70
- end
71
-
72
- context 'and the currency is nil' do
73
- let(:currency) { nil }
74
-
75
- it "should have the default currency" do
76
- expect(money.currency).to eq Money.default_currency
77
- end
78
- end
79
- end
80
-
81
- context "infinite_precision = true" do
82
- before { expect(Money).to receive(:infinite_precision).and_return(true) }
83
- context 'given the initializing value is 1.50' do
84
- let(:initializing_value) { 1.50 }
85
-
86
- it "should have the correct cents" do
87
- expect(money.cents).to eq BigDecimal('1.50')
88
- end
89
- end
90
- end
91
- end
92
-
93
- describe ".add_rate" do
94
- before do
95
- @default_bank = Money.default_bank
96
- Money.default_bank = Money::Bank::VariableExchange.new
97
- end
98
-
99
- after do
100
- Money.default_bank = @default_bank
101
- end
102
-
103
- it "saves rate into current bank" do
104
- Money.add_rate("EUR", "USD", 10)
105
- expect(Money.new(10_00, "EUR").exchange_to("USD")).to eq Money.new(100_00, "USD")
106
- end
107
- end
108
-
109
- describe ".disallow_currency_conversions!" do
110
- before do
111
- @default_bank = Money.default_bank
112
- end
113
-
114
- after do
115
- Money.default_bank = @default_bank
116
- end
117
-
118
- it "disallows conversions when doing money arithmetic" do
119
- Money.disallow_currency_conversion!
120
- expect { Money.new(100, "USD") + Money.new(100, "EUR") }.to raise_exception(Money::Bank::DifferentCurrencyError)
121
- end
122
- end
123
-
124
- %w[cents pence].each do |units|
125
- describe "##{units}" do
126
- it "is a synonym of #fractional" do
127
- expectation = Money.new(0)
128
- def expectation.fractional
129
- "expectation"
130
- end
131
- expect(expectation.cents).to eq "expectation"
132
- end
133
- end
134
- end
135
-
136
- describe "#fractional" do
137
- it "returns the amount in fractional unit" do
138
- expect(Money.new(1_00).fractional).to eq 1_00
139
- end
140
-
141
- it "stores fractional as an integer regardless of what is passed into the constructor" do
142
- m = Money.new(100)
143
- expect(m.fractional).to eq 100
144
- expect(m.fractional).to be_a(Fixnum)
145
- end
146
-
147
- context "loading a serialized Money via YAML" do
148
-
149
- let(:serialized) { <<YAML
150
- !ruby/object:Money
151
- fractional: 249.5
152
- currency: !ruby/object:Money::Currency
153
- id: :eur
154
- priority: 2
155
- iso_code: EUR
156
- name: Euro
157
- symbol: €
158
- alternate_symbols: []
159
- subunit: Cent
160
- subunit_to_unit: 100
161
- symbol_first: true
162
- html_entity: ! '&#x20AC;'
163
- decimal_mark: ! ','
164
- thousands_separator: .
165
- iso_numeric: '978'
166
- mutex: !ruby/object:Mutex {}
167
- last_updated: 2012-11-23 20:41:47.454438399 +02:00
168
- YAML
169
- }
170
-
171
- it "uses BigDecimal when rounding" do
172
- m = YAML::load serialized
173
- expect(m).to be_a(Money)
174
- expect(m.class.infinite_precision).to be false
175
- expect(m.fractional).to eq 250 # 249.5 rounded up
176
- expect(m.fractional).to be_a(Integer)
177
- end
178
-
179
- context "with infinite_precision" do
180
- before do
181
- Money.infinite_precision = true
182
- end
183
-
184
- after do
185
- Money.infinite_precision = false
186
- end
187
-
188
- it "is a BigDecimal" do
189
- money = YAML::load serialized
190
- expect(money.fractional).to be_a BigDecimal
191
- end
192
- end
193
- end
194
-
195
- context "user changes rounding_mode" do
196
- after do
197
- Money.rounding_mode = BigDecimal::ROUND_HALF_EVEN
198
- end
199
-
200
- context "with the setter" do
201
- it "respects the rounding_mode" do
202
- Money.rounding_mode = BigDecimal::ROUND_DOWN
203
- expect(Money.new(1.9).fractional).to eq 1
204
-
205
- Money.rounding_mode = BigDecimal::ROUND_UP
206
- expect(Money.new(1.1).fractional).to eq 2
207
- end
208
- end
209
-
210
- context "with a block" do
211
- it "respects the rounding_mode" do
212
- expect(Money.rounding_mode(BigDecimal::ROUND_DOWN) do
213
- Money.new(1.9).fractional
214
- end).to eq 1
215
-
216
- expect(Money.rounding_mode(BigDecimal::ROUND_UP) do
217
- Money.new(1.1).fractional
218
- end).to eq 2
219
-
220
- expect(Money.rounding_mode).to eq BigDecimal::ROUND_HALF_EVEN
221
- end
222
-
223
- it "works for multiplication within a block" do
224
- Money.rounding_mode(BigDecimal::ROUND_DOWN) do
225
- expect((Money.new(1_00) * "0.019".to_d).fractional).to eq 1
226
- end
227
-
228
- Money.rounding_mode(BigDecimal::ROUND_UP) do
229
- expect((Money.new(1_00) * "0.011".to_d).fractional).to eq 2
230
- end
231
-
232
- expect(Money.rounding_mode).to eq BigDecimal::ROUND_HALF_EVEN
233
- end
234
- end
235
- end
236
-
237
- context "infinite_precision = true" do
238
- before do
239
- Money.infinite_precision = true
240
- end
241
-
242
- after do
243
- Money.infinite_precision = false
244
- end
245
-
246
- it "returns the amount in fractional unit" do
247
- expect(Money.new(1_00).fractional).to eq BigDecimal("100")
248
- end
249
-
250
- it "stores in fractional unit as an integer regardless of what is passed into the constructor" do
251
- m = Money.new(100)
252
- expect(m.fractional).to eq BigDecimal("100")
253
- expect(m.fractional).to be_a(BigDecimal)
254
- end
255
- end
256
- end
257
-
258
- describe "#round_to_nearest_cash_value" do
259
- it "rounds to the nearest possible cash value" do
260
- money = Money.new(2350, "AED")
261
- expect(money.round_to_nearest_cash_value).to eq 2350
262
-
263
- money = Money.new(-2350, "AED")
264
- expect(money.round_to_nearest_cash_value).to eq(-2350)
265
-
266
- money = Money.new(2213, "AED")
267
- expect(money.round_to_nearest_cash_value).to eq 2225
268
-
269
- money = Money.new(-2213, "AED")
270
- expect(money.round_to_nearest_cash_value).to eq(-2225)
271
-
272
- money = Money.new(2212, "AED")
273
- expect(money.round_to_nearest_cash_value).to eq 2200
274
-
275
- money = Money.new(-2212, "AED")
276
- expect(money.round_to_nearest_cash_value).to eq(-2200)
277
-
278
- money = Money.new(178, "CHF")
279
- expect(money.round_to_nearest_cash_value).to eq 180
280
-
281
- money = Money.new(-178, "CHF")
282
- expect(money.round_to_nearest_cash_value).to eq(-180)
283
-
284
- money = Money.new(177, "CHF")
285
- expect(money.round_to_nearest_cash_value).to eq 175
286
-
287
- money = Money.new(-177, "CHF")
288
- expect(money.round_to_nearest_cash_value).to eq(-175)
289
-
290
- money = Money.new(175, "CHF")
291
- expect(money.round_to_nearest_cash_value).to eq 175
292
-
293
- money = Money.new(-175, "CHF")
294
- expect(money.round_to_nearest_cash_value).to eq(-175)
295
-
296
- money = Money.new(299, "USD")
297
- expect(money.round_to_nearest_cash_value).to eq 299
298
-
299
- money = Money.new(-299, "USD")
300
- expect(money.round_to_nearest_cash_value).to eq(-299)
301
-
302
- money = Money.new(300, "USD")
303
- expect(money.round_to_nearest_cash_value).to eq 300
304
-
305
- money = Money.new(-300, "USD")
306
- expect(money.round_to_nearest_cash_value).to eq(-300)
307
-
308
- money = Money.new(301, "USD")
309
- expect(money.round_to_nearest_cash_value).to eq 301
310
-
311
- money = Money.new(-301, "USD")
312
- expect(money.round_to_nearest_cash_value).to eq(-301)
313
- end
314
-
315
- it "raises an exception if smallest denomination is not defined" do
316
- money = Money.new(100, "XAG")
317
- expect {money.round_to_nearest_cash_value}.to raise_error(Money::UndefinedSmallestDenomination)
318
- end
319
-
320
- it "returns a Fixnum when infinite_precision is not set" do
321
- money = Money.new(100, "USD")
322
- expect(money.round_to_nearest_cash_value).to be_a Fixnum
323
- end
324
-
325
- context "with infinite_precision" do
326
- before do
327
- Money.infinite_precision = true
328
- end
329
-
330
- after do
331
- Money.infinite_precision = false
332
- end
333
-
334
- it "returns a BigDecimal" do
335
- money = Money.new(100, "EUR")
336
- expect(money.round_to_nearest_cash_value).to be_a BigDecimal
337
- end
338
- end
339
- end
340
-
341
- describe "#amount" do
342
- it "returns the amount of cents as dollars" do
343
- expect(Money.new(1_00).amount).to eq 1
344
- end
345
-
346
- it "respects :subunit_to_unit currency property" do
347
- expect(Money.new(1_00, "USD").amount).to eq 1
348
- expect(Money.new(1_000, "TND").amount).to eq 1
349
- expect(Money.new(1, "VUV").amount).to eq 1
350
- end
351
-
352
- it "does not loose precision" do
353
- expect(Money.new(100_37).amount).to eq 100.37
354
- end
355
-
356
- it 'produces a BigDecimal' do
357
- expect(Money.new(1_00).amount).to be_a BigDecimal
358
- end
359
- end
360
-
361
- describe "#dollars" do
362
- it "is synonym of #amount" do
363
- m = Money.new(0)
364
-
365
- # Make a small expectation
366
- def m.amount
367
- 5
368
- end
369
-
370
- expect(m.dollars).to eq 5
371
- end
372
- end
373
-
374
- describe "#currency" do
375
- it "returns the currency object" do
376
- expect(Money.new(1_00, "USD").currency).to eq Money::Currency.new("USD")
377
- end
378
- end
379
-
380
- describe "#currency_as_string" do
381
- it "returns the iso_code of the currency object" do
382
- expect(Money.new(1_00, "USD").currency_as_string).to eq "USD"
383
- expect(Money.new(1_00, "EUR").currency_as_string).to eq "EUR"
384
- end
385
- end
386
-
387
- describe "#currency_as_string=" do
388
- it "sets the currency object using the provided string" do
389
- money = Money.new(100_00, "USD")
390
- money.currency_as_string = "EUR"
391
- expect(money.currency).to eq Money::Currency.new("EUR")
392
- money.currency_as_string = "YEN"
393
- expect(money.currency).to eq Money::Currency.new("YEN")
394
- end
395
- end
396
-
397
- describe "#hash=" do
398
- it "returns the same value for equal objects" do
399
- expect(Money.new(1_00, "EUR").hash).to eq Money.new(1_00, "EUR").hash
400
- expect(Money.new(2_00, "USD").hash).to eq Money.new(2_00, "USD").hash
401
- expect(Money.new(1_00, "EUR").hash).not_to eq Money.new(2_00, "EUR").hash
402
- expect(Money.new(1_00, "EUR").hash).not_to eq Money.new(1_00, "USD").hash
403
- expect(Money.new(1_00, "EUR").hash).not_to eq Money.new(2_00, "USD").hash
404
- end
405
-
406
- it "can be used to return the intersection of Money object arrays" do
407
- intersection = [Money.new(1_00, "EUR"), Money.new(1_00, "USD")] & [Money.new(1_00, "EUR")]
408
- expect(intersection).to eq [Money.new(1_00, "EUR")]
409
- end
410
- end
411
-
412
- describe "#symbol" do
413
- it "works as documented" do
414
- currency = Money::Currency.new("EUR")
415
- expect(currency).to receive(:symbol).and_return("€")
416
- expect(Money.new(0, currency).symbol).to eq "€"
417
-
418
- currency = Money::Currency.new("EUR")
419
- expect(currency).to receive(:symbol).and_return(nil)
420
- expect(Money.new(0, currency).symbol).to eq "¤"
421
- end
422
- end
423
-
424
- describe "#to_s" do
425
- it "works as documented" do
426
- expect(Money.new(10_00).to_s).to eq "10.00"
427
- expect(Money.new(400_08).to_s).to eq "400.08"
428
- expect(Money.new(-237_43).to_s).to eq "-237.43"
429
- end
430
-
431
- it "respects :subunit_to_unit currency property" do
432
- expect(Money.new(10_00, "BHD").to_s).to eq "1.000"
433
- expect(Money.new(10_00, "CNY").to_s).to eq "10.00"
434
- end
435
-
436
- it "does not have decimal when :subunit_to_unit == 1" do
437
- expect(Money.new(10_00, "VUV").to_s).to eq "1000"
438
- end
439
-
440
- it "does not work when :subunit_to_unit == 5" do
441
- expect(Money.new(10_00, "MGA").to_s).to eq "200.0"
442
- end
443
-
444
- it "respects :decimal_mark" do
445
- expect(Money.new(10_00, "BRL").to_s).to eq "10,00"
446
- end
447
-
448
- context "infinite_precision = true" do
449
- before do
450
- Money.infinite_precision = true
451
- end
452
-
453
- after do
454
- Money.infinite_precision = false
455
- end
456
-
457
- it "shows fractional cents" do
458
- expect(Money.new(1.05, "USD").to_s).to eq "0.0105"
459
- end
460
-
461
- it "suppresses fractional cents when there is none" do
462
- expect(Money.new(1.0, "USD").to_s).to eq "0.01"
463
- end
464
-
465
- it "shows fractional if needed when :subunut_to_unit == 1" do
466
- expect(Money.new(10_00.1, "VUV").to_s).to eq "1000.1"
467
- end
468
- end
469
- end
470
-
471
- describe "#to_d" do
472
- it "works as documented" do
473
- decimal = Money.new(10_00).to_d
474
- expect(decimal).to be_a(BigDecimal)
475
- expect(decimal).to eq 10.0
476
- end
477
-
478
- it "respects :subunit_to_unit currency property" do
479
- decimal = Money.new(10_00, "BHD").to_d
480
- expect(decimal).to be_a(BigDecimal)
481
- expect(decimal).to eq 1.0
482
- end
483
-
484
- it "works with float :subunit_to_unit currency property" do
485
- money = Money.new(10_00, "BHD")
486
- allow(money.currency).to receive(:subunit_to_unit).and_return(1000.0)
487
-
488
- decimal = money.to_d
489
- expect(decimal).to be_a(BigDecimal)
490
- expect(decimal).to eq 1.0
491
- end
492
- end
493
-
494
- describe "#to_f" do
495
- it "works as documented" do
496
- expect(Money.new(10_00).to_f).to eq 10.0
497
- end
498
-
499
- it "respects :subunit_to_unit currency property" do
500
- expect(Money.new(10_00, "BHD").to_f).to eq 1.0
501
- end
502
- end
503
-
504
- describe "#to_i" do
505
- it "works as documented" do
506
- expect(Money.new(10_00).to_i).to eq 10
507
- end
508
-
509
- it "respects :subunit_to_unit currency property" do
510
- expect(Money.new(10_00, "BHD").to_i).to eq 1
511
- end
512
- end
513
-
514
- describe "#to_money" do
515
- it "works as documented" do
516
- money = Money.new(10_00, "DKK")
517
- expect(money).to eq money.to_money
518
- expect(money).to eq money.to_money("DKK")
519
- expect(money.bank).to receive(:exchange_with).with(Money.new(10_00, Money::Currency.new("DKK")), Money::Currency.new("EUR")).and_return(Money.new(200_00, Money::Currency.new('EUR')))
520
- expect(money.to_money("EUR")).to eq Money.new(200_00, "EUR")
521
- end
522
- end
523
-
524
- describe "#exchange_to" do
525
- it "exchanges the amount via its exchange bank" do
526
- money = Money.new(100_00, "USD")
527
- expect(money.bank).to 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')))
528
- money.exchange_to("EUR")
529
- end
530
-
531
- it "exchanges the amount properly" do
532
- money = Money.new(100_00, "USD")
533
- expect(money.bank).to 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')))
534
- expect(money.exchange_to("EUR")).to eq Money.new(200_00, "EUR")
535
- end
536
-
537
- it 'uses the block given as rounding method' do
538
- money = Money.new(100_00, 'USD')
539
- expect(money.bank).to receive(:exchange_with).and_yield(300_00)
540
- expect { |block| money.exchange_to(Money::Currency.new('EUR'), &block) }.to yield_successive_args(300_00)
541
- end
542
-
543
- it "does no exchange when the currencies are the same" do
544
- money = Money.new(100_00, "USD")
545
- expect(money.bank).to_not receive(:exchange_with)
546
- expect(money.exchange_to("USD")).to eq money
547
- end
548
- end
549
-
550
- describe "#allocate" do
551
- it "takes no action when one gets all" do
552
- expect(Money.us_dollar(005).allocate([1.0])).to eq [Money.us_dollar(5)]
553
- end
554
-
555
- it "keeps currencies intact" do
556
- expect(Money.ca_dollar(005).allocate([1])).to eq [Money.ca_dollar(5)]
557
- end
558
-
559
- it "does not loose pennies" do
560
- moneys = Money.us_dollar(5).allocate([0.3, 0.7])
561
- expect(moneys[0]).to eq Money.us_dollar(2)
562
- expect(moneys[1]).to eq Money.us_dollar(3)
563
- end
564
-
565
- it "does not loose pennies" do
566
- moneys = Money.us_dollar(100).allocate([0.333, 0.333, 0.333])
567
- expect(moneys[0].cents).to eq 34
568
- expect(moneys[1].cents).to eq 33
569
- expect(moneys[2].cents).to eq 33
570
- end
571
-
572
- it "requires total to be less then 1" do
573
- expect { Money.us_dollar(0.05).allocate([0.5, 0.6]) }.to raise_error(ArgumentError)
574
- end
575
-
576
- context "infinite_precision = true" do
577
- before do
578
- Money.infinite_precision = true
579
- end
580
-
581
- after do
582
- Money.infinite_precision = false
583
- end
584
-
585
- it "allows for fractional cents allocation" do
586
- one_third = BigDecimal("1") / BigDecimal("3")
587
-
588
- moneys = Money.new(100).allocate([one_third, one_third, one_third])
589
- expect(moneys[0].cents).to eq one_third * BigDecimal("100")
590
- expect(moneys[1].cents).to eq one_third * BigDecimal("100")
591
- expect(moneys[2].cents).to eq one_third * BigDecimal("100")
592
- end
593
- end
594
- end
595
-
596
- describe "#split" do
597
- it "needs at least one party" do
598
- expect { Money.us_dollar(1).split(0) }.to raise_error(ArgumentError)
599
- expect { Money.us_dollar(1).split(-1) }.to raise_error(ArgumentError)
600
- end
601
-
602
- it "gives 1 cent to both people if we start with 2" do
603
- expect(Money.us_dollar(2).split(2)).to eq [Money.us_dollar(1), Money.us_dollar(1)]
604
- end
605
-
606
- it "may distribute no money to some parties if there isnt enough to go around" do
607
- expect(Money.us_dollar(2).split(3)).to eq [Money.us_dollar(1), Money.us_dollar(1), Money.us_dollar(0)]
608
- end
609
-
610
- it "does not lose pennies" do
611
- expect(Money.us_dollar(5).split(2)).to eq [Money.us_dollar(3), Money.us_dollar(2)]
612
- end
613
-
614
- it "splits a dollar" do
615
- moneys = Money.us_dollar(100).split(3)
616
- expect(moneys[0].cents).to eq 34
617
- expect(moneys[1].cents).to eq 33
618
- expect(moneys[2].cents).to eq 33
619
- end
620
-
621
- context "infinite_precision = true" do
622
- before do
623
- Money.infinite_precision = true
624
- end
625
-
626
- after do
627
- Money.infinite_precision = false
628
- end
629
-
630
- it "allows for splitting by fractional cents" do
631
- thirty_three_and_one_third = BigDecimal("100") / BigDecimal("3")
632
-
633
- moneys = Money.new(100).split(3)
634
- expect(moneys[0].cents).to eq thirty_three_and_one_third
635
- expect(moneys[1].cents).to eq thirty_three_and_one_third
636
- expect(moneys[2].cents).to eq thirty_three_and_one_third
637
- end
638
- end
639
- end
640
-
641
- describe "#round" do
642
-
643
- let(:money) { Money.new(15.75, 'NZD') }
644
- subject(:rounded) { money.round }
645
-
646
- context "without infinite_precision" do
647
- before do
648
- Money.infinite_precision = false
649
- end
650
-
651
- it "returns self (as it is already rounded)" do
652
- rounded = money.round
653
- expect(rounded).to be money
654
- expect(rounded.cents).to eq 16
655
- end
656
- end
657
-
658
- context "with infinite_precision" do
659
- before do
660
- Money.infinite_precision = true
661
- end
662
-
663
- after do
664
- Money.infinite_precision = false
665
- end
666
-
667
- it "returns a different money" do
668
- expect(rounded).not_to be money
669
- end
670
-
671
- it "rounds the cents" do
672
- expect(rounded.cents).to eq 16
673
- end
674
-
675
- it "maintains the currency" do
676
- expect(rounded.currency).to eq Money::Currency.new('NZD')
677
- end
678
-
679
- it "uses a provided rounding strategy" do
680
- rounded = money.round(BigDecimal::ROUND_DOWN)
681
- expect(rounded.cents).to eq 15
682
- end
683
- end
684
- end
685
-
686
- describe "inheritance" do
687
- it "allows inheritance" do
688
- # TypeError:
689
- # wrong argument type nil (expected Fixnum)
690
- # ./lib/money/money.rb:63:in `round'
691
- # ./lib/money/money.rb:63:in `fractional'
692
- # ./lib/money/money/arithmetic.rb:115:in `-'
693
- MoneyChild = Class.new(Money)
694
- expect(MoneyChild.new(1000) - Money.new(500)).to eq Money.new(500)
695
- end
696
- end
697
-
698
- describe "#as_*" do
699
- before do
700
- Money.default_bank = Money::Bank::VariableExchange.new
701
- Money.add_rate("EUR", "USD", 1)
702
- Money.add_rate("EUR", "CAD", 1)
703
- Money.add_rate("USD", "EUR", 1)
704
- end
705
-
706
- after do
707
- Money.default_bank = Money::Bank::VariableExchange.instance
708
- end
709
-
710
- specify "as_us_dollar converts Money object to USD" do
711
- obj = Money.new(1, "EUR")
712
- expect(obj.as_us_dollar).to eq Money.new(1, "USD")
713
- end
714
-
715
- specify "as_ca_dollar converts Money object to CAD" do
716
- obj = Money.new(1, "EUR")
717
- expect(obj.as_ca_dollar).to eq Money.new(1, "CAD")
718
- end
719
-
720
- specify "as_euro converts Money object to EUR" do
721
- obj = Money.new(1, "USD")
722
- expect(obj.as_euro).to eq Money.new(1, "EUR")
723
- end
724
- end
725
-
726
- describe ".default_currency" do
727
- before do
728
- @default_currency = Money.default_currency
729
- end
730
-
731
- after do
732
- Money.default_currency = @default_currency
733
- end
734
-
735
- it "accepts a lambda" do
736
- Money.default_currency = lambda { :eur }
737
- expect(Money.default_currency).to eq Money::Currency.new(:eur)
738
- end
739
-
740
- it "accepts a symbol" do
741
- Money.default_currency = :eur
742
- expect(Money.default_currency).to eq Money::Currency.new(:eur)
743
- end
744
- end
745
- end