money-joshm1 5.1.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,233 @@
1
+ require 'spec_helper'
2
+ require 'json'
3
+ require 'yaml'
4
+
5
+ describe Money::Bank::VariableExchange do
6
+
7
+ describe "#initialize" do
8
+ context "without &block" do
9
+ let(:bank) {
10
+ Money::Bank::VariableExchange.new.tap do |bank|
11
+ bank.add_rate('USD', 'EUR', 1.33)
12
+ end
13
+ }
14
+
15
+ describe "#exchange_with" do
16
+ it "accepts str" do
17
+ expect { bank.exchange_with(Money.new(100, 'USD'), 'EUR') }.to_not raise_exception
18
+ end
19
+
20
+ it "accepts currency" do
21
+ expect { bank.exchange_with(Money.new(100, 'USD'), Money::Currency.wrap('EUR')) }.to_not raise_exception
22
+ end
23
+
24
+ it "exchanges one currency to another" do
25
+ bank.exchange_with(Money.new(100, 'USD'), 'EUR').should == Money.new(133, 'EUR')
26
+ end
27
+
28
+ it "truncates extra digits" do
29
+ bank.exchange_with(Money.new(10, 'USD'), 'EUR').should == Money.new(13, 'EUR')
30
+ end
31
+
32
+ it "raises an UnknownCurrency exception when an unknown currency is requested" do
33
+ expect { bank.exchange_with(Money.new(100, 'USD'), 'BBB') }.to raise_exception(Money::Currency::UnknownCurrency)
34
+ end
35
+
36
+ it "raises an UnknownRate exception when an unknown rate is requested" do
37
+ expect { bank.exchange_with(Money.new(100, 'USD'), 'JPY') }.to raise_exception(Money::Bank::UnknownRate)
38
+ end
39
+
40
+ #it "rounds the exchanged result down" do
41
+ # bank.add_rate("USD", "EUR", 0.788332676)
42
+ # bank.add_rate("EUR", "YEN", 122.631477)
43
+ # bank.exchange_with(Money.new(10_00, "USD"), "EUR").should == Money.new(788, "EUR")
44
+ # bank.exchange_with(Money.new(500_00, "EUR"), "YEN").should == Money.new(6131573, "YEN")
45
+ #end
46
+
47
+ it "accepts a custom truncation method" do
48
+ proc = Proc.new { |n| n.ceil }
49
+ bank.exchange_with(Money.new(10, 'USD'), 'EUR', &proc).should == Money.new(14, 'EUR')
50
+ end
51
+ end
52
+ end
53
+
54
+ context "with &block" do
55
+ let(:bank) {
56
+ proc = Proc.new { |n| n.ceil }
57
+ Money::Bank::VariableExchange.new(&proc).tap do |bank|
58
+ bank.add_rate('USD', 'EUR', 1.33)
59
+ end
60
+ }
61
+
62
+ describe "#exchange_with" do
63
+ it "uses the stored truncation method" do
64
+ bank.exchange_with(Money.new(10, 'USD'), 'EUR').should == Money.new(14, 'EUR')
65
+ end
66
+
67
+ it "accepts a custom truncation method" do
68
+ proc = Proc.new { |n| n.ceil + 1 }
69
+ bank.exchange_with(Money.new(10, 'USD'), 'EUR', &proc).should == Money.new(15, 'EUR')
70
+ end
71
+ end
72
+ end
73
+ end
74
+
75
+ describe "#add_rate" do
76
+ it "adds rates correctly" do
77
+ subject.add_rate("USD", "EUR", 0.788332676)
78
+ subject.add_rate("EUR", "YEN", 122.631477)
79
+
80
+ subject.instance_variable_get(:@rates)['USD_TO_EUR'].should == 0.788332676
81
+ subject.instance_variable_get(:@rates)['EUR_TO_JPY'].should == 122.631477
82
+ end
83
+
84
+ it "treats currency names case-insensitively" do
85
+ subject.add_rate("usd", "eur", 1)
86
+ subject.instance_variable_get(:@rates)['USD_TO_EUR'].should == 1
87
+ end
88
+ end
89
+
90
+ describe "#set_rate" do
91
+ it "sets a rate" do
92
+ subject.set_rate('USD', 'EUR', 1.25)
93
+ subject.instance_variable_get(:@rates)['USD_TO_EUR'].should == 1.25
94
+ end
95
+
96
+ it "raises an UnknownCurrency exception when an unknown currency is passed" do
97
+ expect { subject.set_rate('AAA', 'BBB', 1.25) }.to raise_exception(Money::Currency::UnknownCurrency)
98
+ end
99
+ end
100
+
101
+ describe "#get_rate" do
102
+ it "returns a rate" do
103
+ subject.set_rate('USD', 'EUR', 1.25)
104
+ subject.get_rate('USD', 'EUR').should == 1.25
105
+ end
106
+
107
+ it "raises an UnknownCurrency exception when an unknown currency is passed" do
108
+ expect { subject.get_rate('AAA', 'BBB') }.to raise_exception(Money::Currency::UnknownCurrency)
109
+ end
110
+ end
111
+
112
+ describe "#export_rates" do
113
+ before :each do
114
+ subject.set_rate('USD', 'EUR', 1.25)
115
+ subject.set_rate('USD', 'JPY', 2.55)
116
+
117
+ @rates = { "USD_TO_EUR" => 1.25, "USD_TO_JPY" => 2.55 }
118
+ end
119
+
120
+ context "with format == :json" do
121
+ it "should return rates formatted as json" do
122
+ json = subject.export_rates(:json)
123
+ JSON.load(json).should == @rates
124
+ end
125
+ end
126
+
127
+ context "with format == :ruby" do
128
+ it "should return rates formatted as ruby objects" do
129
+ Marshal.load(subject.export_rates(:ruby)).should == @rates
130
+ end
131
+ end
132
+
133
+ context "with format == :yaml" do
134
+ it "should return rates formatted as yaml" do
135
+ yaml = subject.export_rates(:yaml)
136
+ YAML.load(yaml).should == @rates
137
+ end
138
+ end
139
+
140
+ context "with unknown format" do
141
+ it "raises Money::Bank::UnknownRateFormat" do
142
+ expect { subject.export_rates(:foo)}.to raise_error Money::Bank::UnknownRateFormat
143
+ end
144
+ end
145
+
146
+ context "with :file provided" do
147
+ it "writes rates to file" do
148
+ f = mock('IO')
149
+ File.should_receive(:open).with('null', 'w').and_yield(f)
150
+ f.should_receive(:write).with(JSON.dump(@rates))
151
+
152
+ subject.export_rates(:json, 'null')
153
+ end
154
+ end
155
+ end
156
+
157
+ describe "#import_rates" do
158
+ context "with format == :json" do
159
+ it "loads the rates provided" do
160
+ s = '{"USD_TO_EUR":1.25,"USD_TO_JPY":2.55}'
161
+ subject.import_rates(:json, s)
162
+ subject.get_rate('USD', 'EUR').should == 1.25
163
+ subject.get_rate('USD', 'JPY').should == 2.55
164
+ end
165
+ end
166
+
167
+ context "with format == :ruby" do
168
+ it "loads the rates provided" do
169
+ s = Marshal.dump({"USD_TO_EUR"=>1.25,"USD_TO_JPY"=>2.55})
170
+ subject.import_rates(:ruby, s)
171
+ subject.get_rate('USD', 'EUR').should == 1.25
172
+ subject.get_rate('USD', 'JPY').should == 2.55
173
+ end
174
+ end
175
+
176
+ context "with format == :yaml" do
177
+ it "loads the rates provided" do
178
+ s = "--- \nUSD_TO_EUR: 1.25\nUSD_TO_JPY: 2.55\n"
179
+ subject.import_rates(:yaml, s)
180
+ subject.get_rate('USD', 'EUR').should == 1.25
181
+ subject.get_rate('USD', 'JPY').should == 2.55
182
+ end
183
+ end
184
+
185
+ context "with unknown format" do
186
+ it "raises Money::Bank::UnknownRateFormat" do
187
+ expect { subject.import_rates(:foo, "")}.to raise_error Money::Bank::UnknownRateFormat
188
+ end
189
+ end
190
+ end
191
+
192
+ describe "#rate_key_for" do
193
+ it "accepts str/str" do
194
+ expect { subject.send(:rate_key_for, 'USD', 'EUR')}.to_not raise_exception
195
+ end
196
+
197
+ it "accepts currency/str" do
198
+ expect { subject.send(:rate_key_for, Money::Currency.wrap('USD'), 'EUR')}.to_not raise_exception
199
+ end
200
+
201
+ it "accepts str/currency" do
202
+ expect { subject.send(:rate_key_for, 'USD', Money::Currency.wrap('EUR'))}.to_not raise_exception
203
+ end
204
+
205
+ it "accepts currency/currency" do
206
+ expect { subject.send(:rate_key_for, Money::Currency.wrap('USD'), Money::Currency.wrap('EUR'))}.to_not raise_exception
207
+ end
208
+
209
+ it "returns a hashkey based on the passed arguments" do
210
+ subject.send(:rate_key_for, 'USD', 'EUR').should == 'USD_TO_EUR'
211
+ subject.send(:rate_key_for, Money::Currency.wrap('USD'), 'EUR').should == 'USD_TO_EUR'
212
+ subject.send(:rate_key_for, 'USD', Money::Currency.wrap('EUR')).should == 'USD_TO_EUR'
213
+ subject.send(:rate_key_for, Money::Currency.wrap('USD'), Money::Currency.wrap('EUR')).should == 'USD_TO_EUR'
214
+ end
215
+
216
+ it "raises a Money::Currency::UnknownCurrency exception when an unknown currency is passed" do
217
+ expect { subject.send(:rate_key_for, 'AAA', 'BBB')}.to raise_exception(Money::Currency::UnknownCurrency)
218
+ end
219
+ end
220
+
221
+ describe "#marshal_dump" do
222
+ it "does not raise an error" do
223
+ expect { Marshal.dump(subject) }.to_not raise_error
224
+ end
225
+
226
+ it "works with Marshal.load" do
227
+ bank = Marshal.load(Marshal.dump(subject))
228
+
229
+ bank.rates.should == subject.rates
230
+ bank.rounding_method.should == subject.rounding_method
231
+ end
232
+ end
233
+ end
@@ -0,0 +1,160 @@
1
+ require "spec_helper"
2
+
3
+ describe Money, "core extensions" do
4
+
5
+ describe Numeric do
6
+ describe "#to_money" do
7
+ it "work as documented" do
8
+ money = 1234.to_money
9
+ money.cents.should == 1234_00
10
+ money.currency.should == Money.default_currency
11
+
12
+ money = 100.37.to_money
13
+ money.cents.should == 100_37
14
+ money.currency.should == Money.default_currency
15
+
16
+ money = BigDecimal.new('1234').to_money
17
+ money.cents.should == 1234_00
18
+ money.currency.should == Money.default_currency
19
+ end
20
+
21
+ it "accepts optional currency" do
22
+ 1234.to_money('USD').should == Money.new(123400, 'USD')
23
+ 1234.to_money('EUR').should == Money.new(123400, 'EUR')
24
+ end
25
+
26
+ it "respects :subunit_to_unit currency property" do
27
+ 10.to_money('USD').should == Money.new(10_00, 'USD')
28
+ 10.to_money('TND').should == Money.new(10_000, 'TND')
29
+ 10.to_money('CLP').should == Money.new(10, 'CLP')
30
+ end
31
+
32
+ specify "GH-15" do
33
+ amount = 555.55.to_money
34
+ amount.should == Money.new(55555)
35
+ end
36
+ end
37
+ end
38
+
39
+ describe String do
40
+ describe "#to_money" do
41
+
42
+ STRING_TO_MONEY = {
43
+ "20.15" => Money.new(20_15) ,
44
+ "100" => Money.new(100_00) ,
45
+ "100.37" => Money.new(100_37) ,
46
+ "100,37" => Money.new(100_37) ,
47
+ "100 000" => Money.new(100_000_00) ,
48
+ "100,000.00" => Money.new(100_000_00) ,
49
+ "1,000" => Money.new(1_000_00) ,
50
+ "-1,000" => Money.new(-1_000_00) ,
51
+ "1,000.5" => Money.new(1_000_50) ,
52
+ "1,000.51" => Money.new(1_000_51) ,
53
+ "1,000.505" => Money.new(1_000_51) ,
54
+ "1,000.504" => Money.new(1_000_50) ,
55
+ "1,000.0000" => Money.new(1_000_00) ,
56
+ "1,000.5000" => Money.new(1_000_50) ,
57
+ "1,000.5099" => Money.new(1_000_51) ,
58
+ "1.550" => Money.new(1_55) ,
59
+ "25." => Money.new(25_00) ,
60
+ ".75" => Money.new(75) ,
61
+
62
+ "100 USD" => Money.new(100_00, "USD") ,
63
+ "-100 USD" => Money.new(-100_00, "USD") ,
64
+ "100 EUR" => Money.new(100_00, "EUR") ,
65
+ "100.37 EUR" => Money.new(100_37, "EUR") ,
66
+ "100,37 EUR" => Money.new(100_37, "EUR") ,
67
+ "100,000.00 USD" => Money.new(100_000_00, "USD") ,
68
+ "100.000,00 EUR" => Money.new(100_000_00, "EUR") ,
69
+ "1,000 USD" => Money.new(1_000_00, "USD") ,
70
+ "-1,000 USD" => Money.new(-1_000_00, "USD") ,
71
+ "1,000.5500 USD" => Money.new(1_000_55, "USD") ,
72
+ "-1,000.6500 USD" => Money.new(-1_000_65, "USD") ,
73
+ "1.550 USD" => Money.new(1_55, "USD") ,
74
+
75
+ "USD 100" => Money.new(100_00, "USD") ,
76
+ "EUR 100" => Money.new(100_00, "EUR") ,
77
+ "EUR 100.37" => Money.new(100_37, "EUR") ,
78
+ "CAD -100.37" => Money.new(-100_37, "CAD") ,
79
+ "EUR 100,37" => Money.new(100_37, "EUR") ,
80
+ "EUR -100,37" => Money.new(-100_37, "EUR") ,
81
+ "USD 100,000.00" => Money.new(100_000_00, "USD") ,
82
+ "EUR 100.000,00" => Money.new(100_000_00, "EUR") ,
83
+ "USD 1,000" => Money.new(1_000_00, "USD") ,
84
+ "USD -1,000" => Money.new(-1_000_00, "USD") ,
85
+ "USD 1,000.9000" => Money.new(1_000_90, "USD") ,
86
+ "USD -1,000.090" => Money.new(-1_000_09, "USD") ,
87
+ "USD 1.5500" => Money.new(1_55, "USD") ,
88
+
89
+ "$100 USD" => Money.new(100_00, "USD") ,
90
+ "$1,194.59 USD" => Money.new(1_194_59, "USD") ,
91
+ "$-1,955 USD" => Money.new(-1_955_00, "USD") ,
92
+ "$1,194.5900 USD" => Money.new(1_194_59, "USD") ,
93
+ "$-1,955.000 USD" => Money.new(-1_955_00, "USD") ,
94
+ "$1.99000 USD" => Money.new(1_99, "USD") ,
95
+ }
96
+
97
+ it "works as documented" do
98
+ STRING_TO_MONEY.each do |string, money|
99
+ string.to_money.should == money
100
+ end
101
+ end
102
+
103
+ it "coerces input to string" do
104
+ Money.parse(20, "USD").should == Money.new(20_00, "USD")
105
+ end
106
+
107
+ it "accepts optional currency" do
108
+ "10.10".to_money('USD').should == Money.new(1010, 'USD')
109
+ "10.10".to_money('EUR').should == Money.new(1010, 'EUR')
110
+ "10.10 USD".to_money('USD').should == Money.new(1010, 'USD')
111
+ end
112
+
113
+ it "raises error if optional currency doesn't match string currency" do
114
+ expect { "10.10 USD".to_money('EUR') }.to raise_error(/Mismatching Currencies/)
115
+ end
116
+
117
+ it "ignores unrecognized data" do
118
+ "hello 2000 world".to_money.should == Money.new(2000_00)
119
+ end
120
+
121
+ it "respects :subunit_to_unit currency property" do
122
+ "1".to_money("USD").should == Money.new(1_00, "USD")
123
+ "1".to_money("TND").should == Money.new(1_000, "TND")
124
+ "1".to_money("CLP").should == Money.new(1, "CLP")
125
+ "1.5".to_money("KWD").cents.should == 1500
126
+ end
127
+ end
128
+
129
+ describe "#to_currency" do
130
+ it "converts String to Currency" do
131
+ "USD".to_currency.should == Money::Currency.new("USD")
132
+ "EUR".to_currency.should == Money::Currency.new("EUR")
133
+ end
134
+
135
+ it "raises Money::Currency::UnknownCurrency with unknown Currency" do
136
+ expect { "XXX".to_currency }.to raise_error(Money::Currency::UnknownCurrency)
137
+ expect { " ".to_currency }.to raise_error(Money::Currency::UnknownCurrency)
138
+ end
139
+ end
140
+ end
141
+
142
+ describe Symbol do
143
+ describe "#to_currency" do
144
+ it "converts Symbol to Currency" do
145
+ :usd.to_currency.should == Money::Currency.new("USD")
146
+ :ars.to_currency.should == Money::Currency.new("ARS")
147
+ end
148
+
149
+ it "is case-insensitive" do
150
+ :EUR.to_currency.should == Money::Currency.new("EUR")
151
+ end
152
+
153
+ it "raises Money::Currency::UnknownCurrency with unknown Currency" do
154
+ expect { :XXX.to_currency }.to raise_error(Money::Currency::UnknownCurrency)
155
+ expect { :" ".to_currency }.to raise_error(Money::Currency::UnknownCurrency)
156
+ end
157
+ end
158
+ end
159
+
160
+ end
@@ -0,0 +1,84 @@
1
+ # encoding: utf-8
2
+ require 'spec_helper'
3
+
4
+ describe Money::Currency::Heuristics do
5
+ describe "#analyze_string" do
6
+ let(:it) { Money::Currency }
7
+
8
+ it "is not affected by blank characters and numbers" do
9
+ it.analyze('123').should == []
10
+ it.analyze('\n123 \t').should == []
11
+ end
12
+
13
+ it "returns nothing when given nothing" do
14
+ it.analyze('').should == []
15
+ it.analyze(nil).should == []
16
+ end
17
+
18
+ it "finds a currency by use of its symbol" do
19
+ it.analyze('zł').should == ['PLN']
20
+ end
21
+
22
+ it "is not affected by trailing dot" do
23
+ it.analyze('zł.').should == ['PLN']
24
+ end
25
+
26
+ it "finds match even if has numbers after" do
27
+ it.analyze('zł 123').should == ['PLN']
28
+ end
29
+
30
+ it "finds match even if has numbers before" do
31
+ it.analyze('123 zł').should == ['PLN']
32
+ end
33
+
34
+ it "find match even if symbol is next to number" do
35
+ it.analyze('300zł').should == ['PLN']
36
+ end
37
+
38
+ it "finds match even if has numbers with delimiters" do
39
+ it.analyze('zł 123,000.50').should == ['PLN']
40
+ it.analyze('zł123,000.50').should == ['PLN']
41
+ end
42
+
43
+ it "finds currencies with dots in symbols" do
44
+ it.analyze('L.E.').should == ['EGP']
45
+ end
46
+
47
+ it "finds by name" do
48
+ it.analyze('1900 bulgarian lev').should == ['BGN']
49
+ it.analyze('Swedish Krona').should == ['SEK']
50
+ end
51
+
52
+ it "Finds several currencies when several match" do
53
+ r = it.analyze('$400')
54
+ r.should include("ARS")
55
+ r.should include("USD")
56
+ r.should include("NZD")
57
+
58
+ r = it.analyze('9000 £')
59
+ r.should include("GBP")
60
+ r.should include("SHP")
61
+ r.should include("SYP")
62
+ end
63
+
64
+ it "should use alternate symbols" do
65
+ it.analyze('US$').should == ['USD']
66
+ end
67
+
68
+ it "finds a currency by use of its iso code" do
69
+ it.analyze('USD 200').should == ['USD']
70
+ end
71
+
72
+ it "finds currencies in the middle of a sentence!" do
73
+ it.analyze('It would be nice to have 10000 Albanian lek by tomorrow!').should == ['ALL']
74
+ end
75
+
76
+ it "finds several currencies in the same text!" do
77
+ it.analyze("10EUR is less than 100:- but really, I want US$1").should == ['EUR', 'SEK', 'USD']
78
+ end
79
+
80
+ it "should function with unicode characters" do
81
+ it.analyze("10 դր.").should == ["AMD"]
82
+ end
83
+ end
84
+ end