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
@@ -1,568 +0,0 @@
1
- # encoding: utf-8
2
-
3
- require "spec_helper"
4
-
5
- describe Money do
6
- describe "-@" do
7
- it "changes the sign of a number" do
8
- expect((- Money.new(0))).to eq Money.new(0)
9
- expect((- Money.new(1))).to eq Money.new(-1)
10
- expect((- Money.new(-1))).to eq Money.new(1)
11
- end
12
- end
13
-
14
- describe "#==" do
15
- it "returns true if and only if their amount and currency are equal" do
16
- expect(Money.new(1_00, "USD")).to eq Money.new(1_00, "USD")
17
- expect(Money.new(1_00, "USD")).not_to eq Money.new(1_00, "EUR")
18
- expect(Money.new(1_00, "USD")).not_to eq Money.new(2_00, "USD")
19
- expect(Money.new(1_00, "USD")).not_to eq Money.new(99_00, "EUR")
20
- end
21
-
22
- it "returns false if used to compare with an object that doesn't respond to #to_money" do
23
- expect(Money.new(1_00, "USD")).not_to eq Object.new
24
- expect(Money.new(1_00, "USD")).not_to eq Class
25
- expect(Money.new(1_00, "USD")).not_to eq Kernel
26
- expect(Money.new(1_00, "USD")).not_to eq /foo/
27
- expect(Money.new(1_00, "USD")).not_to eq nil
28
- end
29
-
30
- it "can be used to compare with an object that responds to #to_money" do
31
- klass = Class.new do
32
- def initialize(money)
33
- @money = money
34
- end
35
-
36
- def to_money
37
- @money
38
- end
39
- end
40
-
41
- expect(Money.new(1_00, "USD")).to eq klass.new(Money.new(1_00, "USD"))
42
- expect(Money.new(2_50, "USD")).to eq klass.new(Money.new(2_50, "USD"))
43
- expect(Money.new(2_50, "USD")).not_to eq klass.new(Money.new(3_00, "USD"))
44
- expect(Money.new(1_00, "GBP")).not_to eq klass.new(Money.new(1_00, "USD"))
45
- end
46
- end
47
-
48
- describe "#eql?" do
49
- it "returns true if and only if their amount and currency are equal" do
50
- expect(Money.new(1_00, "USD").eql?(Money.new(1_00, "USD"))).to be true
51
- expect(Money.new(1_00, "USD").eql?(Money.new(1_00, "EUR"))).to be false
52
- expect(Money.new(1_00, "USD").eql?(Money.new(2_00, "USD"))).to be false
53
- expect(Money.new(1_00, "USD").eql?(Money.new(99_00, "EUR"))).to be false
54
- end
55
-
56
- it "returns false if used to compare with an object that doesn't respond to #to_money" do
57
- expect(Money.new(1_00, "USD").eql?(Object.new)).to be false
58
- expect(Money.new(1_00, "USD").eql?(Class)).to be false
59
- expect(Money.new(1_00, "USD").eql?(Kernel)).to be false
60
- expect(Money.new(1_00, "USD").eql?(/foo/)).to be false
61
- expect(Money.new(1_00, "USD").eql?(nil)).to be false
62
- end
63
-
64
- it "can be used to compare with an object that responds to #to_money" do
65
- klass = Class.new do
66
- def initialize(money)
67
- @money = money
68
- end
69
-
70
- def to_money
71
- @money
72
- end
73
- end
74
-
75
- expect(Money.new(1_00, "USD").eql?(klass.new(Money.new(1_00, "USD")))).to be true
76
- expect(Money.new(2_50, "USD").eql?(klass.new(Money.new(2_50, "USD")))).to be true
77
- expect(Money.new(2_50, "USD").eql?(klass.new(Money.new(3_00, "USD")))).to be false
78
- expect(Money.new(1_00, "GBP").eql?(klass.new(Money.new(1_00, "USD")))).to be false
79
- end
80
- end
81
-
82
- describe "#<=>" do
83
- it "compares the two object amounts (same currency)" do
84
- expect((Money.new(1_00, "USD") <=> Money.new(1_00, "USD"))).to eq 0
85
- expect((Money.new(1_00, "USD") <=> Money.new(99, "USD"))).to be > 0
86
- expect((Money.new(1_00, "USD") <=> Money.new(2_00, "USD"))).to be < 0
87
- end
88
-
89
- it "converts other object amount to current currency, then compares the two object amounts (different currency)" do
90
- target = Money.new(200_00, "EUR")
91
- expect(target).to receive(:exchange_to).with(Money::Currency.new("USD")).and_return(Money.new(300_00, "USD"))
92
- expect(Money.new(100_00, "USD") <=> target).to be < 0
93
-
94
- target = Money.new(200_00, "EUR")
95
- expect(target).to receive(:exchange_to).with(Money::Currency.new("USD")).and_return(Money.new(100_00, "USD"))
96
- expect(Money.new(100_00, "USD") <=> target).to eq 0
97
-
98
- target = Money.new(200_00, "EUR")
99
- expect(target).to receive(:exchange_to).with(Money::Currency.new("USD")).and_return(Money.new(99_00, "USD"))
100
- expect(Money.new(100_00, "USD") <=> target).to be > 0
101
- end
102
-
103
- it "can be used to compare with an object that responds to #to_money" do
104
- klass = Class.new do
105
- def initialize(money)
106
- @money = money
107
- end
108
-
109
- def to_money
110
- @money
111
- end
112
- end
113
-
114
- expect(Money.new(1_00) <=> klass.new(Money.new(1_00))).to eq 0
115
- expect(Money.new(1_00) <=> klass.new(Money.new(99))).to be > 0
116
- expect(Money.new(1_00) <=> klass.new(Money.new(2_00))).to be < 0
117
- end
118
-
119
- it "raises ArgumentError when used to compare with an object that doesn't respond to #to_money" do
120
- expected_message = /Comparison .+ failed/
121
- expect{ Money.new(1_00) <=> Object.new }.to raise_error(ArgumentError, expected_message)
122
- expect{ Money.new(1_00) <=> Class }.to raise_error(ArgumentError, expected_message)
123
- expect{ Money.new(1_00) <=> Kernel }.to raise_error(ArgumentError, expected_message)
124
- expect{ Money.new(1_00) <=> /foo/ }.to raise_error(ArgumentError, expected_message)
125
- end
126
- end
127
-
128
- describe "#positive?" do
129
- it "returns true if the amount is greater than 0" do
130
- expect(Money.new(1)).to be_positive
131
- end
132
-
133
- it "returns false if the amount is 0" do
134
- expect(Money.new(0)).not_to be_positive
135
- end
136
-
137
- it "returns false if the amount is negative" do
138
- expect(Money.new(-1)).not_to be_positive
139
- end
140
- end
141
-
142
- describe "#negative?" do
143
- it "returns true if the amount is less than 0" do
144
- expect(Money.new(-1)).to be_negative
145
- end
146
-
147
- it "returns false if the amount is 0" do
148
- expect(Money.new(0)).not_to be_negative
149
- end
150
-
151
- it "returns false if the amount is greater than 0" do
152
- expect(Money.new(1)).not_to be_negative
153
- end
154
- end
155
-
156
- describe "#+" do
157
- it "adds other amount to current amount (same currency)" do
158
- expect(Money.new(10_00, "USD") + Money.new(90, "USD")).to eq Money.new(10_90, "USD")
159
- end
160
-
161
- it "converts other object amount to current currency and adds other amount to current amount (different currency)" do
162
- other = Money.new(90, "EUR")
163
- expect(other).to receive(:exchange_to).with(Money::Currency.new("USD")).and_return(Money.new(9_00, "USD"))
164
- expect(Money.new(10_00, "USD") + other).to eq Money.new(19_00, "USD")
165
- end
166
-
167
- it "adds Fixnum 0 to money and returns the same ammount" do
168
- expect(Money.new(10_00) + 0).to eq Money.new(10_00)
169
- end
170
- end
171
-
172
- describe "#-" do
173
- it "subtracts other amount from current amount (same currency)" do
174
- expect(Money.new(10_00, "USD") - Money.new(90, "USD")).to eq Money.new(9_10, "USD")
175
- end
176
-
177
- it "converts other object amount to current currency and subtracts other amount from current amount (different currency)" do
178
- other = Money.new(90, "EUR")
179
- expect(other).to receive(:exchange_to).with(Money::Currency.new("USD")).and_return(Money.new(9_00, "USD"))
180
- expect(Money.new(10_00, "USD") - other).to eq Money.new(1_00, "USD")
181
- end
182
-
183
- it "subtract Fixnum 0 to money and returns the same ammount" do
184
- expect(Money.new(10_00) - 0).to eq Money.new(10_00)
185
- end
186
- end
187
-
188
- describe "#*" do
189
- it "multiplies Money by Fixnum and returns Money" do
190
- ts = [
191
- {:a => Money.new( 10, :USD), :b => 4, :c => Money.new( 40, :USD)},
192
- {:a => Money.new( 10, :USD), :b => -4, :c => Money.new(-40, :USD)},
193
- {:a => Money.new(-10, :USD), :b => 4, :c => Money.new(-40, :USD)},
194
- {:a => Money.new(-10, :USD), :b => -4, :c => Money.new( 40, :USD)},
195
- ]
196
- ts.each do |t|
197
- expect(t[:a] * t[:b]).to eq t[:c]
198
- end
199
- end
200
-
201
- it "does not multiply Money by Money (same currency)" do
202
- expect { Money.new( 10, :USD) * Money.new( 4, :USD) }.to raise_error(ArgumentError)
203
- end
204
-
205
- it "does not multiply Money by Money (different currency)" do
206
- expect { Money.new( 10, :USD) * Money.new( 4, :EUR) }.to raise_error(ArgumentError)
207
- end
208
-
209
- it "does not multiply Money by an object which is NOT a number" do
210
- expect { Money.new( 10, :USD) * 'abc' }.to raise_error(ArgumentError)
211
- end
212
- end
213
-
214
- describe "#/" do
215
- it "divides Money by Fixnum and returns Money" do
216
- ts = [
217
- {:a => Money.new( 13, :USD), :b => 4, :c => Money.new( 3, :USD)},
218
- {:a => Money.new( 13, :USD), :b => -4, :c => Money.new(-3, :USD)},
219
- {:a => Money.new(-13, :USD), :b => 4, :c => Money.new(-3, :USD)},
220
- {:a => Money.new(-13, :USD), :b => -4, :c => Money.new( 3, :USD)},
221
- ]
222
- ts.each do |t|
223
- expect(t[:a] / t[:b]).to eq t[:c]
224
- end
225
- end
226
-
227
- context 'rounding preference' do
228
- before do
229
- allow(Money).to receive(:rounding_mode).and_return(rounding_mode)
230
- end
231
-
232
- after do
233
- allow(Money).to receive(:rounding_mode).and_call_original
234
- end
235
-
236
- context 'ceiling rounding' do
237
- let(:rounding_mode) { BigDecimal::ROUND_CEILING }
238
- it "obeys the rounding preference" do
239
- expect(Money.new(10) / 3).to eq Money.new(4)
240
- end
241
- end
242
-
243
- context 'floor rounding' do
244
- let(:rounding_mode) { BigDecimal::ROUND_FLOOR }
245
- it "obeys the rounding preference" do
246
- expect(Money.new(10) / 6).to eq Money.new(1)
247
- end
248
- end
249
-
250
- context 'half up rounding' do
251
- let(:rounding_mode) { BigDecimal::ROUND_HALF_UP }
252
- it "obeys the rounding preference" do
253
- expect(Money.new(10) / 4).to eq Money.new(3)
254
- end
255
- end
256
-
257
- context 'half down rounding' do
258
- let(:rounding_mode) { BigDecimal::ROUND_HALF_DOWN }
259
- it "obeys the rounding preference" do
260
- expect(Money.new(10) / 4).to eq Money.new(2)
261
- end
262
- end
263
- end
264
-
265
- it "divides Money by Money (same currency) and returns Float" do
266
- ts = [
267
- {:a => Money.new( 13, :USD), :b => Money.new( 4, :USD), :c => 3.25},
268
- {:a => Money.new( 13, :USD), :b => Money.new(-4, :USD), :c => -3.25},
269
- {:a => Money.new(-13, :USD), :b => Money.new( 4, :USD), :c => -3.25},
270
- {:a => Money.new(-13, :USD), :b => Money.new(-4, :USD), :c => 3.25},
271
- ]
272
- ts.each do |t|
273
- expect(t[:a] / t[:b]).to eq t[:c]
274
- end
275
- end
276
-
277
- it "divides Money by Money (different currency) and returns Float" do
278
- ts = [
279
- {:a => Money.new( 13, :USD), :b => Money.new( 4, :EUR), :c => 1.625},
280
- {:a => Money.new( 13, :USD), :b => Money.new(-4, :EUR), :c => -1.625},
281
- {:a => Money.new(-13, :USD), :b => Money.new( 4, :EUR), :c => -1.625},
282
- {:a => Money.new(-13, :USD), :b => Money.new(-4, :EUR), :c => 1.625},
283
- ]
284
- ts.each do |t|
285
- expect(t[:b]).to receive(:exchange_to).once.with(t[:a].currency).and_return(Money.new(t[:b].cents * 2, :USD))
286
- expect(t[:a] / t[:b]).to eq t[:c]
287
- end
288
- end
289
-
290
- context "infinite_precision = true" do
291
- before do
292
- Money.infinite_precision = true
293
- end
294
-
295
- after do
296
- Money.infinite_precision = false
297
- end
298
-
299
- it "uses BigDecimal division" do
300
- ts = [
301
- {:a => Money.new( 13, :USD), :b => 4, :c => Money.new( 3.25, :USD)},
302
- {:a => Money.new( 13, :USD), :b => -4, :c => Money.new(-3.25, :USD)},
303
- {:a => Money.new(-13, :USD), :b => 4, :c => Money.new(-3.25, :USD)},
304
- {:a => Money.new(-13, :USD), :b => -4, :c => Money.new( 3.25, :USD)},
305
- ]
306
- ts.each do |t|
307
- expect(t[:a] / t[:b]).to eq t[:c]
308
- end
309
- end
310
- end
311
- end
312
-
313
- describe "#div" do
314
- it "divides Money by Fixnum and returns Money" do
315
- ts = [
316
- {:a => Money.new( 13, :USD), :b => 4, :c => Money.new( 3, :USD)},
317
- {:a => Money.new( 13, :USD), :b => -4, :c => Money.new(-3, :USD)},
318
- {:a => Money.new(-13, :USD), :b => 4, :c => Money.new(-3, :USD)},
319
- {:a => Money.new(-13, :USD), :b => -4, :c => Money.new( 3, :USD)},
320
- ]
321
- ts.each do |t|
322
- expect(t[:a].div(t[:b])).to eq t[:c]
323
- end
324
- end
325
-
326
- it "divides Money by Money (same currency) and returns Float" do
327
- ts = [
328
- {:a => Money.new( 13, :USD), :b => Money.new( 4, :USD), :c => 3.25},
329
- {:a => Money.new( 13, :USD), :b => Money.new(-4, :USD), :c => -3.25},
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
- ]
333
- ts.each do |t|
334
- expect(t[:a].div(t[:b])).to eq t[:c]
335
- end
336
- end
337
-
338
- it "divides Money by Money (different currency) and returns Float" do
339
- ts = [
340
- {:a => Money.new( 13, :USD), :b => Money.new( 4, :EUR), :c => 1.625},
341
- {:a => Money.new( 13, :USD), :b => Money.new(-4, :EUR), :c => -1.625},
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
- ]
345
- ts.each do |t|
346
- expect(t[:b]).to receive(:exchange_to).once.with(t[:a].currency).and_return(Money.new(t[:b].cents * 2, :USD))
347
- expect(t[:a].div(t[:b])).to eq t[:c]
348
- end
349
- end
350
-
351
- context "infinite_precision = true" do
352
- before do
353
- Money.infinite_precision = true
354
- end
355
-
356
- after do
357
- Money.infinite_precision = false
358
- end
359
-
360
- it "uses BigDecimal division" do
361
- ts = [
362
- {:a => Money.new( 13, :USD), :b => 4, :c => Money.new( 3.25, :USD)},
363
- {:a => Money.new( 13, :USD), :b => -4, :c => Money.new(-3.25, :USD)},
364
- {:a => Money.new(-13, :USD), :b => 4, :c => Money.new(-3.25, :USD)},
365
- {:a => Money.new(-13, :USD), :b => -4, :c => Money.new( 3.25, :USD)},
366
- ]
367
- ts.each do |t|
368
- expect(t[:a].div(t[:b])).to eq t[:c]
369
- end
370
- end
371
- end
372
- end
373
-
374
- describe "#divmod" do
375
- it "calculates division and modulo with Fixnum" do
376
- ts = [
377
- {:a => Money.new( 13, :USD), :b => 4, :c => [Money.new( 3, :USD), Money.new( 1, :USD)]},
378
- {:a => Money.new( 13, :USD), :b => -4, :c => [Money.new(-3, :USD), Money.new(-3, :USD)]},
379
- {:a => Money.new(-13, :USD), :b => 4, :c => [Money.new(-3, :USD), Money.new( 3, :USD)]},
380
- {:a => Money.new(-13, :USD), :b => -4, :c => [Money.new( 3, :USD), Money.new(-1, :USD)]},
381
- ]
382
- ts.each do |t|
383
- expect(t[:a].divmod(t[:b])).to eq t[:c]
384
- end
385
- end
386
-
387
- it "calculates division and modulo with Money (same currency)" do
388
- ts = [
389
- {:a => Money.new( 13, :USD), :b => Money.new( 4, :USD), :c => [ 3, Money.new( 1, :USD)]},
390
- {:a => Money.new( 13, :USD), :b => Money.new(-4, :USD), :c => [-4, Money.new(-3, :USD)]},
391
- {:a => Money.new(-13, :USD), :b => Money.new( 4, :USD), :c => [-4, Money.new( 3, :USD)]},
392
- {:a => Money.new(-13, :USD), :b => Money.new(-4, :USD), :c => [ 3, Money.new(-1, :USD)]},
393
- ]
394
- ts.each do |t|
395
- expect(t[:a].divmod(t[:b])).to eq t[:c]
396
- end
397
- end
398
-
399
- it "calculates division and modulo with Money (different currency)" do
400
- ts = [
401
- {:a => Money.new( 13, :USD), :b => Money.new( 4, :EUR), :c => [ 1, Money.new( 5, :USD)]},
402
- {:a => Money.new( 13, :USD), :b => Money.new(-4, :EUR), :c => [-2, Money.new(-3, :USD)]},
403
- {:a => Money.new(-13, :USD), :b => Money.new( 4, :EUR), :c => [-2, Money.new( 3, :USD)]},
404
- {:a => Money.new(-13, :USD), :b => Money.new(-4, :EUR), :c => [ 1, Money.new(-5, :USD)]},
405
- ]
406
- ts.each do |t|
407
- expect(t[:b]).to receive(:exchange_to).once.with(t[:a].currency).and_return(Money.new(t[:b].cents * 2, :USD))
408
- expect(t[:a].divmod(t[:b])).to eq t[:c]
409
- end
410
- end
411
-
412
- context "infinite_precision = true" do
413
- before do
414
- Money.infinite_precision = true
415
- end
416
-
417
- after do
418
- Money.infinite_precision = false
419
- end
420
-
421
- it "uses BigDecimal division" do
422
- ts = [
423
- {:a => Money.new( 13, :USD), :b => 4, :c => [Money.new( 3, :USD), Money.new( 1, :USD)]},
424
- {:a => Money.new( 13, :USD), :b => -4, :c => [Money.new(-4, :USD), Money.new(-3, :USD)]},
425
- {:a => Money.new(-13, :USD), :b => 4, :c => [Money.new(-4, :USD), Money.new( 3, :USD)]},
426
- {:a => Money.new(-13, :USD), :b => -4, :c => [Money.new( 3, :USD), Money.new(-1, :USD)]},
427
- ]
428
- ts.each do |t|
429
- expect(t[:a].divmod(t[:b])).to eq t[:c]
430
- end
431
- end
432
- end
433
- end
434
-
435
- describe "#modulo" do
436
- it "calculates modulo with Fixnum" do
437
- ts = [
438
- {:a => Money.new( 13, :USD), :b => 4, :c => Money.new( 1, :USD)},
439
- {:a => Money.new( 13, :USD), :b => -4, :c => Money.new(-3, :USD)},
440
- {:a => Money.new(-13, :USD), :b => 4, :c => Money.new( 3, :USD)},
441
- {:a => Money.new(-13, :USD), :b => -4, :c => Money.new(-1, :USD)},
442
- ]
443
- ts.each do |t|
444
- expect(t[:a].modulo(t[:b])).to eq t[:c]
445
- end
446
- end
447
-
448
- it "calculates modulo with Money (same currency)" do
449
- ts = [
450
- {:a => Money.new( 13, :USD), :b => Money.new( 4, :USD), :c => Money.new( 1, :USD)},
451
- {:a => Money.new( 13, :USD), :b => Money.new(-4, :USD), :c => Money.new(-3, :USD)},
452
- {:a => Money.new(-13, :USD), :b => Money.new( 4, :USD), :c => Money.new( 3, :USD)},
453
- {:a => Money.new(-13, :USD), :b => Money.new(-4, :USD), :c => Money.new(-1, :USD)},
454
- ]
455
- ts.each do |t|
456
- expect(t[:a].modulo(t[:b])).to eq t[:c]
457
- end
458
- end
459
-
460
- it "calculates modulo with Money (different currency)" do
461
- ts = [
462
- {:a => Money.new( 13, :USD), :b => Money.new( 4, :EUR), :c => Money.new( 5, :USD)},
463
- {:a => Money.new( 13, :USD), :b => Money.new(-4, :EUR), :c => Money.new(-3, :USD)},
464
- {:a => Money.new(-13, :USD), :b => Money.new( 4, :EUR), :c => Money.new( 3, :USD)},
465
- {:a => Money.new(-13, :USD), :b => Money.new(-4, :EUR), :c => Money.new(-5, :USD)},
466
- ]
467
- ts.each do |t|
468
- expect(t[:b]).to receive(:exchange_to).once.with(t[:a].currency).and_return(Money.new(t[:b].cents * 2, :USD))
469
- expect(t[:a].modulo(t[:b])).to eq t[:c]
470
- end
471
- end
472
- end
473
-
474
- describe "#%" do
475
- it "calculates modulo with Fixnum" do
476
- ts = [
477
- {:a => Money.new( 13, :USD), :b => 4, :c => Money.new( 1, :USD)},
478
- {:a => Money.new( 13, :USD), :b => -4, :c => Money.new(-3, :USD)},
479
- {:a => Money.new(-13, :USD), :b => 4, :c => Money.new( 3, :USD)},
480
- {:a => Money.new(-13, :USD), :b => -4, :c => Money.new(-1, :USD)},
481
- ]
482
- ts.each do |t|
483
- expect(t[:a] % t[:b]).to eq t[:c]
484
- end
485
- end
486
-
487
- it "calculates modulo with Money (same currency)" do
488
- ts = [
489
- {:a => Money.new( 13, :USD), :b => Money.new( 4, :USD), :c => Money.new( 1, :USD)},
490
- {:a => Money.new( 13, :USD), :b => Money.new(-4, :USD), :c => Money.new(-3, :USD)},
491
- {:a => Money.new(-13, :USD), :b => Money.new( 4, :USD), :c => Money.new( 3, :USD)},
492
- {:a => Money.new(-13, :USD), :b => Money.new(-4, :USD), :c => Money.new(-1, :USD)},
493
- ]
494
- ts.each do |t|
495
- expect(t[:a] % t[:b]).to eq t[:c]
496
- end
497
- end
498
-
499
- it "calculates modulo with Money (different currency)" do
500
- ts = [
501
- {:a => Money.new( 13, :USD), :b => Money.new( 4, :EUR), :c => Money.new( 5, :USD)},
502
- {:a => Money.new( 13, :USD), :b => Money.new(-4, :EUR), :c => Money.new(-3, :USD)},
503
- {:a => Money.new(-13, :USD), :b => Money.new( 4, :EUR), :c => Money.new( 3, :USD)},
504
- {:a => Money.new(-13, :USD), :b => Money.new(-4, :EUR), :c => Money.new(-5, :USD)},
505
- ]
506
- ts.each do |t|
507
- expect(t[:b]).to receive(:exchange_to).once.with(t[:a].currency).and_return(Money.new(t[:b].cents * 2, :USD))
508
- expect(t[:a] % t[:b]).to eq t[:c]
509
- end
510
- end
511
- end
512
-
513
- describe "#remainder" do
514
- it "calculates remainder with Fixnum" do
515
- ts = [
516
- {:a => Money.new( 13, :USD), :b => 4, :c => Money.new( 1, :USD)},
517
- {:a => Money.new( 13, :USD), :b => -4, :c => Money.new( 1, :USD)},
518
- {:a => Money.new(-13, :USD), :b => 4, :c => Money.new(-1, :USD)},
519
- {:a => Money.new(-13, :USD), :b => -4, :c => Money.new(-1, :USD)},
520
- ]
521
- ts.each do |t|
522
- expect(t[:a].remainder(t[:b])).to eq t[:c]
523
- end
524
- end
525
- end
526
-
527
- describe "#abs" do
528
- it "returns the absolute value as a new Money object" do
529
- n = Money.new(-1, :USD)
530
- expect(n.abs).to eq Money.new( 1, :USD)
531
- expect(n).to eq Money.new(-1, :USD)
532
- end
533
- end
534
-
535
- describe "#zero?" do
536
- it "returns whether the amount is 0" do
537
- expect(Money.new(0, "USD")).to be_zero
538
- expect(Money.new(0, "EUR")).to be_zero
539
- expect(Money.new(1, "USD")).not_to be_zero
540
- expect(Money.new(10, "YEN")).not_to be_zero
541
- expect(Money.new(-1, "EUR")).not_to be_zero
542
- end
543
- end
544
-
545
- describe "#nonzero?" do
546
- it "returns whether the amount is not 0" do
547
- expect(Money.new(0, "USD")).not_to be_nonzero
548
- expect(Money.new(0, "EUR")).not_to be_nonzero
549
- expect(Money.new(1, "USD")).to be_nonzero
550
- expect(Money.new(10, "YEN")).to be_nonzero
551
- expect(Money.new(-1, "EUR")).to be_nonzero
552
- end
553
-
554
- it "has the same return-value semantics as Numeric#nonzero?" do
555
- expect(Money.new(0, "USD").nonzero?).to be_nil
556
-
557
- money = Money.new(1, "USD")
558
- expect(money.nonzero?).to be_equal(money)
559
- end
560
- end
561
-
562
- describe "#coerce" do
563
- it "allows mathematical operations by coercing arguments" do
564
- result = 2 * Money.new(4, 'USD')
565
- expect(result).to eq Money.new(8, 'USD')
566
- end
567
- end
568
- end
@@ -1,75 +0,0 @@
1
- # encoding: utf-8
2
-
3
- require "spec_helper"
4
-
5
- describe Money::Constructors do
6
-
7
- describe "::empty" do
8
- it "creates a new Money object of 0 cents" do
9
- expect(Money.empty).to eq Money.new(0)
10
- end
11
-
12
- it "memoizes the result" do
13
- expect(Money.empty.object_id).to eq Money.empty.object_id
14
- end
15
-
16
- it "memoizes a result for each currency" do
17
- expect(Money.empty(:cad).object_id).to eq Money.empty(:cad).object_id
18
- end
19
-
20
- it "doesn't allow money to be modified for a currency" do
21
- expect(Money.empty).to be_frozen
22
- end
23
- end
24
-
25
-
26
- describe "::zero" do
27
- subject { Money.zero }
28
- it { is_expected.to eq Money.empty }
29
- end
30
-
31
-
32
- describe "::ca_dollar" do
33
- it "creates a new Money object of the given value in CAD" do
34
- expect(Money.ca_dollar(50)).to eq Money.new(50, "CAD")
35
- end
36
-
37
- it "is aliased to ::cad" do
38
- expect(Money.cad(50)).to eq Money.ca_dollar(50)
39
- end
40
- end
41
-
42
-
43
- describe "::us_dollar" do
44
- it "creates a new Money object of the given value in USD" do
45
- expect(Money.us_dollar(50)).to eq Money.new(50, "USD")
46
- end
47
-
48
- it "is aliased to ::usd" do
49
- expect(Money.usd(50)).to eq Money.us_dollar(50)
50
- end
51
- end
52
-
53
-
54
- describe "::euro" do
55
- it "creates a new Money object of the given value in EUR" do
56
- expect(Money.euro(50)).to eq Money.new(50, "EUR")
57
- end
58
-
59
- it "is aliased to ::eur" do
60
- expect(Money.eur(50)).to eq Money.euro(50)
61
- end
62
- end
63
-
64
-
65
- describe "::pound_sterling" do
66
- it "creates a new Money object of the given value in GBP" do
67
- expect(Money.pound_sterling(50)).to eq Money.new(50, "GBP")
68
- end
69
-
70
- it "is aliased to ::gbp" do
71
- expect(Money.gbp(50)).to eq Money.pound_sterling(50)
72
- end
73
- end
74
-
75
- end