money 6.9.0 → 6.16.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (47) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +131 -3
  3. data/LICENSE +17 -17
  4. data/README.md +181 -71
  5. data/config/currency_backwards_compatible.json +65 -0
  6. data/config/currency_iso.json +119 -56
  7. data/config/currency_non_iso.json +35 -2
  8. data/lib/money/bank/variable_exchange.rb +22 -12
  9. data/lib/money/currency/loader.rb +15 -13
  10. data/lib/money/currency.rb +38 -39
  11. data/lib/money/locale_backend/base.rb +7 -0
  12. data/lib/money/locale_backend/currency.rb +11 -0
  13. data/lib/money/locale_backend/errors.rb +6 -0
  14. data/lib/money/locale_backend/i18n.rb +25 -0
  15. data/lib/money/locale_backend/legacy.rb +28 -0
  16. data/lib/money/money/allocation.rb +46 -0
  17. data/lib/money/money/arithmetic.rb +33 -15
  18. data/lib/money/money/constructors.rb +1 -2
  19. data/lib/money/money/formatter.rb +399 -0
  20. data/lib/money/money/formatting_rules.rb +142 -0
  21. data/lib/money/money/locale_backend.rb +22 -0
  22. data/lib/money/money.rb +235 -187
  23. data/lib/money/rates_store/memory.rb +24 -24
  24. data/lib/money/version.rb +1 -1
  25. data/money.gemspec +14 -8
  26. metadata +36 -56
  27. data/.coveralls.yml +0 -1
  28. data/.gitignore +0 -23
  29. data/.rspec +0 -1
  30. data/.travis.yml +0 -26
  31. data/AUTHORS +0 -126
  32. data/CONTRIBUTING.md +0 -17
  33. data/Gemfile +0 -16
  34. data/Rakefile +0 -17
  35. data/lib/money/money/formatting.rb +0 -426
  36. data/spec/bank/base_spec.rb +0 -79
  37. data/spec/bank/single_currency_spec.rb +0 -13
  38. data/spec/bank/variable_exchange_spec.rb +0 -265
  39. data/spec/currency/heuristics_spec.rb +0 -11
  40. data/spec/currency/loader_spec.rb +0 -19
  41. data/spec/currency_spec.rb +0 -359
  42. data/spec/money/arithmetic_spec.rb +0 -693
  43. data/spec/money/constructors_spec.rb +0 -103
  44. data/spec/money/formatting_spec.rb +0 -757
  45. data/spec/money_spec.rb +0 -778
  46. data/spec/rates_store/memory_spec.rb +0 -69
  47. data/spec/spec_helper.rb +0 -28
@@ -1,757 +0,0 @@
1
- # encoding: utf-8
2
-
3
- describe Money, "formatting" do
4
-
5
- BAR = '{ "priority": 1, "iso_code": "BAR", "iso_numeric": "840", "name": "Dollar with 4 decimal places", "symbol": "$", "subunit": "Cent", "subunit_to_unit": 10000, "symbol_first": true, "html_entity": "$", "decimal_mark": ".", "thousands_separator": ",", "smallest_denomination": 1 }'
6
- INDIAN_BAR = '{ "priority": 1, "iso_code": "INDIAN_BAR", "iso_numeric": "840", "name": "Dollar with 4 decimal places", "symbol": "$", "subunit": "Cent", "subunit_to_unit": 10000, "symbol_first": true, "html_entity": "$", "decimal_mark": ".", "thousands_separator": ",", "south_asian_number_formatting": true, "smallest_denomination": 1}'
7
- EU4 = '{ "priority": 1, "iso_code": "EU4", "iso_numeric": "841", "name": "Euro with 4 decimal places", "symbol": "€", "subunit": "Cent", "subunit_to_unit": 10000, "symbol_first": true, "html_entity": "€", "decimal_mark": ",", "thousands_separator": ".", "smallest_denomination": 1 }'
8
-
9
- context "without i18n" do
10
- subject(:money) { Money.empty("USD") }
11
-
12
- it "should use ',' as the thousands separator" do
13
- expect(money.thousands_separator).to eq ','
14
- end
15
-
16
- it "should use '.' as the decimal mark" do
17
- expect(money.decimal_mark).to eq '.'
18
- end
19
- end
20
-
21
- context "with i18n but use_i18n = false" do
22
- before :each do
23
- reset_i18n
24
- I18n.locale = :de
25
- I18n.backend.store_translations(
26
- :de,
27
- :number => { :currency => { :format => { :delimiter => ".", :separator => "," } } }
28
- )
29
- Money.use_i18n = false
30
- end
31
-
32
- after :each do
33
- reset_i18n
34
- I18n.locale = :en
35
- Money.use_i18n = true
36
- end
37
-
38
- subject(:money) { Money.empty("USD") }
39
-
40
- it "should use ',' as the thousands separator" do
41
- expect(money.thousands_separator).to eq ','
42
- end
43
-
44
- it "should use '.' as the decimal mark" do
45
- expect(money.decimal_mark).to eq '.'
46
- end
47
- end
48
-
49
- context "with i18n" do
50
- after :each do
51
- reset_i18n
52
- I18n.locale = :en
53
- end
54
-
55
- context "with number.format.*" do
56
- before :each do
57
- reset_i18n
58
- I18n.locale = :de
59
- I18n.backend.store_translations(
60
- :de,
61
- :number => { :format => { :delimiter => ".", :separator => "," } }
62
- )
63
- end
64
-
65
- subject(:money) { Money.empty("USD") }
66
-
67
- it "should use '.' as the thousands separator" do
68
- expect(money.thousands_separator).to eq '.'
69
- end
70
-
71
- it "should use ',' as the decimal mark" do
72
- expect(money.decimal_mark).to eq ','
73
- end
74
- end
75
-
76
- context "with number.currency.format.*" do
77
- before :each do
78
- reset_i18n
79
- I18n.locale = :de
80
- I18n.backend.store_translations(
81
- :de,
82
- :number => { :currency => { :format => { :delimiter => ".", :separator => "," } } }
83
- )
84
- end
85
-
86
- subject(:money) { Money.empty("USD") }
87
-
88
- it "should use '.' as the thousands separator" do
89
- expect(money.thousands_separator).to eq '.'
90
- end
91
-
92
- it "should use ',' as the decimal mark" do
93
- expect(money.decimal_mark).to eq ','
94
- end
95
- end
96
-
97
- context "with number.currency.symbol.*" do
98
- before :each do
99
- reset_i18n
100
- I18n.locale = :de
101
- I18n.backend.store_translations(
102
- :de,
103
- :number => { :currency => { :symbol => { :CAD => "CAD$" } } }
104
- )
105
- end
106
-
107
- subject(:money) { Money.empty("CAD") }
108
-
109
- it "should use 'CAD$' as the currency symbol" do
110
- expect(money.format(:translate => true)).to eq("CAD$0.00")
111
- end
112
- end
113
-
114
- context "with overridden i18n settings" do
115
- it "should respect explicit overriding of thousands_separator/delimiter when decimal_mark/separator collide and there’s no decimal component for currencies that have no subunit" do
116
- expect(Money.new(300_000, 'ISK').format(:thousands_separator => ".", decimal_mark: ',')).to eq "kr300.000"
117
- end
118
-
119
- it "should respect explicit overriding of thousands_separator/delimiter when decimal_mark/separator collide and there’s no decimal component for currencies with subunits that drop_trailing_zeros" do
120
- expect(Money.new(300_000, 'USD').format(:thousands_separator => ".", decimal_mark: ',', drop_trailing_zeros: true)).to eq "$3.000"
121
- end
122
- end
123
- end
124
-
125
- describe "#format" do
126
- context "Locale :ja" do
127
- before { @_locale = I18n.locale; I18n.locale = :ja }
128
-
129
- it "formats Japanese currency in Japanese properly" do
130
- money = Money.new(1000, "JPY")
131
- expect(money.format).to eq "1,000円"
132
- expect(money.format(:symbol => false)).to eq "1,000"
133
- end
134
-
135
- after { I18n.locale = @_locale }
136
- end
137
-
138
- it "returns the monetary value as a string" do
139
- expect(Money.ca_dollar(100).format).to eq "$1.00"
140
- expect(Money.new(40008).format).to eq "$400.08"
141
- end
142
-
143
- it "respects :subunit_to_unit currency property" do
144
- expect(Money.new(10_00, "BHD").format).to eq "ب.د1.000"
145
- end
146
-
147
- it "does not display a decimal when :subunit_to_unit is 1" do
148
- expect(Money.new(10_00, "VUV").format).to eq "Vt1,000"
149
- end
150
-
151
- it "respects the thousands_separator and decimal_mark defaults" do
152
- one_thousand = Proc.new do |currency|
153
- Money.new(1000_00, currency).format
154
- end
155
-
156
- # Pounds
157
- expect(one_thousand["GBP"]).to eq "£1,000.00"
158
-
159
- # Dollars
160
- expect(one_thousand["USD"]).to eq "$1,000.00"
161
- expect(one_thousand["CAD"]).to eq "$1,000.00"
162
- expect(one_thousand["AUD"]).to eq "$1,000.00"
163
- expect(one_thousand["NZD"]).to eq "$1,000.00"
164
- expect(one_thousand["ZWD"]).to eq "$1,000.00"
165
-
166
- # Yen
167
- expect(one_thousand["JPY"]).to eq "¥100,000"
168
- expect(one_thousand["CNY"]).to eq "¥1,000.00"
169
-
170
- # Euro
171
- expect(one_thousand["EUR"]).to eq "€1.000,00"
172
-
173
- # Rupees
174
- expect(one_thousand["INR"]).to eq "₹1,000.00"
175
- expect(one_thousand["NPR"]).to eq "₨1,000.00"
176
- expect(one_thousand["SCR"]).to eq "1,000.00 ₨"
177
- expect(one_thousand["LKR"]).to eq "1,000.00 ₨"
178
-
179
- # Brazilian Real
180
- expect(one_thousand["BRL"]).to eq "R$1.000,00"
181
-
182
- # Other
183
- expect(one_thousand["SEK"]).to eq "1 000,00 kr"
184
- expect(one_thousand["GHC"]).to eq "₵1,000.00"
185
- end
186
-
187
- it "inserts commas into the result if the amount is sufficiently large" do
188
- expect(Money.us_dollar(1_000_000_000_12).format).to eq "$1,000,000,000.12"
189
- expect(Money.us_dollar(1_000_000_000_12).format(:no_cents => true)).to eq "$1,000,000,000"
190
- end
191
-
192
- it "inserts thousands separator into the result if the amount is sufficiently large and the currency symbol is at the end" do
193
- expect(Money.euro(1_234_567_12).format).to eq "€1.234.567,12"
194
- expect(Money.euro(1_234_567_12).format(:no_cents => true)).to eq "€1.234.567"
195
- end
196
-
197
- context 'when default_formatting_rules defines (display_free: true)' do
198
- before do
199
- Money.default_formatting_rules = { :display_free => "you won't pay a thing" }
200
- end
201
-
202
- after do
203
- Money.default_formatting_rules = nil
204
- end
205
-
206
- context 'with no rule provided' do
207
- it 'acknowledges default rule' do
208
- expect(Money.new(0, 'USD').format).to eq "you won't pay a thing"
209
- end
210
- end
211
-
212
- context 'with rule (display_free: false) provided' do
213
- it 'acknowledges provided rule' do
214
- expect(Money.new(0, 'USD').format(:display_free => false)).to eq '$0.00'
215
- end
216
- end
217
- end
218
-
219
- context 'when default_formatting_rules is not defined' do
220
- before do
221
- Money.default_formatting_rules = nil
222
- end
223
-
224
- context 'acknowledges provided rule' do
225
- it 'acknowledges provided rule' do
226
- expect(Money.new(100, 'USD').format(:with_currency => true)).to eq '$1.00 USD'
227
- end
228
- end
229
- end
230
-
231
- describe ":with_currency option" do
232
- specify "(:with_currency option => true) works as documented" do
233
- expect(Money.ca_dollar(100).format(:with_currency => true)).to eq "$1.00 CAD"
234
- expect(Money.us_dollar(85).format(:with_currency => true)).to eq "$0.85 USD"
235
- end
236
- end
237
-
238
- describe ":no_cents option" do
239
- specify "(:with_currency option => true) works as documented" do
240
- expect(Money.ca_dollar(100).format(:no_cents => true)).to eq "$1"
241
- expect(Money.ca_dollar(599).format(:no_cents => true)).to eq "$5"
242
- expect(Money.ca_dollar(570).format(:no_cents => true, :with_currency => true)).to eq "$5 CAD"
243
- expect(Money.ca_dollar(39000).format(:no_cents => true)).to eq "$390"
244
- end
245
-
246
- it "respects :subunit_to_unit currency property" do
247
- expect(Money.new(10_00, "BHD").format(:no_cents => true)).to eq "ب.د1"
248
- end
249
-
250
- it "inserts thousand separators if symbol contains decimal mark and no_cents is true" do
251
- expect(Money.new(100000000, "AMD").format(:no_cents => true)).to eq "1,000,000 դր."
252
- expect(Money.new(100000000, "USD").format(:no_cents => true)).to eq "$1,000,000"
253
- expect(Money.new(100000000, "RUB").format(:no_cents => true)).to eq "1.000.000 ₽"
254
- end
255
-
256
- it "doesn't incorrectly format HTML" do
257
- money = ::Money.new(1999, "RUB")
258
- output = money.format(:html => true, :no_cents => true)
259
- expect(output).to eq "19 ₽"
260
- end
261
- end
262
-
263
- describe ":no_cents_if_whole option" do
264
- specify "(:no_cents_if_whole => true) works as documented" do
265
- expect(Money.new(10000, "VUV").format(:no_cents_if_whole => true, :symbol => false)).to eq "10,000"
266
- expect(Money.new(10034, "VUV").format(:no_cents_if_whole => true, :symbol => false)).to eq "10,034"
267
- expect(Money.new(10000, "MGA").format(:no_cents_if_whole => true, :symbol => false)).to eq "2,000"
268
- expect(Money.new(10034, "MGA").format(:no_cents_if_whole => true, :symbol => false)).to eq "2,006.4"
269
- expect(Money.new(10000, "VND").format(:no_cents_if_whole => true, :symbol => false)).to eq "10.000"
270
- expect(Money.new(10034, "VND").format(:no_cents_if_whole => true, :symbol => false)).to eq "10.034"
271
- expect(Money.new(10000, "USD").format(:no_cents_if_whole => true, :symbol => false)).to eq "100"
272
- expect(Money.new(10034, "USD").format(:no_cents_if_whole => true, :symbol => false)).to eq "100.34"
273
- expect(Money.new(10000, "IQD").format(:no_cents_if_whole => true, :symbol => false)).to eq "10"
274
- expect(Money.new(10034, "IQD").format(:no_cents_if_whole => true, :symbol => false)).to eq "10.034"
275
- end
276
-
277
- specify "(:no_cents_if_whole => false) works as documented" do
278
- expect(Money.new(10000, "VUV").format(:no_cents_if_whole => false, :symbol => false)).to eq "10,000"
279
- expect(Money.new(10034, "VUV").format(:no_cents_if_whole => false, :symbol => false)).to eq "10,034"
280
- expect(Money.new(10000, "MGA").format(:no_cents_if_whole => false, :symbol => false)).to eq "2,000.0"
281
- expect(Money.new(10034, "MGA").format(:no_cents_if_whole => false, :symbol => false)).to eq "2,006.4"
282
- expect(Money.new(10000, "VND").format(:no_cents_if_whole => false, :symbol => false)).to eq "10.000"
283
- expect(Money.new(10034, "VND").format(:no_cents_if_whole => false, :symbol => false)).to eq "10.034"
284
- expect(Money.new(10000, "USD").format(:no_cents_if_whole => false, :symbol => false)).to eq "100.00"
285
- expect(Money.new(10034, "USD").format(:no_cents_if_whole => false, :symbol => false)).to eq "100.34"
286
- expect(Money.new(10000, "IQD").format(:no_cents_if_whole => false, :symbol => false)).to eq "10.000"
287
- expect(Money.new(10034, "IQD").format(:no_cents_if_whole => false, :symbol => false)).to eq "10.034"
288
- end
289
- end
290
-
291
- describe ":symbol option" do
292
- specify "(:symbol => a symbol string) uses the given value as the money symbol" do
293
- expect(Money.new(100, "GBP").format(:symbol => "£")).to eq "£1.00"
294
- end
295
-
296
- specify "(:symbol => true) returns symbol based on the given currency code" do
297
- one = Proc.new do |currency|
298
- Money.new(100, currency).format(:symbol => true)
299
- end
300
-
301
- # Pounds
302
- expect(one["GBP"]).to eq "£1.00"
303
-
304
- # Dollars
305
- expect(one["USD"]).to eq "$1.00"
306
- expect(one["CAD"]).to eq "$1.00"
307
- expect(one["AUD"]).to eq "$1.00"
308
- expect(one["NZD"]).to eq "$1.00"
309
- expect(one["ZWD"]).to eq "$1.00"
310
-
311
- # Yen
312
- expect(one["JPY"]).to eq "¥100"
313
- expect(one["CNY"]).to eq "¥1.00"
314
-
315
- # Euro
316
- expect(one["EUR"]).to eq "€1,00"
317
-
318
- # Rupees
319
- expect(one["INR"]).to eq "₹1.00"
320
- expect(one["NPR"]).to eq "₨1.00"
321
- expect(one["SCR"]).to eq "1.00 ₨"
322
- expect(one["LKR"]).to eq "1.00 ₨"
323
-
324
- # Brazilian Real
325
- expect(one["BRL"]).to eq "R$1,00"
326
-
327
- # Vietnamese Dong
328
- expect(one["VND"]).to eq "100 ₫"
329
-
330
- # Other
331
- expect(one["SEK"]).to eq "1,00 kr"
332
- expect(one["GHC"]).to eq "₵1.00"
333
- end
334
-
335
- specify "(:symbol => true) returns $ when currency code is not recognized" do
336
- currency = Money::Currency.new("EUR")
337
- expect(currency).to receive(:symbol).and_return(nil)
338
- expect(Money.new(100, currency).format(:symbol => true)).to eq "¤1,00"
339
- end
340
-
341
- specify "(:symbol => some non-Boolean value that evaluates to true) returns symbol based on the given currency code" do
342
- expect(Money.new(100, "GBP").format(:symbol => true)).to eq "£1.00"
343
- expect(Money.new(100, "EUR").format(:symbol => true)).to eq "€1,00"
344
- expect(Money.new(100, "SEK").format(:symbol => true)).to eq "1,00 kr"
345
- end
346
-
347
- specify "(:symbol => "", nil or false) returns the amount without a symbol" do
348
- money = Money.new(100, "GBP")
349
- expect(money.format(:symbol => "")).to eq "1.00"
350
- expect(money.format(:symbol => nil)).to eq "1.00"
351
- expect(money.format(:symbol => false)).to eq "1.00"
352
-
353
- money = Money.new(100, "JPY")
354
- expect(money.format(:symbol => false)).to eq "100"
355
- end
356
-
357
- it "defaults :symbol to true" do
358
- money = Money.new(100)
359
- expect(money.format).to eq "$1.00"
360
-
361
- money = Money.new(100, "GBP")
362
- expect(money.format).to eq "£1.00"
363
-
364
- money = Money.new(100, "EUR")
365
- expect(money.format).to eq "€1,00"
366
- end
367
-
368
- specify "(:symbol => false) returns a signed amount without a symbol" do
369
- money = Money.new(-100, "EUR")
370
- expect(money.format(:symbol => false)).to eq "-1,00"
371
-
372
- money = Money.new(100, "EUR")
373
- expect(money.format(:symbol => false,
374
- :sign_positive => true)).to eq "+1,00"
375
- end
376
- end
377
-
378
- describe ":decimal_mark option" do
379
- specify "(:decimal_mark => a decimal_mark string) works as documented" do
380
- expect(Money.us_dollar(100).format(:decimal_mark => ",")).to eq "$1,00"
381
- end
382
-
383
- it "defaults to '.' if currency isn't recognized" do
384
- expect(Money.new(100, "ZWD").format).to eq "$1.00"
385
- end
386
- end
387
-
388
- describe ":separator option" do
389
- specify "(:separator => a separator string) works as documented" do
390
- expect(Money.us_dollar(100).format(:separator => ",")).to eq "$1,00"
391
- end
392
- end
393
-
394
- describe ":south_asian_number_formatting delimiter" do
395
- before(:each) do
396
- Money::Currency.register(JSON.parse(INDIAN_BAR, :symbolize_names => true))
397
- end
398
-
399
- after(:each) do
400
- Money::Currency.unregister(JSON.parse(INDIAN_BAR, :symbolize_names => true))
401
- end
402
-
403
- specify "(:south_asian_number_formatting => true) works as documented" do
404
- expect(Money.new(10000000, 'INR').format(:south_asian_number_formatting => true, :symbol => false)).to eq "1,00,000.00"
405
- expect(Money.new(1000000000, 'INDIAN_BAR').format(:south_asian_number_formatting => true, :symbol => false)).to eq "1,00,000.0000"
406
- expect(Money.new(10000000).format(:south_asian_number_formatting => true)).to eq "$1,00,000.00"
407
- end
408
- end
409
-
410
- describe ":thousands_separator option" do
411
- specify "(:thousands_separator => a thousands_separator string) works as documented" do
412
- expect(Money.us_dollar(100000).format(:thousands_separator => ".")).to eq "$1.000.00"
413
- expect(Money.us_dollar(200000).format(:thousands_separator => "")).to eq "$2000.00"
414
- end
415
-
416
- specify "(:thousands_separator => false or nil) works as documented" do
417
- expect(Money.us_dollar(100000).format(:thousands_separator => false)).to eq "$1000.00"
418
- expect(Money.us_dollar(200000).format(:thousands_separator => nil)).to eq "$2000.00"
419
- end
420
-
421
- specify "(:delimiter => a delimiter string) works as documented" do
422
- expect(Money.us_dollar(100000).format(:delimiter => ".")).to eq "$1.000.00"
423
- expect(Money.us_dollar(200000).format(:delimiter => "")).to eq "$2000.00"
424
- end
425
-
426
- specify "(:delimiter => false or nil) works as documented" do
427
- expect(Money.us_dollar(100000).format(:delimiter => false)).to eq "$1000.00"
428
- expect(Money.us_dollar(200000).format(:delimiter => nil)).to eq "$2000.00"
429
- end
430
-
431
- it "defaults to ',' if currency isn't recognized" do
432
- expect(Money.new(100000, "ZWD").format).to eq "$1,000.00"
433
- end
434
-
435
- context "without i18n" do
436
- before { Money.use_i18n = false }
437
-
438
- it "should respect explicit overriding of thousands_separator/delimiter when decimal_mark/separator collide and there’s no decimal component for currencies that have no subunit" do
439
- expect(Money.new(300_000, 'ISK').format(:thousands_separator => ",", decimal_mark: '.')).to eq "kr300,000"
440
- end
441
-
442
- it "should respect explicit overriding of thousands_separator/delimiter when decimal_mark/separator collide and there’s no decimal component for currencies with subunits that drop_trailing_zeros" do
443
- expect(Money.new(300_000, 'USD').format(:thousands_separator => ".", decimal_mark: ',', drop_trailing_zeros: true)).to eq "$3.000"
444
- end
445
-
446
- after { Money.use_i18n = true}
447
- end
448
- end
449
-
450
- describe ":thousands_separator and :decimal_mark option" do
451
- specify "(:thousands_separator => a thousands_separator string, :decimal_mark => a decimal_mark string) works as documented" do
452
- expect(Money.new(123_456_789, "USD").format(thousands_separator: ".", decimal_mark: ",")).to eq("$1.234.567,89")
453
- expect(Money.new(987_654_321, "USD").format(thousands_separator: " ", decimal_mark: ".")).to eq("$9 876 543.21")
454
- end
455
- end
456
-
457
- describe ":html option" do
458
- specify "(:html => true) works as documented" do
459
- string = Money.ca_dollar(570).format(:html => true, :with_currency => true)
460
- expect(string).to eq "$5.70 <span class=\"currency\">CAD</span>"
461
- end
462
-
463
- specify "should fallback to symbol if entity is not available" do
464
- string = Money.new(570, 'DKK').format(:html => true)
465
- expect(string).to eq "5,70 kr."
466
- end
467
- end
468
-
469
- describe ":html_wrap_symbol option" do
470
- specify "(:html_wrap_symbol => true) works as documented" do
471
- string = Money.ca_dollar(570).format(:html_wrap_symbol => true)
472
- expect(string).to eq "<span class=\"currency_symbol\">$</span>5.70"
473
- end
474
- end
475
-
476
- describe ":symbol_position option" do
477
- it "inserts currency symbol before the amount when set to :before" do
478
- expect(Money.euro(1_234_567_12).format(:symbol_position => :before)).to eq "€1.234.567,12"
479
- end
480
-
481
- it "inserts currency symbol after the amount when set to :after" do
482
- expect(Money.us_dollar(1_000_000_000_12).format(:symbol_position => :after)).to eq "1,000,000,000.12 $"
483
- end
484
-
485
- it "raises an ArgumentError when passed an invalid option" do
486
- expect{Money.euro(0).format(:symbol_position => :befor)}.to raise_error(ArgumentError)
487
- end
488
- end
489
-
490
- describe ":sign_before_symbol option" do
491
- specify "(:sign_before_symbol => true) works as documented" do
492
- expect(Money.us_dollar(-100000).format(:sign_before_symbol => true)).to eq "-$1,000.00"
493
- end
494
-
495
- specify "(:sign_before_symbol => false) works as documented" do
496
- expect(Money.us_dollar(-100000).format(:sign_before_symbol => false)).to eq "$-1,000.00"
497
- expect(Money.us_dollar(-100000).format(:sign_before_symbol => nil)).to eq "$-1,000.00"
498
- end
499
- end
500
-
501
- describe ":symbol_before_without_space option" do
502
- it "does not insert space between currency symbol and amount when set to true" do
503
- expect(Money.euro(1_234_567_12).format(:symbol_position => :before, :symbol_before_without_space => true)).to eq "€1.234.567,12"
504
- end
505
-
506
- it "inserts space between currency symbol and amount when set to false" do
507
- expect(Money.euro(1_234_567_12).format(:symbol_position => :before, :symbol_before_without_space => false)).to eq "€ 1.234.567,12"
508
- end
509
-
510
- it "defaults to true" do
511
- expect(Money.euro(1_234_567_12).format(:symbol_position => :before)).to eq "€1.234.567,12"
512
- end
513
- end
514
-
515
- describe ":symbol_after_without_space option" do
516
- it "does not insert space between amount and currency symbol when set to true" do
517
- expect(Money.euro(1_234_567_12).format(:symbol_position => :after, :symbol_after_without_space => true)).to eq "1.234.567,12€"
518
- end
519
-
520
- it "inserts space between amount and currency symbol when set to false" do
521
- expect(Money.euro(1_234_567_12).format(:symbol_position => :after, :symbol_after_without_space => false)).to eq "1.234.567,12 €"
522
- end
523
-
524
- it "defaults to false" do
525
- expect(Money.euro(1_234_567_12).format(:symbol_position => :after)).to eq "1.234.567,12 €"
526
- end
527
- end
528
-
529
- describe ":sign_positive option" do
530
- specify "(:sign_positive => true, :sign_before_symbol => true) works as documented" do
531
- expect(Money.us_dollar( 0).format(:sign_positive => true, :sign_before_symbol => true)).to eq "$0.00"
532
- expect(Money.us_dollar( 100000).format(:sign_positive => true, :sign_before_symbol => true)).to eq "+$1,000.00"
533
- expect(Money.us_dollar(-100000).format(:sign_positive => true, :sign_before_symbol => true)).to eq "-$1,000.00"
534
- end
535
-
536
- specify "(:sign_positive => true, :sign_before_symbol => false) works as documented" do
537
- expect(Money.us_dollar( 0).format(:sign_positive => true, :sign_before_symbol => false)).to eq "$0.00"
538
- expect(Money.us_dollar( 100000).format(:sign_positive => true, :sign_before_symbol => false)).to eq "$+1,000.00"
539
- expect(Money.us_dollar( 100000).format(:sign_positive => true, :sign_before_symbol => nil)).to eq "$+1,000.00"
540
- expect(Money.us_dollar(-100000).format(:sign_positive => true, :sign_before_symbol => false)).to eq "$-1,000.00"
541
- expect(Money.us_dollar(-100000).format(:sign_positive => true, :sign_before_symbol => nil)).to eq "$-1,000.00"
542
- end
543
-
544
- specify "(:sign_positive => false, :sign_before_symbol => true) works as documented" do
545
- expect(Money.us_dollar( 100000).format(:sign_positive => false, :sign_before_symbol => true)).to eq "$1,000.00"
546
- expect(Money.us_dollar(-100000).format(:sign_positive => false, :sign_before_symbol => true)).to eq "-$1,000.00"
547
- end
548
-
549
- specify "(:sign_positive => false, :sign_before_symbol => false) works as documented" do
550
- expect(Money.us_dollar( 100000).format(:sign_positive => false, :sign_before_symbol => false)).to eq "$1,000.00"
551
- expect(Money.us_dollar( 100000).format(:sign_positive => false, :sign_before_symbol => nil)).to eq "$1,000.00"
552
- expect(Money.us_dollar(-100000).format(:sign_positive => false, :sign_before_symbol => false)).to eq "$-1,000.00"
553
- expect(Money.us_dollar(-100000).format(:sign_positive => false, :sign_before_symbol => nil)).to eq "$-1,000.00"
554
- end
555
- end
556
-
557
- describe ":rounded_infinite_precision option", :infinite_precision do
558
- it "does round fractional when set to true" do
559
- expect(Money.new(BigDecimal.new('12.1'), "USD").format(:rounded_infinite_precision => true)).to eq "$0.12"
560
- expect(Money.new(BigDecimal.new('12.5'), "USD").format(:rounded_infinite_precision => true)).to eq "$0.13"
561
- expect(Money.new(BigDecimal.new('123.1'), "BHD").format(:rounded_infinite_precision => true)).to eq "ب.د0.123"
562
- expect(Money.new(BigDecimal.new('123.5'), "BHD").format(:rounded_infinite_precision => true)).to eq "ب.د0.124"
563
- expect(Money.new(BigDecimal.new('100.1'), "USD").format(:rounded_infinite_precision => true)).to eq "$1.00"
564
- expect(Money.new(BigDecimal.new('109.5'), "USD").format(:rounded_infinite_precision => true)).to eq "$1.10"
565
- expect(Money.new(BigDecimal.new('1'), "MGA").format(:rounded_infinite_precision => true)).to eq "Ar0.2"
566
- end
567
-
568
- it "does not round fractional when set to false" do
569
- expect(Money.new(BigDecimal.new('12.1'), "USD").format(:rounded_infinite_precision => false)).to eq "$0.121"
570
- expect(Money.new(BigDecimal.new('12.5'), "USD").format(:rounded_infinite_precision => false)).to eq "$0.125"
571
- expect(Money.new(BigDecimal.new('123.1'), "BHD").format(:rounded_infinite_precision => false)).to eq "ب.د0.1231"
572
- expect(Money.new(BigDecimal.new('123.5'), "BHD").format(:rounded_infinite_precision => false)).to eq "ب.د0.1235"
573
- expect(Money.new(BigDecimal.new('100.1'), "USD").format(:rounded_infinite_precision => false)).to eq "$1.001"
574
- expect(Money.new(BigDecimal.new('109.5'), "USD").format(:rounded_infinite_precision => false)).to eq "$1.095"
575
- expect(Money.new(BigDecimal.new('1'), "MGA").format(:rounded_infinite_precision => false)).to eq "Ar0.1"
576
- end
577
-
578
- describe "with i18n = false" do
579
- before do
580
- Money.use_i18n = false
581
- end
582
-
583
- after do
584
- Money.use_i18n = true
585
- end
586
-
587
- it 'does round fractional when set to true' do
588
- expect(Money.new(BigDecimal.new('12.1'), "EUR").format(:rounded_infinite_precision => true)).to eq "€0,12"
589
- expect(Money.new(BigDecimal.new('12.5'), "EUR").format(:rounded_infinite_precision => true)).to eq "€0,13"
590
- expect(Money.new(BigDecimal.new('100.1'), "EUR").format(:rounded_infinite_precision => true)).to eq "€1,00"
591
- expect(Money.new(BigDecimal.new('109.5'), "EUR").format(:rounded_infinite_precision => true)).to eq "€1,10"
592
-
593
- expect(Money.new(BigDecimal.new('100012.1'), "EUR").format(:rounded_infinite_precision => true)).to eq "€1.000,12"
594
- expect(Money.new(BigDecimal.new('100012.5'), "EUR").format(:rounded_infinite_precision => true)).to eq "€1.000,13"
595
- end
596
- end
597
-
598
- describe "with i18n = true" do
599
- before do
600
- Money.use_i18n = true
601
- reset_i18n
602
- I18n.locale = :de
603
- I18n.backend.store_translations(
604
- :de,
605
- :number => { :currency => { :format => { :delimiter => ".", :separator => "," } } }
606
- )
607
- end
608
-
609
- after do
610
- reset_i18n
611
- I18n.locale = :en
612
- end
613
-
614
- it 'does round fractional when set to true' do
615
- expect(Money.new(BigDecimal.new('12.1'), "USD").format(:rounded_infinite_precision => true)).to eq "$0,12"
616
- expect(Money.new(BigDecimal.new('12.5'), "USD").format(:rounded_infinite_precision => true)).to eq "$0,13"
617
- expect(Money.new(BigDecimal.new('123.1'), "BHD").format(:rounded_infinite_precision => true)).to eq "ب.د0,123"
618
- expect(Money.new(BigDecimal.new('123.5'), "BHD").format(:rounded_infinite_precision => true)).to eq "ب.د0,124"
619
- expect(Money.new(BigDecimal.new('100.1'), "USD").format(:rounded_infinite_precision => true)).to eq "$1,00"
620
- expect(Money.new(BigDecimal.new('109.5'), "USD").format(:rounded_infinite_precision => true)).to eq "$1,10"
621
- expect(Money.new(BigDecimal.new('1'), "MGA").format(:rounded_infinite_precision => true)).to eq "Ar0,2"
622
- end
623
- end
624
- end
625
-
626
- context "when the monetary value is 0" do
627
- let(:money) { Money.us_dollar(0) }
628
-
629
- it "returns 'free' when :display_free is true" do
630
- expect(money.format(:display_free => true)).to eq 'free'
631
- end
632
-
633
- it "returns '$0.00' when :display_free is false or not given" do
634
- expect(money.format).to eq '$0.00'
635
- expect(money.format(:display_free => false)).to eq '$0.00'
636
- expect(money.format(:display_free => nil)).to eq '$0.00'
637
- end
638
-
639
- it "returns the value specified by :display_free if it's a string-like object" do
640
- expect(money.format(:display_free => 'gratis')).to eq 'gratis'
641
- end
642
- end
643
- end
644
-
645
- context "custom currencies with 4 decimal places" do
646
- before :each do
647
- Money::Currency.register(JSON.parse(BAR, :symbolize_names => true))
648
- Money::Currency.register(JSON.parse(EU4, :symbolize_names => true))
649
- end
650
-
651
- after :each do
652
- Money::Currency.unregister(JSON.parse(BAR, :symbolize_names => true))
653
- Money::Currency.unregister(JSON.parse(EU4, :symbolize_names => true))
654
- end
655
-
656
- it "respects custom subunit to unit, decimal and thousands separator" do
657
- expect(Money.new(4, "BAR").format).to eq "$0.0004"
658
- expect(Money.new(4, "EU4").format).to eq "€0,0004"
659
-
660
- expect(Money.new(24, "BAR").format).to eq "$0.0024"
661
- expect(Money.new(24, "EU4").format).to eq "€0,0024"
662
-
663
- expect(Money.new(324, "BAR").format).to eq "$0.0324"
664
- expect(Money.new(324, "EU4").format).to eq "€0,0324"
665
-
666
- expect(Money.new(5324, "BAR").format).to eq "$0.5324"
667
- expect(Money.new(5324, "EU4").format).to eq "€0,5324"
668
-
669
- expect(Money.new(65324, "BAR").format).to eq "$6.5324"
670
- expect(Money.new(65324, "EU4").format).to eq "€6,5324"
671
-
672
- expect(Money.new(865324, "BAR").format).to eq "$86.5324"
673
- expect(Money.new(865324, "EU4").format).to eq "€86,5324"
674
-
675
- expect(Money.new(1865324, "BAR").format).to eq "$186.5324"
676
- expect(Money.new(1865324, "EU4").format).to eq "€186,5324"
677
-
678
- expect(Money.new(33310034, "BAR").format).to eq "$3,331.0034"
679
- expect(Money.new(33310034, "EU4").format).to eq "€3.331,0034"
680
-
681
- expect(Money.new(88833310034, "BAR").format).to eq "$8,883,331.0034"
682
- expect(Money.new(88833310034, "EU4").format).to eq "€8.883.331,0034"
683
- end
684
-
685
- end
686
-
687
- context "currencies with ambiguous signs" do
688
-
689
- it "returns ambiguous signs when disambiguate is not set" do
690
- expect(Money.new(1999_98, "USD").format).to eq("$1,999.98")
691
- expect(Money.new(1999_98, "CAD").format).to eq("$1,999.98")
692
- expect(Money.new(1999_98, "DKK").format).to eq("1.999,98 kr.")
693
- expect(Money.new(1999_98, "NOK").format).to eq("1.999,98 kr")
694
- expect(Money.new(1999_98, "SEK").format).to eq("1 999,98 kr")
695
- end
696
-
697
- it "returns ambiguous signs when disambiguate is false" do
698
- expect(Money.new(1999_98, "USD").format(disambiguate: false)).to eq("$1,999.98")
699
- expect(Money.new(1999_98, "CAD").format(disambiguate: false)).to eq("$1,999.98")
700
- expect(Money.new(1999_98, "DKK").format(disambiguate: false)).to eq("1.999,98 kr.")
701
- expect(Money.new(1999_98, "NOK").format(disambiguate: false)).to eq("1.999,98 kr")
702
- expect(Money.new(1999_98, "SEK").format(disambiguate: false)).to eq("1 999,98 kr")
703
- end
704
-
705
- it "returns disambiguate signs when disambiguate: true" do
706
- expect(Money.new(1999_98, "USD").format(disambiguate: true)).to eq("US$1,999.98")
707
- expect(Money.new(1999_98, "CAD").format(disambiguate: true)).to eq("C$1,999.98")
708
- expect(Money.new(1999_98, "DKK").format(disambiguate: true)).to eq("1.999,98 DKK")
709
- expect(Money.new(1999_98, "NOK").format(disambiguate: true)).to eq("1.999,98 NOK")
710
- expect(Money.new(1999_98, "SEK").format(disambiguate: true)).to eq("1 999,98 SEK")
711
- end
712
-
713
- it "returns disambiguate signs when disambiguate: true and symbol: true" do
714
- expect(Money.new(1999_98, "USD").format(disambiguate: true, symbol: true)).to eq("US$1,999.98")
715
- expect(Money.new(1999_98, "CAD").format(disambiguate: true, symbol: true)).to eq("C$1,999.98")
716
- expect(Money.new(1999_98, "DKK").format(disambiguate: true, symbol: true)).to eq("1.999,98 DKK")
717
- expect(Money.new(1999_98, "NOK").format(disambiguate: true, symbol: true)).to eq("1.999,98 NOK")
718
- expect(Money.new(1999_98, "SEK").format(disambiguate: true, symbol: true)).to eq("1 999,98 SEK")
719
- end
720
-
721
- it "returns no signs when disambiguate: true and symbol: false" do
722
- expect(Money.new(1999_98, "USD").format(disambiguate: true, symbol: false)).to eq("1,999.98")
723
- expect(Money.new(1999_98, "CAD").format(disambiguate: true, symbol: false)).to eq("1,999.98")
724
- expect(Money.new(1999_98, "DKK").format(disambiguate: true, symbol: false)).to eq("1.999,98")
725
- expect(Money.new(1999_98, "NOK").format(disambiguate: true, symbol: false)).to eq("1.999,98")
726
- expect(Money.new(1999_98, "SEK").format(disambiguate: true, symbol: false)).to eq("1 999,98")
727
- end
728
-
729
- it "should never return an ambiguous format with disambiguate: true" do
730
- formatted_results = {}
731
-
732
- # When we format the same amount in all known currencies, disambiguate should return
733
- # all different values
734
- Money::Currency.all.each do |currency|
735
- format = Money.new(1999_98, currency).format(disambiguate: true)
736
- expect(formatted_results.keys).not_to include(format), "Format '#{format}' for #{currency} is ambiguous with currency #{formatted_results[format]}."
737
- formatted_results[format] = currency
738
- end
739
- end
740
-
741
- describe ":drop_trailing_zeros option" do
742
- specify "(:drop_trailing_zeros => true) works as documented" do
743
- expect(Money.new(89000, "BTC").format(:drop_trailing_zeros => true, :symbol => false)).to eq "0.00089"
744
- expect(Money.new(100089000, "BTC").format(:drop_trailing_zeros => true, :symbol => false)).to eq "1.00089"
745
- expect(Money.new(100000000, "BTC").format(:drop_trailing_zeros => true, :symbol => false)).to eq "1"
746
- expect(Money.new(110, "AUD").format(:drop_trailing_zeros => true, :symbol => false)).to eq "1.1"
747
- end
748
-
749
- specify "(:drop_trailing_zeros => false) works as documented" do
750
- expect(Money.new(89000, "BTC").format(:drop_trailing_zeros => false, :symbol => false)).to eq "0.00089000"
751
- expect(Money.new(100089000, "BTC").format(:drop_trailing_zeros => false, :symbol => false)).to eq "1.00089000"
752
- expect(Money.new(100000000, "BTC").format(:drop_trailing_zeros => false, :symbol => false)).to eq "1.00000000"
753
- expect(Money.new(110, "AUD").format(:drop_trailing_zeros => false, :symbol => false)).to eq "1.10"
754
- end
755
- end
756
- end
757
- end