money 3.7.1 → 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. data/CHANGELOG.md +384 -351
  2. data/LICENSE +21 -21
  3. data/README.md +243 -214
  4. data/Rakefile +49 -49
  5. data/lib/money.rb +28 -27
  6. data/lib/money/bank/base.rb +131 -131
  7. data/lib/money/bank/variable_exchange.rb +252 -252
  8. data/lib/money/core_extensions.rb +82 -82
  9. data/lib/money/currency.rb +263 -422
  10. data/lib/money/currency_loader.rb +19 -0
  11. data/lib/money/money.rb +405 -405
  12. data/lib/money/money/arithmetic.rb +246 -246
  13. data/lib/money/money/formatting.rb +260 -244
  14. data/lib/money/money/parsing.rb +350 -350
  15. data/money.gemspec +29 -35
  16. data/spec/bank/base_spec.rb +72 -72
  17. data/spec/bank/variable_exchange_spec.rb +238 -238
  18. data/spec/core_extensions_spec.rb +158 -158
  19. data/spec/currency_spec.rb +120 -133
  20. data/spec/money/arithmetic_spec.rb +479 -479
  21. data/spec/money/formatting_spec.rb +383 -375
  22. data/spec/money/parsing_spec.rb +197 -197
  23. data/spec/money_spec.rb +292 -292
  24. data/spec/spec_helper.rb +28 -28
  25. metadata +54 -126
  26. data/lib/money.rbc +0 -184
  27. data/lib/money/bank/base.rbc +0 -818
  28. data/lib/money/bank/variable_exchange.rbc +0 -2550
  29. data/lib/money/core_extensions.rbc +0 -664
  30. data/lib/money/currency.rbc +0 -22708
  31. data/lib/money/money.rbc +0 -3861
  32. data/lib/money/money/arithmetic.rbc +0 -2778
  33. data/lib/money/money/formatting.rbc +0 -2265
  34. data/lib/money/money/parsing.rbc +0 -2737
  35. data/spec/bank/base_spec.rbc +0 -2461
  36. data/spec/bank/variable_exchange_spec.rbc +0 -7541
  37. data/spec/core_extensions_spec.rbc +0 -5921
  38. data/spec/currency_spec.rbc +0 -4535
  39. data/spec/money/arithmetic_spec.rbc +0 -25140
  40. data/spec/money/formatting_spec.rbc +0 -12545
  41. data/spec/money/parsing_spec.rbc +0 -6511
  42. data/spec/money_spec.rbc +0 -9824
  43. data/spec/spec_helper.rbc +0 -575
data/money.gemspec CHANGED
@@ -1,35 +1,29 @@
1
- # -*- encoding: utf-8 -*-
2
- Gem::Specification.new do |s|
3
- s.name = "money"
4
- s.version = "3.7.1"
5
- s.platform = Gem::Platform::RUBY
6
- s.authors = ["Tobias Luetke", "Hongli Lai", "Jeremy McNevin",
7
- "Shane Emmons", "Simone Carletti", "Jean-Louis Giordano",
8
- "Joshua Clayton", "Bodaniel Jeanes", "Tobias Schmidt",
9
- "Chris Kampmeier", "Romain Gérard", "Eloy", "Josh Delsman",
10
- "Pelle Braendgaard", "Tom Lianza", "James Cotterill",
11
- "François Beausoleil", "Abhay Kumar", "pconnor",
12
- "Christian Billen", "Ilia Lobsanov", "Andrew White",
13
- ]
14
- s.email = ["hongli@phusion.nl", "semmons99+RubyMoney@gmail.com"]
15
- s.homepage = "http://money.rubyforge.org"
16
- s.summary = "Money and currency exchange support library."
17
- s.description = "This library aids one in handling money and different currencies."
18
-
19
- s.required_rubygems_version = ">= 1.3.6"
20
- s.rubyforge_project = "money"
21
-
22
- s.add_dependency "i18n", "~> 0.4"
23
-
24
- s.add_development_dependency "rspec", ">= 2.0.0"
25
- s.add_development_dependency "yard"
26
- s.add_development_dependency "json"
27
-
28
- s.requirements << "json if you plan to import/export rates formatted as json"
29
-
30
- s.files = Dir.glob("{lib,spec}/**/*")
31
- s.files += %w(CHANGELOG.md LICENSE README.md)
32
- s.files += %w(Rakefile .gemtest money.gemspec)
33
-
34
- s.require_path = "lib"
35
- end
1
+ # -*- encoding: utf-8 -*-
2
+ Gem::Specification.new do |s|
3
+ s.name = "money"
4
+ s.version = "4.0.0"
5
+ s.platform = Gem::Platform::RUBY
6
+ s.authors = ["Tobias Luetke", "Hongli Lai", "Jeremy McNevin",
7
+ "Shane Emmons", "Simone Carletti"]
8
+ s.email = ["semmons99+RubyMoney@gmail.com"]
9
+ s.homepage = "http://money.rubyforge.org"
10
+ s.summary = "Money and currency exchange support library."
11
+ s.description = "This library aids one in handling money and different currencies."
12
+
13
+ s.required_rubygems_version = ">= 1.3.6"
14
+ s.rubyforge_project = "money"
15
+
16
+ s.add_dependency "i18n", "~> 0.4"
17
+ s.add_dependency "json"
18
+
19
+ s.add_development_dependency "rspec", ">= 2.0.0"
20
+ s.add_development_dependency "yard"
21
+
22
+ s.requirements << "json"
23
+
24
+ s.files = Dir.glob("{lib,spec}/**/*")
25
+ s.files += %w(CHANGELOG.md LICENSE README.md)
26
+ s.files += %w(Rakefile .gemtest money.gemspec)
27
+
28
+ s.require_path = "lib"
29
+ end
@@ -1,72 +1,72 @@
1
- require "spec_helper"
2
-
3
- describe Money::Bank::Base do
4
- before :each do
5
- @bank = Money::Bank::Base.new
6
- end
7
-
8
- describe '#new with &block' do
9
- it 'should store @rounding_method' do
10
- proc = Proc.new{|n| n.ceil}
11
- bank = Money::Bank::Base.new(&proc)
12
- bank.rounding_method.should == proc
13
- end
14
- end
15
-
16
- describe '#setup' do
17
- it 'should call #setup after #initialize' do
18
- class MyBank < Money::Bank::Base
19
- attr_reader :setup_called
20
-
21
- def setup
22
- @setup_called = true
23
- end
24
- end
25
-
26
- bank = MyBank.new
27
- bank.setup_called.should == true
28
- end
29
- end
30
-
31
- describe '#exchange_with' do
32
- it 'should raise NotImplementedError' do
33
- lambda { @bank.exchange_with(Money.new(100, 'USD'), 'EUR') }.should raise_exception(NotImplementedError)
34
- end
35
- end
36
-
37
- describe '#same_currency?' do
38
- it 'should accept str/str' do
39
- lambda{@bank.send(:same_currency?, 'USD', 'EUR')}.should_not raise_exception
40
- end
41
-
42
- it 'should accept currency/str' do
43
- lambda{@bank.send(:same_currency?, Money::Currency.wrap('USD'), 'EUR')}.should_not raise_exception
44
- end
45
-
46
- it 'should accept str/currency' do
47
- lambda{@bank.send(:same_currency?, 'USD', Money::Currency.wrap('EUR'))}.should_not raise_exception
48
- end
49
-
50
- it 'should accept currency/currency' do
51
- lambda{@bank.send(:same_currency?, Money::Currency.wrap('USD'), Money::Currency.wrap('EUR'))}.should_not raise_exception
52
- end
53
-
54
- it 'should return `true` when currencies match' do
55
- @bank.send(:same_currency?, 'USD', 'USD').should == true
56
- @bank.send(:same_currency?, Money::Currency.wrap('USD'), 'USD').should == true
57
- @bank.send(:same_currency?, 'USD', Money::Currency.wrap('USD')).should == true
58
- @bank.send(:same_currency?, Money::Currency.wrap('USD'), Money::Currency.wrap('USD')).should == true
59
- end
60
-
61
- it 'should return `false` when currencies do not match' do
62
- @bank.send(:same_currency?, 'USD', 'EUR').should == false
63
- @bank.send(:same_currency?, Money::Currency.wrap('USD'), 'EUR').should == false
64
- @bank.send(:same_currency?, 'USD', Money::Currency.wrap('EUR')).should == false
65
- @bank.send(:same_currency?, Money::Currency.wrap('USD'), Money::Currency.wrap('EUR')).should == false
66
- end
67
-
68
- it 'should raise an UnknownCurrency exception when an unknown currency is passed' do
69
- lambda{@bank.send(:same_currency?, 'AAA', 'BBB')}.should raise_exception(Money::Currency::UnknownCurrency)
70
- end
71
- end
72
- end
1
+ require "spec_helper"
2
+
3
+ describe Money::Bank::Base do
4
+ before :each do
5
+ @bank = Money::Bank::Base.new
6
+ end
7
+
8
+ describe '#new with &block' do
9
+ it 'should store @rounding_method' do
10
+ proc = Proc.new{|n| n.ceil}
11
+ bank = Money::Bank::Base.new(&proc)
12
+ bank.rounding_method.should == proc
13
+ end
14
+ end
15
+
16
+ describe '#setup' do
17
+ it 'should call #setup after #initialize' do
18
+ class MyBank < Money::Bank::Base
19
+ attr_reader :setup_called
20
+
21
+ def setup
22
+ @setup_called = true
23
+ end
24
+ end
25
+
26
+ bank = MyBank.new
27
+ bank.setup_called.should == true
28
+ end
29
+ end
30
+
31
+ describe '#exchange_with' do
32
+ it 'should raise NotImplementedError' do
33
+ lambda { @bank.exchange_with(Money.new(100, 'USD'), 'EUR') }.should raise_exception(NotImplementedError)
34
+ end
35
+ end
36
+
37
+ describe '#same_currency?' do
38
+ it 'should accept str/str' do
39
+ lambda{@bank.send(:same_currency?, 'USD', 'EUR')}.should_not raise_exception
40
+ end
41
+
42
+ it 'should accept currency/str' do
43
+ lambda{@bank.send(:same_currency?, Money::Currency.wrap('USD'), 'EUR')}.should_not raise_exception
44
+ end
45
+
46
+ it 'should accept str/currency' do
47
+ lambda{@bank.send(:same_currency?, 'USD', Money::Currency.wrap('EUR'))}.should_not raise_exception
48
+ end
49
+
50
+ it 'should accept currency/currency' do
51
+ lambda{@bank.send(:same_currency?, Money::Currency.wrap('USD'), Money::Currency.wrap('EUR'))}.should_not raise_exception
52
+ end
53
+
54
+ it 'should return `true` when currencies match' do
55
+ @bank.send(:same_currency?, 'USD', 'USD').should == true
56
+ @bank.send(:same_currency?, Money::Currency.wrap('USD'), 'USD').should == true
57
+ @bank.send(:same_currency?, 'USD', Money::Currency.wrap('USD')).should == true
58
+ @bank.send(:same_currency?, Money::Currency.wrap('USD'), Money::Currency.wrap('USD')).should == true
59
+ end
60
+
61
+ it 'should return `false` when currencies do not match' do
62
+ @bank.send(:same_currency?, 'USD', 'EUR').should == false
63
+ @bank.send(:same_currency?, Money::Currency.wrap('USD'), 'EUR').should == false
64
+ @bank.send(:same_currency?, 'USD', Money::Currency.wrap('EUR')).should == false
65
+ @bank.send(:same_currency?, Money::Currency.wrap('USD'), Money::Currency.wrap('EUR')).should == false
66
+ end
67
+
68
+ it 'should raise an UnknownCurrency exception when an unknown currency is passed' do
69
+ lambda{@bank.send(:same_currency?, 'AAA', 'BBB')}.should raise_exception(Money::Currency::UnknownCurrency)
70
+ end
71
+ end
72
+ end
@@ -1,238 +1,238 @@
1
- require "spec_helper"
2
- require "json"
3
- require "yaml"
4
-
5
- describe Money::Bank::VariableExchange do
6
-
7
- describe '#new without block' do
8
- before :each do
9
- @bank = Money::Bank::VariableExchange.new
10
- end
11
-
12
- describe '#exchange_with' do
13
- before :each do
14
- @bank.send(:set_rate, 'USD', 'EUR', 1.33)
15
- end
16
-
17
- it 'should accept str' do
18
- lambda{@bank.exchange_with(Money.new(100, 'USD'), 'EUR')}.should_not raise_exception
19
- end
20
-
21
- it 'should accept currency' do
22
- lambda{@bank.exchange_with(Money.new(100, 'USD'), Money::Currency.wrap('EUR'))}.should_not raise_exception
23
- end
24
-
25
- it 'should exchange one currency to another' do
26
- @bank.exchange_with(Money.new(100, 'USD'), 'EUR').should == Money.new(133, 'EUR')
27
- end
28
-
29
- it 'should truncate extra digits' do
30
- @bank.exchange_with(Money.new(10, 'USD'), 'EUR').should == Money.new(13, 'EUR')
31
- end
32
-
33
- it 'should raise an UnknownCurrency exception when an unknown currency is requested' do
34
- lambda{@bank.exchange_with(Money.new(100, 'USD'), 'BBB')}.should raise_exception(Money::Currency::UnknownCurrency)
35
- end
36
-
37
- it 'should raise an UnknownRate exception when an unknown rate is requested' do
38
- lambda{@bank.exchange_with(Money.new(100, 'USD'), 'JPY')}.should raise_exception(Money::Bank::UnknownRate)
39
- end
40
-
41
- #it 'should round the exchanged result down' do
42
- # @bank.add_rate("USD", "EUR", 0.788332676)
43
- # @bank.add_rate("EUR", "YEN", 122.631477)
44
- # @bank.exchange_with(Money.new(10_00, "USD"), "EUR").should == Money.new(788, "EUR")
45
- # @bank.exchange_with(Money.new(500_00, "EUR"), "YEN").should == Money.new(6131573, "YEN")
46
- #end
47
-
48
- it 'should accept a custom truncation method' do
49
- proc = Proc.new { |n| n.ceil }
50
- @bank.exchange_with(Money.new(10, 'USD'), 'EUR', &proc).should == Money.new(14, 'EUR')
51
- end
52
- end
53
-
54
- describe "#add_rate" do
55
- it "should add rates correctly" do
56
- @bank.add_rate("USD", "EUR", 0.788332676)
57
- @bank.add_rate("EUR", "YEN", 122.631477)
58
-
59
- @bank.instance_variable_get(:@rates)['USD_TO_EUR'].should == 0.788332676
60
- @bank.instance_variable_get(:@rates)['EUR_TO_JPY'].should == 122.631477
61
- end
62
-
63
- it "should treat currency names case-insensitively" do
64
- @bank.add_rate("usd", "eur", 1)
65
- @bank.instance_variable_get(:@rates)['USD_TO_EUR'].should == 1
66
- end
67
- end
68
-
69
- describe '#set_rate' do
70
- it 'should set a rate' do
71
- @bank.set_rate('USD', 'EUR', 1.25)
72
- @bank.instance_variable_get(:@rates)['USD_TO_EUR'].should == 1.25
73
- end
74
-
75
- it 'should raise an UnknownCurrency exception when an unknown currency is passed' do
76
- lambda{ @bank.set_rate('AAA', 'BBB', 1.25) }.should raise_exception(Money::Currency::UnknownCurrency)
77
- end
78
- end
79
-
80
- describe '#get_rate' do
81
- it 'should return a rate' do
82
- @bank.set_rate('USD', 'EUR', 1.25)
83
- @bank.get_rate('USD', 'EUR').should == 1.25
84
- end
85
-
86
- it 'should raise an UnknownCurrency exception when an unknown currency is requested' do
87
- lambda{ @bank.get_rate('AAA', 'BBB') }.should raise_exception(Money::Currency::UnknownCurrency)
88
- end
89
- end
90
-
91
- describe '#export_rates' do
92
- before :each do
93
- @bank.set_rate('USD', 'EUR', 1.25)
94
- @bank.set_rate('USD', 'JPY', 2.55)
95
-
96
- @rates = {"USD_TO_EUR"=>1.25,"USD_TO_JPY"=>2.55}
97
- end
98
-
99
- describe 'with format == :json' do
100
- it 'should return rates formatted as json' do
101
- json = @bank.export_rates(:json)
102
- JSON.load(json).should == @rates
103
- end
104
- end
105
-
106
- describe 'with format == :ruby' do
107
- it 'should return rates formatted as ruby objects' do
108
- Marshal.load(@bank.export_rates(:ruby)).should == @rates
109
- end
110
- end
111
-
112
- describe 'with format == :yaml' do
113
- it 'should return rates formatted as yaml' do
114
- yaml = @bank.export_rates(:yaml)
115
- YAML.load(yaml).should == @rates
116
- end
117
- end
118
-
119
- describe 'with unknown format' do
120
- it 'should raise `UnknownRateFormat`' do
121
- lambda{@bank.export_rates(:foo)}.should raise_error Money::Bank::UnknownRateFormat
122
- end
123
- end
124
-
125
- describe 'with :file provided' do
126
- it 'should write rates to file' do
127
- f = mock('IO')
128
- File.should_receive(:open).with('null', 'w').and_return(f)
129
- f.should_receive(:write).with(@rates.to_json)
130
-
131
- @bank.export_rates(:json, 'null')
132
- end
133
- end
134
- end
135
-
136
- describe '#import_rates' do
137
- describe 'with format == :json' do
138
- it 'should load the rates provided' do
139
- s = '{"USD_TO_EUR":1.25,"USD_TO_JPY":2.55}'
140
- @bank.import_rates(:json, s)
141
- @bank.get_rate('USD', 'EUR').should == 1.25
142
- @bank.get_rate('USD', 'JPY').should == 2.55
143
- end
144
- end
145
-
146
- describe 'with format == :ruby' do
147
- it 'should load the rates provided' do
148
- s = Marshal.dump({"USD_TO_EUR"=>1.25,"USD_TO_JPY"=>2.55})
149
- @bank.import_rates(:ruby, s)
150
- @bank.get_rate('USD', 'EUR').should == 1.25
151
- @bank.get_rate('USD', 'JPY').should == 2.55
152
- end
153
- end
154
-
155
- describe 'with format == :yaml' do
156
- it 'should load the rates provided' do
157
- s = "--- \nUSD_TO_EUR: 1.25\nUSD_TO_JPY: 2.55\n"
158
- @bank.import_rates(:yaml, s)
159
- @bank.get_rate('USD', 'EUR').should == 1.25
160
- @bank.get_rate('USD', 'JPY').should == 2.55
161
- end
162
- end
163
-
164
- describe 'with unknown format' do
165
- it 'should raise `UnknownRateFormat`' do
166
- lambda{@bank.import_rates(:foo, "")}.should raise_error Money::Bank::UnknownRateFormat
167
- end
168
- end
169
- end
170
-
171
- describe '#rate_key_for' do
172
- it 'should accept str/str' do
173
- lambda{@bank.send(:rate_key_for, 'USD', 'EUR')}.should_not raise_exception
174
- end
175
-
176
- it 'should accept currency/str' do
177
- lambda{@bank.send(:rate_key_for, Money::Currency.wrap('USD'), 'EUR')}.should_not raise_exception
178
- end
179
-
180
- it 'should accept str/currency' do
181
- lambda{@bank.send(:rate_key_for, 'USD', Money::Currency.wrap('EUR'))}.should_not raise_exception
182
- end
183
-
184
- it 'should accept currency/currency' do
185
- lambda{@bank.send(:rate_key_for, Money::Currency.wrap('USD'), Money::Currency.wrap('EUR'))}.should_not raise_exception
186
- end
187
-
188
- it 'should return a hashkey based on the passed arguments' do
189
- @bank.send(:rate_key_for, 'USD', 'EUR').should == 'USD_TO_EUR'
190
- @bank.send(:rate_key_for, Money::Currency.wrap('USD'), 'EUR').should == 'USD_TO_EUR'
191
- @bank.send(:rate_key_for, 'USD', Money::Currency.wrap('EUR')).should == 'USD_TO_EUR'
192
- @bank.send(:rate_key_for, Money::Currency.wrap('USD'), Money::Currency.wrap('EUR')).should == 'USD_TO_EUR'
193
- end
194
-
195
- it 'should raise an UnknownCurrency exception when an unknown currency is passed' do
196
- lambda{@bank.send(:rate_key_for, 'AAA', 'BBB')}.should raise_exception(Money::Currency::UnknownCurrency)
197
- end
198
- end
199
-
200
- end
201
-
202
-
203
- describe '#new with &block' do
204
- before :each do
205
- proc = Proc.new { |n| n.ceil }
206
- @bank = Money::Bank::VariableExchange.new(&proc)
207
- @bank.add_rate('USD', 'EUR', 1.33)
208
- end
209
-
210
- describe '#exchange_with' do
211
- it 'should use a stored truncation method' do
212
- @bank.exchange_with(Money.new(10, 'USD'), 'EUR').should == Money.new(14, 'EUR')
213
- end
214
-
215
- it 'should use a custom truncation method over a stored one' do
216
- proc = Proc.new { |n| n.ceil + 1 }
217
- @bank.exchange_with(Money.new(10, 'USD'), 'EUR', &proc).should == Money.new(15, 'EUR')
218
- end
219
- end
220
- end
221
-
222
- describe "#marshal_dump" do
223
- before :each do
224
- @bank = Money::Bank::VariableExchange.new
225
- end
226
-
227
- it 'should not raise an error' do
228
- lambda{Marshal.dump(@bank)}.should_not raise_error
229
- end
230
-
231
- it 'should work with Marshal.load' do
232
- b = Marshal.load(Marshal.dump(@bank))
233
-
234
- b.rates.should == @bank.rates
235
- b.rounding_method.should == @bank.rounding_method
236
- end
237
- end
238
- end
1
+ require "spec_helper"
2
+ require "json"
3
+ require "yaml"
4
+
5
+ describe Money::Bank::VariableExchange do
6
+
7
+ describe '#new without block' do
8
+ before :each do
9
+ @bank = Money::Bank::VariableExchange.new
10
+ end
11
+
12
+ describe '#exchange_with' do
13
+ before :each do
14
+ @bank.send(:set_rate, 'USD', 'EUR', 1.33)
15
+ end
16
+
17
+ it 'should accept str' do
18
+ lambda{@bank.exchange_with(Money.new(100, 'USD'), 'EUR')}.should_not raise_exception
19
+ end
20
+
21
+ it 'should accept currency' do
22
+ lambda{@bank.exchange_with(Money.new(100, 'USD'), Money::Currency.wrap('EUR'))}.should_not raise_exception
23
+ end
24
+
25
+ it 'should exchange one currency to another' do
26
+ @bank.exchange_with(Money.new(100, 'USD'), 'EUR').should == Money.new(133, 'EUR')
27
+ end
28
+
29
+ it 'should truncate extra digits' do
30
+ @bank.exchange_with(Money.new(10, 'USD'), 'EUR').should == Money.new(13, 'EUR')
31
+ end
32
+
33
+ it 'should raise an UnknownCurrency exception when an unknown currency is requested' do
34
+ lambda{@bank.exchange_with(Money.new(100, 'USD'), 'BBB')}.should raise_exception(Money::Currency::UnknownCurrency)
35
+ end
36
+
37
+ it 'should raise an UnknownRate exception when an unknown rate is requested' do
38
+ lambda{@bank.exchange_with(Money.new(100, 'USD'), 'JPY')}.should raise_exception(Money::Bank::UnknownRate)
39
+ end
40
+
41
+ #it 'should round the exchanged result down' do
42
+ # @bank.add_rate("USD", "EUR", 0.788332676)
43
+ # @bank.add_rate("EUR", "YEN", 122.631477)
44
+ # @bank.exchange_with(Money.new(10_00, "USD"), "EUR").should == Money.new(788, "EUR")
45
+ # @bank.exchange_with(Money.new(500_00, "EUR"), "YEN").should == Money.new(6131573, "YEN")
46
+ #end
47
+
48
+ it 'should accept a custom truncation method' do
49
+ proc = Proc.new { |n| n.ceil }
50
+ @bank.exchange_with(Money.new(10, 'USD'), 'EUR', &proc).should == Money.new(14, 'EUR')
51
+ end
52
+ end
53
+
54
+ describe "#add_rate" do
55
+ it "should add rates correctly" do
56
+ @bank.add_rate("USD", "EUR", 0.788332676)
57
+ @bank.add_rate("EUR", "YEN", 122.631477)
58
+
59
+ @bank.instance_variable_get(:@rates)['USD_TO_EUR'].should == 0.788332676
60
+ @bank.instance_variable_get(:@rates)['EUR_TO_JPY'].should == 122.631477
61
+ end
62
+
63
+ it "should treat currency names case-insensitively" do
64
+ @bank.add_rate("usd", "eur", 1)
65
+ @bank.instance_variable_get(:@rates)['USD_TO_EUR'].should == 1
66
+ end
67
+ end
68
+
69
+ describe '#set_rate' do
70
+ it 'should set a rate' do
71
+ @bank.set_rate('USD', 'EUR', 1.25)
72
+ @bank.instance_variable_get(:@rates)['USD_TO_EUR'].should == 1.25
73
+ end
74
+
75
+ it 'should raise an UnknownCurrency exception when an unknown currency is passed' do
76
+ lambda{ @bank.set_rate('AAA', 'BBB', 1.25) }.should raise_exception(Money::Currency::UnknownCurrency)
77
+ end
78
+ end
79
+
80
+ describe '#get_rate' do
81
+ it 'should return a rate' do
82
+ @bank.set_rate('USD', 'EUR', 1.25)
83
+ @bank.get_rate('USD', 'EUR').should == 1.25
84
+ end
85
+
86
+ it 'should raise an UnknownCurrency exception when an unknown currency is requested' do
87
+ lambda{ @bank.get_rate('AAA', 'BBB') }.should raise_exception(Money::Currency::UnknownCurrency)
88
+ end
89
+ end
90
+
91
+ describe '#export_rates' do
92
+ before :each do
93
+ @bank.set_rate('USD', 'EUR', 1.25)
94
+ @bank.set_rate('USD', 'JPY', 2.55)
95
+
96
+ @rates = {"USD_TO_EUR"=>1.25,"USD_TO_JPY"=>2.55}
97
+ end
98
+
99
+ describe 'with format == :json' do
100
+ it 'should return rates formatted as json' do
101
+ json = @bank.export_rates(:json)
102
+ JSON.load(json).should == @rates
103
+ end
104
+ end
105
+
106
+ describe 'with format == :ruby' do
107
+ it 'should return rates formatted as ruby objects' do
108
+ Marshal.load(@bank.export_rates(:ruby)).should == @rates
109
+ end
110
+ end
111
+
112
+ describe 'with format == :yaml' do
113
+ it 'should return rates formatted as yaml' do
114
+ yaml = @bank.export_rates(:yaml)
115
+ YAML.load(yaml).should == @rates
116
+ end
117
+ end
118
+
119
+ describe 'with unknown format' do
120
+ it 'should raise `UnknownRateFormat`' do
121
+ lambda{@bank.export_rates(:foo)}.should raise_error Money::Bank::UnknownRateFormat
122
+ end
123
+ end
124
+
125
+ describe 'with :file provided' do
126
+ it 'should write rates to file' do
127
+ f = mock('IO')
128
+ File.should_receive(:open).with('null', 'w').and_return(f)
129
+ f.should_receive(:write).with(@rates.to_json)
130
+
131
+ @bank.export_rates(:json, 'null')
132
+ end
133
+ end
134
+ end
135
+
136
+ describe '#import_rates' do
137
+ describe 'with format == :json' do
138
+ it 'should load the rates provided' do
139
+ s = '{"USD_TO_EUR":1.25,"USD_TO_JPY":2.55}'
140
+ @bank.import_rates(:json, s)
141
+ @bank.get_rate('USD', 'EUR').should == 1.25
142
+ @bank.get_rate('USD', 'JPY').should == 2.55
143
+ end
144
+ end
145
+
146
+ describe 'with format == :ruby' do
147
+ it 'should load the rates provided' do
148
+ s = Marshal.dump({"USD_TO_EUR"=>1.25,"USD_TO_JPY"=>2.55})
149
+ @bank.import_rates(:ruby, s)
150
+ @bank.get_rate('USD', 'EUR').should == 1.25
151
+ @bank.get_rate('USD', 'JPY').should == 2.55
152
+ end
153
+ end
154
+
155
+ describe 'with format == :yaml' do
156
+ it 'should load the rates provided' do
157
+ s = "--- \nUSD_TO_EUR: 1.25\nUSD_TO_JPY: 2.55\n"
158
+ @bank.import_rates(:yaml, s)
159
+ @bank.get_rate('USD', 'EUR').should == 1.25
160
+ @bank.get_rate('USD', 'JPY').should == 2.55
161
+ end
162
+ end
163
+
164
+ describe 'with unknown format' do
165
+ it 'should raise `UnknownRateFormat`' do
166
+ lambda{@bank.import_rates(:foo, "")}.should raise_error Money::Bank::UnknownRateFormat
167
+ end
168
+ end
169
+ end
170
+
171
+ describe '#rate_key_for' do
172
+ it 'should accept str/str' do
173
+ lambda{@bank.send(:rate_key_for, 'USD', 'EUR')}.should_not raise_exception
174
+ end
175
+
176
+ it 'should accept currency/str' do
177
+ lambda{@bank.send(:rate_key_for, Money::Currency.wrap('USD'), 'EUR')}.should_not raise_exception
178
+ end
179
+
180
+ it 'should accept str/currency' do
181
+ lambda{@bank.send(:rate_key_for, 'USD', Money::Currency.wrap('EUR'))}.should_not raise_exception
182
+ end
183
+
184
+ it 'should accept currency/currency' do
185
+ lambda{@bank.send(:rate_key_for, Money::Currency.wrap('USD'), Money::Currency.wrap('EUR'))}.should_not raise_exception
186
+ end
187
+
188
+ it 'should return a hashkey based on the passed arguments' do
189
+ @bank.send(:rate_key_for, 'USD', 'EUR').should == 'USD_TO_EUR'
190
+ @bank.send(:rate_key_for, Money::Currency.wrap('USD'), 'EUR').should == 'USD_TO_EUR'
191
+ @bank.send(:rate_key_for, 'USD', Money::Currency.wrap('EUR')).should == 'USD_TO_EUR'
192
+ @bank.send(:rate_key_for, Money::Currency.wrap('USD'), Money::Currency.wrap('EUR')).should == 'USD_TO_EUR'
193
+ end
194
+
195
+ it 'should raise an UnknownCurrency exception when an unknown currency is passed' do
196
+ lambda{@bank.send(:rate_key_for, 'AAA', 'BBB')}.should raise_exception(Money::Currency::UnknownCurrency)
197
+ end
198
+ end
199
+
200
+ end
201
+
202
+
203
+ describe '#new with &block' do
204
+ before :each do
205
+ proc = Proc.new { |n| n.ceil }
206
+ @bank = Money::Bank::VariableExchange.new(&proc)
207
+ @bank.add_rate('USD', 'EUR', 1.33)
208
+ end
209
+
210
+ describe '#exchange_with' do
211
+ it 'should use a stored truncation method' do
212
+ @bank.exchange_with(Money.new(10, 'USD'), 'EUR').should == Money.new(14, 'EUR')
213
+ end
214
+
215
+ it 'should use a custom truncation method over a stored one' do
216
+ proc = Proc.new { |n| n.ceil + 1 }
217
+ @bank.exchange_with(Money.new(10, 'USD'), 'EUR', &proc).should == Money.new(15, 'EUR')
218
+ end
219
+ end
220
+ end
221
+
222
+ describe "#marshal_dump" do
223
+ before :each do
224
+ @bank = Money::Bank::VariableExchange.new
225
+ end
226
+
227
+ it 'should not raise an error' do
228
+ lambda{Marshal.dump(@bank)}.should_not raise_error
229
+ end
230
+
231
+ it 'should work with Marshal.load' do
232
+ b = Marshal.load(Marshal.dump(@bank))
233
+
234
+ b.rates.should == @bank.rates
235
+ b.rounding_method.should == @bank.rounding_method
236
+ end
237
+ end
238
+ end