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,265 +0,0 @@
1
- require 'json'
2
- require 'yaml'
3
-
4
- class Money
5
- module Bank
6
- describe VariableExchange do
7
-
8
- describe "#initialize" do
9
- context "without &block" do
10
- let(:bank) {
11
- VariableExchange.new.tap do |bank|
12
- bank.add_rate('USD', 'EUR', 1.33)
13
- end
14
- }
15
-
16
- describe '#store' do
17
- it 'defaults to Memory store' do
18
- expect(bank.store).to be_a(Money::RatesStore::Memory)
19
- end
20
- end
21
-
22
- describe 'custom store' do
23
- let(:custom_store) { Object.new }
24
-
25
- let(:bank) { VariableExchange.new(custom_store) }
26
-
27
- it 'sets #store to be custom store' do
28
- expect(bank.store).to eql(custom_store)
29
- end
30
- end
31
-
32
- describe "#exchange_with" do
33
- it "accepts str" do
34
- expect { bank.exchange_with(Money.new(100, 'USD'), 'EUR') }.to_not raise_exception
35
- end
36
-
37
- it "accepts currency" do
38
- expect { bank.exchange_with(Money.new(100, 'USD'), Currency.wrap('EUR')) }.to_not raise_exception
39
- end
40
-
41
- it "exchanges one currency to another" do
42
- expect(bank.exchange_with(Money.new(100, 'USD'), 'EUR')).to eq Money.new(133, 'EUR')
43
- end
44
-
45
- it "truncates extra digits" do
46
- expect(bank.exchange_with(Money.new(10, 'USD'), 'EUR')).to eq Money.new(13, 'EUR')
47
- end
48
-
49
- it "raises an UnknownCurrency exception when an unknown currency is requested" do
50
- expect { bank.exchange_with(Money.new(100, 'USD'), 'BBB') }.to raise_exception(Currency::UnknownCurrency)
51
- end
52
-
53
- it "raises an UnknownRate exception when an unknown rate is requested" do
54
- expect { bank.exchange_with(Money.new(100, 'USD'), 'JPY') }.to raise_exception(UnknownRate)
55
- end
56
-
57
- #it "rounds the exchanged result down" do
58
- # bank.add_rate("USD", "EUR", 0.788332676)
59
- # bank.add_rate("EUR", "YEN", 122.631477)
60
- # expect(bank.exchange_with(Money.new(10_00, "USD"), "EUR")).to eq Money.new(788, "EUR")
61
- # expect(bank.exchange_with(Money.new(500_00, "EUR"), "YEN")).to eq Money.new(6131573, "YEN")
62
- #end
63
-
64
- it "accepts a custom truncation method" do
65
- proc = Proc.new { |n| n.ceil }
66
- expect(bank.exchange_with(Money.new(10, 'USD'), 'EUR', &proc)).to eq Money.new(14, 'EUR')
67
- end
68
-
69
- it 'works with big numbers' do
70
- amount = 10**20
71
- expect(bank.exchange_with(Money.usd(amount), :EUR)).to eq Money.eur(1.33 * amount)
72
- end
73
-
74
- it "preserves the class in the result when given a subclass of Money" do
75
- special_money_class = Class.new(Money)
76
- expect(bank.exchange_with(special_money_class.new(100, 'USD'), 'EUR')).to be_a special_money_class
77
- end
78
-
79
- it "doesn't loose precision when handling larger amounts" do
80
- expect(bank.exchange_with(Money.new(100_000_000_000_000_01, 'USD'), 'EUR')).to eq Money.new(133_000_000_000_000_01, 'EUR')
81
- end
82
- end
83
- end
84
-
85
- context "with &block" do
86
- let(:bank) {
87
- proc = Proc.new { |n| n.ceil }
88
- VariableExchange.new(&proc).tap do |bank|
89
- bank.add_rate('USD', 'EUR', 1.33)
90
- end
91
- }
92
-
93
- describe "#exchange_with" do
94
- it "uses the stored truncation method" do
95
- expect(bank.exchange_with(Money.new(10, 'USD'), 'EUR')).to eq Money.new(14, 'EUR')
96
- end
97
-
98
- it "accepts a custom truncation method" do
99
- proc = Proc.new { |n| n.ceil + 1 }
100
- expect(bank.exchange_with(Money.new(10, 'USD'), 'EUR', &proc)).to eq Money.new(15, 'EUR')
101
- end
102
- end
103
- end
104
- end
105
-
106
- describe "#add_rate" do
107
- it 'delegates to store#add_rate' do
108
- expect(subject.store).to receive(:add_rate).with('USD', 'EUR', 1.25).and_return 1.25
109
- expect(subject.add_rate('USD', 'EUR', 1.25)).to eql 1.25
110
- end
111
-
112
- it "adds rates with correct ISO codes" do
113
- expect(subject.store).to receive(:add_rate).with('USD', 'EUR', 0.788332676)
114
- subject.add_rate("USD", "EUR", 0.788332676)
115
-
116
- expect(subject.store).to receive(:add_rate).with('EUR', 'JPY', 122.631477)
117
- subject.add_rate("EUR", "YEN", 122.631477)
118
- end
119
-
120
- it "treats currency names case-insensitively" do
121
- subject.add_rate("usd", "eur", 1)
122
- expect(subject.get_rate('USD', 'EUR')).to eq 1
123
- end
124
- end
125
-
126
- describe "#set_rate" do
127
- it 'delegates to store#add_rate' do
128
- expect(subject.store).to receive(:add_rate).with('USD', 'EUR', 1.25).and_return 1.25
129
- expect(subject.set_rate('USD', 'EUR', 1.25)).to eql 1.25
130
- end
131
-
132
- it "sets a rate" do
133
- subject.set_rate('USD', 'EUR', 1.25)
134
- expect(subject.store.get_rate('USD', 'EUR')).to eq 1.25
135
- end
136
-
137
- it "raises an UnknownCurrency exception when an unknown currency is passed" do
138
- expect { subject.set_rate('AAA', 'BBB', 1.25) }.to raise_exception(Currency::UnknownCurrency)
139
- end
140
- end
141
-
142
- describe "#get_rate" do
143
- it "returns a rate" do
144
- subject.set_rate('USD', 'EUR', 1.25)
145
- expect(subject.get_rate('USD', 'EUR')).to eq 1.25
146
- end
147
-
148
- it "raises an UnknownCurrency exception when an unknown currency is passed" do
149
- expect { subject.get_rate('AAA', 'BBB') }.to raise_exception(Currency::UnknownCurrency)
150
- end
151
-
152
- it "delegates options to store, options are a no-op" do
153
- expect(subject.store).to receive(:get_rate).with('USD', 'EUR')
154
- subject.get_rate('USD', 'EUR', :without_mutex => true)
155
- end
156
- end
157
-
158
- describe "#export_rates" do
159
- before :each do
160
- subject.set_rate('USD', 'EUR', 1.25)
161
- subject.set_rate('USD', 'JPY', 2.55)
162
-
163
- @rates = { "USD_TO_EUR" => 1.25, "USD_TO_JPY" => 2.55 }
164
- end
165
-
166
- context "with format == :json" do
167
- it "should return rates formatted as json" do
168
- json = subject.export_rates(:json)
169
- expect(JSON.load(json)).to eq @rates
170
- end
171
- end
172
-
173
- context "with format == :ruby" do
174
- it "should return rates formatted as ruby objects" do
175
- expect(Marshal.load(subject.export_rates(:ruby))).to eq @rates
176
- end
177
- end
178
-
179
- context "with format == :yaml" do
180
- it "should return rates formatted as yaml" do
181
- yaml = subject.export_rates(:yaml)
182
- expect(YAML.load(yaml)).to eq @rates
183
- end
184
- end
185
-
186
- context "with unknown format" do
187
- it "raises Money::Bank::UnknownRateFormat" do
188
- expect { subject.export_rates(:foo)}.to raise_error UnknownRateFormat
189
- end
190
- end
191
-
192
- context "with :file provided" do
193
- it "writes rates to file" do
194
- f = double('IO')
195
- expect(File).to receive(:open).with('null', 'w').and_yield(f)
196
- expect(f).to receive(:write).with(JSON.dump(@rates))
197
-
198
- subject.export_rates(:json, 'null')
199
- end
200
- end
201
-
202
- it "delegates execution to store, options are a no-op" do
203
- expect(subject.store).to receive(:transaction)
204
- subject.export_rates(:yaml, nil, :foo => 1)
205
- end
206
-
207
- end
208
-
209
- describe "#import_rates" do
210
- context "with format == :json" do
211
- it "loads the rates provided" do
212
- s = '{"USD_TO_EUR":1.25,"USD_TO_JPY":2.55}'
213
- subject.import_rates(:json, s)
214
- expect(subject.get_rate('USD', 'EUR')).to eq 1.25
215
- expect(subject.get_rate('USD', 'JPY')).to eq 2.55
216
- end
217
- end
218
-
219
- context "with format == :ruby" do
220
- it "loads the rates provided" do
221
- s = Marshal.dump({"USD_TO_EUR"=>1.25,"USD_TO_JPY"=>2.55})
222
- subject.import_rates(:ruby, s)
223
- expect(subject.get_rate('USD', 'EUR')).to eq 1.25
224
- expect(subject.get_rate('USD', 'JPY')).to eq 2.55
225
- end
226
- end
227
-
228
- context "with format == :yaml" do
229
- it "loads the rates provided" do
230
- s = "--- \nUSD_TO_EUR: 1.25\nUSD_TO_JPY: 2.55\n"
231
- subject.import_rates(:yaml, s)
232
- expect(subject.get_rate('USD', 'EUR')).to eq 1.25
233
- expect(subject.get_rate('USD', 'JPY')).to eq 2.55
234
- end
235
- end
236
-
237
- context "with unknown format" do
238
- it "raises Money::Bank::UnknownRateFormat" do
239
- expect { subject.import_rates(:foo, "")}.to raise_error UnknownRateFormat
240
- end
241
- end
242
-
243
- it "delegates execution to store#transaction" do
244
- expect(subject.store).to receive(:transaction)
245
- s = "--- \nUSD_TO_EUR: 1.25\nUSD_TO_JPY: 2.55\n"
246
- subject.import_rates(:yaml, s, :foo => 1)
247
- end
248
-
249
- end
250
-
251
- describe "#marshal_dump" do
252
- it "does not raise an error" do
253
- expect { Marshal.dump(subject) }.to_not raise_error
254
- end
255
-
256
- it "works with Marshal.load" do
257
- bank = Marshal.load(Marshal.dump(subject))
258
-
259
- expect(bank.rates).to eq subject.rates
260
- expect(bank.rounding_method).to eq subject.rounding_method
261
- end
262
- end
263
- end
264
- end
265
- end
@@ -1,11 +0,0 @@
1
- # encoding: utf-8
2
-
3
- describe Money::Currency::Heuristics do
4
- describe "#analyze_string" do
5
- let(:it) { Money::Currency }
6
-
7
- it "it raises deprecation error" do
8
- expect{ it.analyze('123') }.to raise_error(StandardError, 'Heuristics deprecated, add `gem "money-heuristics"` to Gemfile')
9
- end
10
- end
11
- end
@@ -1,19 +0,0 @@
1
- # encoding: utf-8
2
-
3
- describe Money::Currency::Loader do
4
- class CurrencyLoader
5
- include Money::Currency::Loader
6
- end
7
-
8
- let(:loader) { CurrencyLoader.new }
9
-
10
- it "returns a currency table hash" do
11
- expect(loader.load_currencies).to be_a Hash
12
- end
13
-
14
- it "parse currency_iso.json & currency_non_iso.json & currency_backwards_compatible.json" do
15
- expect(loader).to receive(:parse_currency_file).exactly(3).times.and_return({})
16
-
17
- loader.load_currencies
18
- end
19
- end
@@ -1,359 +0,0 @@
1
- # encoding: utf-8
2
-
3
- class Money
4
- describe Currency do
5
-
6
- FOO = '{ "priority": 1, "iso_code": "FOO", "iso_numeric": "840", "name": "United States Dollar", "symbol": "$", "subunit": "Cent", "subunit_to_unit": 1000, "symbol_first": true, "html_entity": "$", "decimal_mark": ".", "thousands_separator": ",", "smallest_denomination": 1 }'
7
-
8
- def register_foo(opts={})
9
- foo_attrs = JSON.parse(FOO, :symbolize_names => true)
10
- # Pass an array of attribute names to 'skip' to remove them from the 'FOO'
11
- # json before registering foo as a currency.
12
- Array(opts[:skip]).each { |attr| foo_attrs.delete(attr) }
13
- Money::Currency.register(foo_attrs)
14
- end
15
-
16
- def unregister_foo
17
- Currency.unregister(JSON.parse(FOO, :symbolize_names => true))
18
- end
19
-
20
- describe "UnknownCurrency" do
21
- it "is a subclass of ArgumentError" do
22
- expect(Currency::UnknownCurrency < ArgumentError).to be true
23
- end
24
- end
25
-
26
- describe ".find" do
27
- before { register_foo }
28
- after { unregister_foo }
29
-
30
- it "returns currency matching given id" do
31
- expected = Currency.new(:foo)
32
- expect(Currency.find(:foo)).to be expected
33
- expect(Currency.find(:FOO)).to be expected
34
- expect(Currency.find("foo")).to be expected
35
- expect(Currency.find("FOO")).to be expected
36
- end
37
-
38
- it "returns nil unless currency matching given id" do
39
- expect(Currency.find("ZZZ")).to be_nil
40
- end
41
- end
42
-
43
- describe ".find_by_iso_numeric" do
44
- it "returns currency matching given numeric code" do
45
- expect(Currency.find_by_iso_numeric(978)).to eq Currency.new(:eur)
46
- expect(Currency.find_by_iso_numeric(208)).not_to eq Currency.new(:eur)
47
- expect(Currency.find_by_iso_numeric('840')).to eq Currency.new(:usd)
48
-
49
- class Mock
50
- def to_s
51
- '208'
52
- end
53
- end
54
- expect(Currency.find_by_iso_numeric(Mock.new)).to eq Currency.new(:dkk)
55
- expect(Currency.find_by_iso_numeric(Mock.new)).not_to eq Currency.new(:usd)
56
- end
57
-
58
- it "returns nil if no currency has the given numeric code" do
59
- expect(Currency.find_by_iso_numeric('non iso 4217 numeric code')).to be_nil
60
- expect(Currency.find_by_iso_numeric(0)).to be_nil
61
- end
62
- end
63
-
64
- describe ".wrap" do
65
- it "returns nil if object is nil" do
66
- expect(Currency.wrap(nil)).to be_nil
67
- expect(Currency.wrap(Currency.new(:usd))).to eq Currency.new(:usd)
68
- expect(Currency.wrap(:usd)).to eq Currency.new(:usd)
69
- end
70
- end
71
-
72
- describe ".all" do
73
- it "returns an array of currencies" do
74
- expect(Currency.all).to include Currency.new(:usd)
75
- end
76
- it "includes registered currencies" do
77
- register_foo
78
- expect(Currency.all).to include Currency.new(:foo)
79
- unregister_foo
80
- end
81
- it 'is sorted by priority' do
82
- expect(Currency.all.first.priority).to eq 1
83
- end
84
- it "raises a MissingAttributeError if any currency has no priority" do
85
- register_foo(:skip => :priority)
86
-
87
- expect{Money::Currency.all}.to \
88
- raise_error(Money::Currency::MissingAttributeError, /foo.*priority/)
89
- unregister_foo
90
- end
91
- end
92
-
93
-
94
- describe ".register" do
95
- after { Currency.unregister(iso_code: "XXX") if Currency.find("XXX") }
96
-
97
- it "registers a new currency" do
98
- Currency.register(
99
- iso_code: "XXX",
100
- name: "Golden Doubloon",
101
- symbol: "%",
102
- subunit_to_unit: 100
103
- )
104
- new_currency = Currency.find("XXX")
105
- expect(new_currency).not_to be_nil
106
- expect(new_currency.name).to eq "Golden Doubloon"
107
- expect(new_currency.symbol).to eq "%"
108
- end
109
-
110
- specify ":iso_code must be present" do
111
- expect {
112
- Currency.register(name: "New Currency")
113
- }.to raise_error(KeyError)
114
- end
115
- end
116
-
117
-
118
- describe ".unregister" do
119
- it "unregisters a currency" do
120
- Currency.register(iso_code: "XXX")
121
- expect(Currency.find("XXX")).not_to be_nil # Sanity check
122
- Currency.unregister(iso_code: "XXX")
123
- expect(Currency.find("XXX")).to be_nil
124
- end
125
-
126
- it "returns true iff the currency existed" do
127
- Currency.register(iso_code: "XXX")
128
- expect(Currency.unregister(iso_code: "XXX")).to be_truthy
129
- expect(Currency.unregister(iso_code: "XXX")).to be_falsey
130
- end
131
-
132
- it "can be passed an ISO code" do
133
- Currency.register(iso_code: "XXX")
134
- Currency.register(iso_code: "YYZ")
135
- # Test with string:
136
- Currency.unregister("XXX")
137
- expect(Currency.find("XXX")).to be_nil
138
- # Test with symbol:
139
- Currency.unregister(:yyz)
140
- expect(Currency.find(:yyz)).to be_nil
141
- end
142
- end
143
-
144
-
145
- describe ".each" do
146
- it "yields each currency to the block" do
147
- expect(Currency).to respond_to(:each)
148
- currencies = []
149
- Currency.each do |currency|
150
- currencies.push(currency)
151
- end
152
-
153
- # Don't bother testing every single currency
154
- expect(currencies[0]).to eq Currency.all[0]
155
- expect(currencies[1]).to eq Currency.all[1]
156
- expect(currencies[-1]).to eq Currency.all[-1]
157
- end
158
- end
159
-
160
-
161
- it "implements Enumerable" do
162
- expect(Currency).to respond_to(:all?)
163
- expect(Currency).to respond_to(:each_with_index)
164
- expect(Currency).to respond_to(:map)
165
- expect(Currency).to respond_to(:select)
166
- expect(Currency).to respond_to(:reject)
167
- end
168
-
169
-
170
- describe "#initialize" do
171
- before { Currency._instances.clear }
172
-
173
- it "lookups data from loaded config" do
174
- currency = Currency.new("USD")
175
- expect(currency.id).to eq :usd
176
- expect(currency.priority).to eq 1
177
- expect(currency.iso_code).to eq "USD"
178
- expect(currency.iso_numeric).to eq "840"
179
- expect(currency.name).to eq "United States Dollar"
180
- expect(currency.decimal_mark).to eq "."
181
- expect(currency.separator).to eq "."
182
- expect(currency.thousands_separator).to eq ","
183
- expect(currency.delimiter).to eq ","
184
- expect(currency.smallest_denomination).to eq 1
185
- end
186
-
187
- it 'caches instances' do
188
- currency = Currency.new("USD")
189
-
190
- expect(Currency._instances.length).to eq 1
191
- expect(Currency._instances["usd"].object_id).to eq currency.object_id
192
- end
193
-
194
- it "raises UnknownCurrency with unknown currency" do
195
- expect { Currency.new("xxx") }.to raise_error(Currency::UnknownCurrency, /xxx/)
196
- end
197
-
198
- it 'returns old object for the same :key' do
199
- expect(Currency.new("USD")).to be(Currency.new("USD"))
200
- expect(Currency.new("USD")).to be(Currency.new(:usd))
201
- expect(Currency.new("USD")).to be(Currency.new(:USD))
202
- expect(Currency.new("USD")).to be(Currency.new('usd'))
203
- expect(Currency.new("USD")).to be(Currency.new('Usd'))
204
- end
205
-
206
- it 'returns new object for the different :key' do
207
- expect(Currency.new("USD")).to_not be(Currency.new("EUR"))
208
- end
209
-
210
- it 'is thread safe' do
211
- ids = []
212
- 2.times.map{ Thread.new{ ids << Currency.new("USD").object_id }}.each(&:join)
213
- expect(ids.uniq.length).to eq(1)
214
- end
215
- end
216
-
217
- describe "#<=>" do
218
- it "compares objects by priority" do
219
- expect(Currency.new(:cad)).to be > Currency.new(:usd)
220
- expect(Currency.new(:usd)).to be < Currency.new(:eur)
221
- end
222
-
223
- it "compares by id when priority is the same" do
224
- Currency.register(iso_code: "ABD", priority: 15)
225
- Currency.register(iso_code: "ABC", priority: 15)
226
- Currency.register(iso_code: "ABE", priority: 15)
227
- abd = Currency.find("ABD")
228
- abc = Currency.find("ABC")
229
- abe = Currency.find("ABE")
230
- expect(abd).to be > abc
231
- expect(abe).to be > abd
232
- Currency.unregister("ABD")
233
- Currency.unregister("ABC")
234
- Currency.unregister("ABE")
235
- end
236
-
237
- context "when one of the currencies has no 'priority' set" do
238
- it "compares by id" do
239
- Currency.register(iso_code: "ABD") # No priority
240
- abd = Currency.find(:abd)
241
- usd = Currency.find(:usd)
242
- expect(abd).to be < usd
243
- Currency.unregister(iso_code: "ABD")
244
- end
245
- end
246
- end
247
-
248
- describe "#==" do
249
- it "returns true if self === other" do
250
- currency = Currency.new(:eur)
251
- expect(currency).to eq currency
252
- end
253
-
254
- it "returns true if the id is equal ignorning case" do
255
- expect(Currency.new(:eur)).to eq Currency.new(:eur)
256
- expect(Currency.new(:eur)).to eq Currency.new(:EUR)
257
- expect(Currency.new(:eur)).not_to eq Currency.new(:usd)
258
- end
259
-
260
- it "allows direct comparison of currencies and symbols/strings" do
261
- expect(Currency.new(:eur)).to eq 'eur'
262
- expect(Currency.new(:eur)).to eq 'EUR'
263
- expect(Currency.new(:eur)).to eq :eur
264
- expect(Currency.new(:eur)).to eq :EUR
265
- expect(Currency.new(:eur)).not_to eq 'usd'
266
- end
267
-
268
- it "allows comparison with nil and returns false" do
269
- expect(Currency.new(:eur)).not_to be_nil
270
- end
271
- end
272
-
273
- describe "#eql?" do
274
- it "returns true if #== returns true" do
275
- expect(Currency.new(:eur).eql?(Currency.new(:eur))).to be true
276
- expect(Currency.new(:eur).eql?(Currency.new(:usd))).to be false
277
- end
278
- end
279
-
280
- describe "#hash" do
281
- it "returns the same value for equal objects" do
282
- expect(Currency.new(:eur).hash).to eq Currency.new(:eur).hash
283
- expect(Currency.new(:eur).hash).not_to eq Currency.new(:usd).hash
284
- end
285
-
286
- it "can be used to return the intersection of Currency object arrays" do
287
- intersection = [Currency.new(:eur), Currency.new(:usd)] & [Currency.new(:eur)]
288
- expect(intersection).to eq [Currency.new(:eur)]
289
- end
290
- end
291
-
292
- describe "#inspect" do
293
- it "works as documented" do
294
- expect(Currency.new(:usd).inspect).to eq %Q{#<Money::Currency id: usd, priority: 1, symbol_first: true, thousands_separator: ,, html_entity: $, decimal_mark: ., name: United States Dollar, symbol: $, subunit_to_unit: 100, exponent: 2, iso_code: USD, iso_numeric: 840, subunit: Cent, smallest_denomination: 1>}
295
- end
296
- end
297
-
298
- describe "#to_s" do
299
- it "works as documented" do
300
- expect(Currency.new(:usd).to_s).to eq("USD")
301
- expect(Currency.new(:eur).to_s).to eq("EUR")
302
- end
303
- end
304
-
305
- describe "#to_str" do
306
- it "works as documented" do
307
- expect(Currency.new(:usd).to_str).to eq("USD")
308
- expect(Currency.new(:eur).to_str).to eq("EUR")
309
- end
310
- end
311
-
312
- describe "#to_sym" do
313
- it "works as documented" do
314
- expect(Currency.new(:usd).to_sym).to eq(:USD)
315
- expect(Currency.new(:eur).to_sym).to eq(:EUR)
316
- end
317
- end
318
-
319
- describe "#to_currency" do
320
- it "works as documented" do
321
- usd = Currency.new(:usd)
322
- expect(usd.to_currency).to eq usd
323
- end
324
-
325
- it "doesn't create new symbols indefinitely" do
326
- expect { Currency.new("bogus") }.to raise_exception(Currency::UnknownCurrency)
327
- expect(Symbol.all_symbols.map{|s| s.to_s}).not_to include("bogus")
328
- end
329
- end
330
-
331
- describe "#code" do
332
- it "works as documented" do
333
- expect(Currency.new(:usd).code).to eq "$"
334
- expect(Currency.new(:azn).code).to eq "\u20BC"
335
- end
336
- end
337
-
338
- describe "#exponent" do
339
- it "conforms to iso 4217" do
340
- expect(Currency.new(:jpy).exponent).to eq 0
341
- expect(Currency.new(:usd).exponent).to eq 2
342
- expect(Currency.new(:iqd).exponent).to eq 3
343
- end
344
- end
345
-
346
- describe "#decimal_places" do
347
- it "proper places for known currency" do
348
- expect(Currency.new(:mro).decimal_places).to eq 1
349
- expect(Currency.new(:usd).decimal_places).to eq 2
350
- end
351
-
352
- it "proper places for custom currency" do
353
- register_foo
354
- expect(Currency.new(:foo).decimal_places).to eq 3
355
- unregister_foo
356
- end
357
- end
358
- end
359
- end