money 3.7.1 → 4.0.0

Sign up to get free protection for your applications and to get access to all the features.
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
@@ -1,197 +1,197 @@
1
- # encoding: utf-8
2
-
3
- require "spec_helper"
4
-
5
- describe Money do
6
- describe "Money.parse" do
7
-
8
- it "should be able to parse european-formatted inputs under 10EUR" do
9
- five_ninety_five = Money.new(595, 'EUR')
10
-
11
- Money.parse('EUR 5,95').should == five_ninety_five
12
- #TODO: try and handle these
13
- #Money.parse('€5,95').should == five_ninety_five
14
- #Money.parse('$5.95').should == five_ninety_five
15
- end
16
-
17
- it "should be able to parse european-formatted inputs with multiple thousands-seperators" do
18
- Money.parse('EUR 1.234.567,89').should == Money.new(123456789, 'EUR')
19
- Money.parse('EUR 1.111.234.567,89').should == Money.new(111123456789, 'EUR')
20
- end
21
-
22
- it "should be able to parse USD-formatted inputs under $10" do
23
- five_ninety_five = Money.new(595, 'USD')
24
-
25
- Money.parse(5.95).should == five_ninety_five
26
- Money.parse('5.95').should == five_ninety_five
27
- Money.parse('$5.95').should == five_ninety_five
28
- Money.parse("\n $5.95 \n").should == five_ninety_five
29
- Money.parse('$ 5.95').should == five_ninety_five
30
- Money.parse('$5.95 ea.').should == five_ninety_five
31
- Money.parse('$5.95, each').should == five_ninety_five
32
- end
33
-
34
- it "should be able to parse USD-formatted inputs with multiple thousands-seperators" do
35
- Money.parse('1,234,567.89').should == Money.new(123456789, 'USD')
36
- Money.parse('1,111,234,567.89').should == Money.new(111123456789, 'USD')
37
- end
38
-
39
- it "should not return a price if there is a price range" do
40
- lambda {Money.parse('$5.95-10.95')}.should raise_error ArgumentError
41
- lambda {Money.parse('$5.95 - 10.95')}.should raise_error ArgumentError
42
- lambda {Money.parse('$5.95 - $10.95')}.should raise_error ArgumentError
43
- end
44
-
45
- it "should not return a price for completely invalid input" do
46
- # TODO: shouldn't these throw an error instead of being considered
47
- # equal to $0.0?
48
- empty_price = Money.new(0, 'USD')
49
-
50
- Money.parse(nil).should == empty_price
51
- Money.parse('hellothere').should == empty_price
52
- Money.parse('').should == empty_price
53
- end
54
- end
55
-
56
- describe "Money.from_string" do
57
- it "converts given amount to cents" do
58
- Money.from_string("1").should == Money.new(1_00)
59
- Money.from_string("1").should == Money.new(1_00, "USD")
60
- Money.from_string("1", "EUR").should == Money.new(1_00, "EUR")
61
- end
62
-
63
- it "should respect :subunit_to_unit currency property" do
64
- Money.from_string("1", "USD").should == Money.new(1_00, "USD")
65
- Money.from_string("1", "TND").should == Money.new(1_000, "TND")
66
- Money.from_string("1", "CLP").should == Money.new(1, "CLP")
67
- end
68
-
69
- it "accepts a currency options" do
70
- m = Money.from_string("1")
71
- m.currency.should == Money.default_currency
72
-
73
- m = Money.from_string("1", Money::Currency.wrap("EUR"))
74
- m.currency.should == Money::Currency.wrap("EUR")
75
-
76
- m = Money.from_string("1", "EUR")
77
- m.currency.should == Money::Currency.wrap("EUR")
78
- end
79
- end
80
-
81
- describe "Money.from_fixnum" do
82
- it "converts given amount to cents" do
83
- Money.from_fixnum(1).should == Money.new(1_00)
84
- Money.from_fixnum(1).should == Money.new(1_00, "USD")
85
- Money.from_fixnum(1, "EUR").should == Money.new(1_00, "EUR")
86
- end
87
-
88
- it "should respect :subunit_to_unit currency property" do
89
- Money.from_fixnum(1, "USD").should == Money.new(1_00, "USD")
90
- Money.from_fixnum(1, "TND").should == Money.new(1_000, "TND")
91
- Money.from_fixnum(1, "CLP").should == Money.new(1, "CLP")
92
- end
93
-
94
- it "accepts a currency options" do
95
- m = Money.from_fixnum(1)
96
- m.currency.should == Money.default_currency
97
-
98
- m = Money.from_fixnum(1, Money::Currency.wrap("EUR"))
99
- m.currency.should == Money::Currency.wrap("EUR")
100
-
101
- m = Money.from_fixnum(1, "EUR")
102
- m.currency.should == Money::Currency.wrap("EUR")
103
- end
104
- end
105
-
106
- describe "Money.from_float" do
107
- it "converts given amount to cents" do
108
- Money.from_float(1.2).should == Money.new(1_20)
109
- Money.from_float(1.2).should == Money.new(1_20, "USD")
110
- Money.from_float(1.2, "EUR").should == Money.new(1_20, "EUR")
111
- end
112
-
113
- it "should respect :subunit_to_unit currency property" do
114
- Money.from_float(1.2, "USD").should == Money.new(1_20, "USD")
115
- Money.from_float(1.2, "TND").should == Money.new(1_200, "TND")
116
- Money.from_float(1.2, "CLP").should == Money.new(1, "CLP")
117
- end
118
-
119
- it "accepts a currency options" do
120
- m = Money.from_float(1.2)
121
- m.currency.should == Money.default_currency
122
-
123
- m = Money.from_float(1.2, Money::Currency.wrap("EUR"))
124
- m.currency.should == Money::Currency.wrap("EUR")
125
-
126
- m = Money.from_float(1.2, "EUR")
127
- m.currency.should == Money::Currency.wrap("EUR")
128
- end
129
- end
130
-
131
- describe "Money.from_bigdecimal" do
132
- it "converts given amount to cents" do
133
- Money.from_bigdecimal(BigDecimal.new("1")).should == Money.new(1_00)
134
- Money.from_bigdecimal(BigDecimal.new("1")).should == Money.new(1_00, "USD")
135
- Money.from_bigdecimal(BigDecimal.new("1"), "EUR").should == Money.new(1_00, "EUR")
136
- end
137
-
138
- it "should respect :subunit_to_unit currency property" do
139
- Money.from_bigdecimal(BigDecimal.new("1"), "USD").should == Money.new(1_00, "USD")
140
- Money.from_bigdecimal(BigDecimal.new("1"), "TND").should == Money.new(1_000, "TND")
141
- Money.from_bigdecimal(BigDecimal.new("1"), "CLP").should == Money.new(1, "CLP")
142
- end
143
-
144
- it "accepts a currency options" do
145
- m = Money.from_bigdecimal(BigDecimal.new("1"))
146
- m.currency.should == Money.default_currency
147
-
148
- m = Money.from_bigdecimal(BigDecimal.new("1"), Money::Currency.wrap("EUR"))
149
- m.currency.should == Money::Currency.wrap("EUR")
150
-
151
- m = Money.from_bigdecimal(BigDecimal.new("1"), "EUR")
152
- m.currency.should == Money::Currency.wrap("EUR")
153
- end
154
- end
155
-
156
- describe "Money.from_numeric" do
157
- it "converts given amount to cents" do
158
- Money.from_numeric(1).should == Money.new(1_00)
159
- Money.from_numeric(1.0).should == Money.new(1_00)
160
- Money.from_numeric(BigDecimal.new("1")).should == Money.new(1_00)
161
- end
162
-
163
- it "should raise ArgumentError with unsupported argument" do
164
- lambda { Money.from_numeric("100") }.should raise_error(ArgumentError)
165
- end
166
-
167
- it "should optimize workload" do
168
- Money.should_receive(:from_fixnum).with(1, "USD").and_return(Money.new(1_00, "USD"))
169
- Money.from_numeric(1, "USD").should == Money.new(1_00, "USD")
170
- Money.should_receive(:from_bigdecimal).with(BigDecimal.new("1.0"), "USD").and_return(Money.new(1_00, "USD"))
171
- Money.from_numeric(1.0, "USD").should == Money.new(1_00, "USD")
172
- end
173
-
174
- it "should respect :subunit_to_unit currency property" do
175
- Money.from_numeric(1, "USD").should == Money.new(1_00, "USD")
176
- Money.from_numeric(1, "TND").should == Money.new(1_000, "TND")
177
- Money.from_numeric(1, "CLP").should == Money.new(1, "CLP")
178
- end
179
-
180
- it "accepts a bank option" do
181
- Money.from_numeric(1).should == Money.new(1_00)
182
- Money.from_numeric(1).should == Money.new(1_00, "USD")
183
- Money.from_numeric(1, "EUR").should == Money.new(1_00, "EUR")
184
- end
185
-
186
- it "accepts a currency options" do
187
- m = Money.from_numeric(1)
188
- m.currency.should == Money.default_currency
189
-
190
- m = Money.from_numeric(1, Money::Currency.wrap("EUR"))
191
- m.currency.should == Money::Currency.wrap("EUR")
192
-
193
- m = Money.from_numeric(1, "EUR")
194
- m.currency.should == Money::Currency.wrap("EUR")
195
- end
196
- end
197
- end
1
+ # encoding: utf-8
2
+
3
+ require "spec_helper"
4
+
5
+ describe Money do
6
+ describe "Money.parse" do
7
+
8
+ it "should be able to parse european-formatted inputs under 10EUR" do
9
+ five_ninety_five = Money.new(595, 'EUR')
10
+
11
+ Money.parse('EUR 5,95').should == five_ninety_five
12
+ #TODO: try and handle these
13
+ #Money.parse('€5,95').should == five_ninety_five
14
+ #Money.parse('$5.95').should == five_ninety_five
15
+ end
16
+
17
+ it "should be able to parse european-formatted inputs with multiple thousands-seperators" do
18
+ Money.parse('EUR 1.234.567,89').should == Money.new(123456789, 'EUR')
19
+ Money.parse('EUR 1.111.234.567,89').should == Money.new(111123456789, 'EUR')
20
+ end
21
+
22
+ it "should be able to parse USD-formatted inputs under $10" do
23
+ five_ninety_five = Money.new(595, 'USD')
24
+
25
+ Money.parse(5.95).should == five_ninety_five
26
+ Money.parse('5.95').should == five_ninety_five
27
+ Money.parse('$5.95').should == five_ninety_five
28
+ Money.parse("\n $5.95 \n").should == five_ninety_five
29
+ Money.parse('$ 5.95').should == five_ninety_five
30
+ Money.parse('$5.95 ea.').should == five_ninety_five
31
+ Money.parse('$5.95, each').should == five_ninety_five
32
+ end
33
+
34
+ it "should be able to parse USD-formatted inputs with multiple thousands-seperators" do
35
+ Money.parse('1,234,567.89').should == Money.new(123456789, 'USD')
36
+ Money.parse('1,111,234,567.89').should == Money.new(111123456789, 'USD')
37
+ end
38
+
39
+ it "should not return a price if there is a price range" do
40
+ lambda {Money.parse('$5.95-10.95')}.should raise_error ArgumentError
41
+ lambda {Money.parse('$5.95 - 10.95')}.should raise_error ArgumentError
42
+ lambda {Money.parse('$5.95 - $10.95')}.should raise_error ArgumentError
43
+ end
44
+
45
+ it "should not return a price for completely invalid input" do
46
+ # TODO: shouldn't these throw an error instead of being considered
47
+ # equal to $0.0?
48
+ empty_price = Money.new(0, 'USD')
49
+
50
+ Money.parse(nil).should == empty_price
51
+ Money.parse('hellothere').should == empty_price
52
+ Money.parse('').should == empty_price
53
+ end
54
+ end
55
+
56
+ describe "Money.from_string" do
57
+ it "converts given amount to cents" do
58
+ Money.from_string("1").should == Money.new(1_00)
59
+ Money.from_string("1").should == Money.new(1_00, "USD")
60
+ Money.from_string("1", "EUR").should == Money.new(1_00, "EUR")
61
+ end
62
+
63
+ it "should respect :subunit_to_unit currency property" do
64
+ Money.from_string("1", "USD").should == Money.new(1_00, "USD")
65
+ Money.from_string("1", "TND").should == Money.new(1_000, "TND")
66
+ Money.from_string("1", "CLP").should == Money.new(1, "CLP")
67
+ end
68
+
69
+ it "accepts a currency options" do
70
+ m = Money.from_string("1")
71
+ m.currency.should == Money.default_currency
72
+
73
+ m = Money.from_string("1", Money::Currency.wrap("EUR"))
74
+ m.currency.should == Money::Currency.wrap("EUR")
75
+
76
+ m = Money.from_string("1", "EUR")
77
+ m.currency.should == Money::Currency.wrap("EUR")
78
+ end
79
+ end
80
+
81
+ describe "Money.from_fixnum" do
82
+ it "converts given amount to cents" do
83
+ Money.from_fixnum(1).should == Money.new(1_00)
84
+ Money.from_fixnum(1).should == Money.new(1_00, "USD")
85
+ Money.from_fixnum(1, "EUR").should == Money.new(1_00, "EUR")
86
+ end
87
+
88
+ it "should respect :subunit_to_unit currency property" do
89
+ Money.from_fixnum(1, "USD").should == Money.new(1_00, "USD")
90
+ Money.from_fixnum(1, "TND").should == Money.new(1_000, "TND")
91
+ Money.from_fixnum(1, "CLP").should == Money.new(1, "CLP")
92
+ end
93
+
94
+ it "accepts a currency options" do
95
+ m = Money.from_fixnum(1)
96
+ m.currency.should == Money.default_currency
97
+
98
+ m = Money.from_fixnum(1, Money::Currency.wrap("EUR"))
99
+ m.currency.should == Money::Currency.wrap("EUR")
100
+
101
+ m = Money.from_fixnum(1, "EUR")
102
+ m.currency.should == Money::Currency.wrap("EUR")
103
+ end
104
+ end
105
+
106
+ describe "Money.from_float" do
107
+ it "converts given amount to cents" do
108
+ Money.from_float(1.2).should == Money.new(1_20)
109
+ Money.from_float(1.2).should == Money.new(1_20, "USD")
110
+ Money.from_float(1.2, "EUR").should == Money.new(1_20, "EUR")
111
+ end
112
+
113
+ it "should respect :subunit_to_unit currency property" do
114
+ Money.from_float(1.2, "USD").should == Money.new(1_20, "USD")
115
+ Money.from_float(1.2, "TND").should == Money.new(1_200, "TND")
116
+ Money.from_float(1.2, "CLP").should == Money.new(1, "CLP")
117
+ end
118
+
119
+ it "accepts a currency options" do
120
+ m = Money.from_float(1.2)
121
+ m.currency.should == Money.default_currency
122
+
123
+ m = Money.from_float(1.2, Money::Currency.wrap("EUR"))
124
+ m.currency.should == Money::Currency.wrap("EUR")
125
+
126
+ m = Money.from_float(1.2, "EUR")
127
+ m.currency.should == Money::Currency.wrap("EUR")
128
+ end
129
+ end
130
+
131
+ describe "Money.from_bigdecimal" do
132
+ it "converts given amount to cents" do
133
+ Money.from_bigdecimal(BigDecimal.new("1")).should == Money.new(1_00)
134
+ Money.from_bigdecimal(BigDecimal.new("1")).should == Money.new(1_00, "USD")
135
+ Money.from_bigdecimal(BigDecimal.new("1"), "EUR").should == Money.new(1_00, "EUR")
136
+ end
137
+
138
+ it "should respect :subunit_to_unit currency property" do
139
+ Money.from_bigdecimal(BigDecimal.new("1"), "USD").should == Money.new(1_00, "USD")
140
+ Money.from_bigdecimal(BigDecimal.new("1"), "TND").should == Money.new(1_000, "TND")
141
+ Money.from_bigdecimal(BigDecimal.new("1"), "CLP").should == Money.new(1, "CLP")
142
+ end
143
+
144
+ it "accepts a currency options" do
145
+ m = Money.from_bigdecimal(BigDecimal.new("1"))
146
+ m.currency.should == Money.default_currency
147
+
148
+ m = Money.from_bigdecimal(BigDecimal.new("1"), Money::Currency.wrap("EUR"))
149
+ m.currency.should == Money::Currency.wrap("EUR")
150
+
151
+ m = Money.from_bigdecimal(BigDecimal.new("1"), "EUR")
152
+ m.currency.should == Money::Currency.wrap("EUR")
153
+ end
154
+ end
155
+
156
+ describe "Money.from_numeric" do
157
+ it "converts given amount to cents" do
158
+ Money.from_numeric(1).should == Money.new(1_00)
159
+ Money.from_numeric(1.0).should == Money.new(1_00)
160
+ Money.from_numeric(BigDecimal.new("1")).should == Money.new(1_00)
161
+ end
162
+
163
+ it "should raise ArgumentError with unsupported argument" do
164
+ lambda { Money.from_numeric("100") }.should raise_error(ArgumentError)
165
+ end
166
+
167
+ it "should optimize workload" do
168
+ Money.should_receive(:from_fixnum).with(1, "USD").and_return(Money.new(1_00, "USD"))
169
+ Money.from_numeric(1, "USD").should == Money.new(1_00, "USD")
170
+ Money.should_receive(:from_bigdecimal).with(BigDecimal.new("1.0"), "USD").and_return(Money.new(1_00, "USD"))
171
+ Money.from_numeric(1.0, "USD").should == Money.new(1_00, "USD")
172
+ end
173
+
174
+ it "should respect :subunit_to_unit currency property" do
175
+ Money.from_numeric(1, "USD").should == Money.new(1_00, "USD")
176
+ Money.from_numeric(1, "TND").should == Money.new(1_000, "TND")
177
+ Money.from_numeric(1, "CLP").should == Money.new(1, "CLP")
178
+ end
179
+
180
+ it "accepts a bank option" do
181
+ Money.from_numeric(1).should == Money.new(1_00)
182
+ Money.from_numeric(1).should == Money.new(1_00, "USD")
183
+ Money.from_numeric(1, "EUR").should == Money.new(1_00, "EUR")
184
+ end
185
+
186
+ it "accepts a currency options" do
187
+ m = Money.from_numeric(1)
188
+ m.currency.should == Money.default_currency
189
+
190
+ m = Money.from_numeric(1, Money::Currency.wrap("EUR"))
191
+ m.currency.should == Money::Currency.wrap("EUR")
192
+
193
+ m = Money.from_numeric(1, "EUR")
194
+ m.currency.should == Money::Currency.wrap("EUR")
195
+ end
196
+ end
197
+ end
data/spec/money_spec.rb CHANGED
@@ -1,292 +1,292 @@
1
- # encoding: utf-8
2
-
3
- require "spec_helper"
4
-
5
- describe Money do
6
-
7
- describe "#new" do
8
- it "rounds the given cents to an integer" do
9
- Money.new(1.00, "USD").cents.should == 1
10
- Money.new(1.01, "USD").cents.should == 1
11
- Money.new(1.50, "USD").cents.should == 2
12
- end
13
-
14
- it "is associated to the singleton instance of Bank::VariableExchange by default" do
15
- Money.new(0).bank.should be_equal(Money::Bank::VariableExchange.instance)
16
- end
17
-
18
- end
19
-
20
- describe "#cents" do
21
- it "returns the amount of cents passed to the constructor" do
22
- Money.new(200_00, "USD").cents.should == 200_00
23
- end
24
-
25
- it "stores cents as an integer regardless of what is passed into the constructor" do
26
- [ Money.new(100), 1.to_money, 1.00.to_money, BigDecimal('1.00').to_money ].each do |m|
27
- m.cents.should == 100
28
- m.cents.should be_an_instance_of(Fixnum)
29
- end
30
- end
31
- end
32
-
33
- describe "#dollars" do
34
- it "gets cents as dollars" do
35
- Money.new_with_dollars(1).should == Money.new(100)
36
- Money.new_with_dollars(1, "USD").should == Money.new(100, "USD")
37
- Money.new_with_dollars(1, "EUR").should == Money.new(100, "EUR")
38
- end
39
-
40
- it "should respect :subunit_to_unit currency property" do
41
- Money.new(1_00, "USD").dollars.should == 1
42
- Money.new(1_000, "TND").dollars.should == 1
43
- Money.new(1, "CLP").dollars.should == 1
44
- end
45
-
46
- it "should not loose precision" do
47
- Money.new(100_37).dollars.should == 100.37
48
- Money.new_with_dollars(100.37).dollars.should == 100.37
49
- end
50
- end
51
-
52
- specify "#currency returns the currency passed to the constructor" do
53
- Money.new(200_00, "USD").currency.should == Money::Currency.new("USD")
54
- end
55
-
56
- specify "#currency_string returns the iso_code of the currency object" do
57
- Money.new(200_00, "USD").currency_as_string.should == Money::Currency.new("USD").to_s
58
- Money.new(200_00, "USD").currency_as_string.should == "USD"
59
- Money.new(200_00, "EUR").currency_as_string.should == "EUR"
60
- Money.new(200_00, "YEN").currency_as_string.should == "YEN"
61
- end
62
-
63
- specify "#currency_string= set the currency object using the provided string" do
64
- obj = Money.new(200_00, "USD")
65
- obj.currency_as_string = "EUR"
66
- obj.currency.should == Money::Currency.new("EUR")
67
- obj.currency_as_string = "YEN"
68
- obj.currency.should == Money::Currency.new("YEN")
69
- obj.currency_as_string = "USD"
70
- obj.currency.should == Money::Currency.new("USD")
71
- end
72
-
73
-
74
- specify "#exchange_to exchanges the amount via its exchange bank" do
75
- money = Money.new(100_00, "USD")
76
- money.bank.should_receive(:exchange_with).with(Money.new(100_00, Money::Currency.new("USD")), Money::Currency.new("EUR")).and_return(Money.new(200_00, Money::Currency.new('EUR')))
77
- money.exchange_to("EUR")
78
- end
79
-
80
- specify "#exchange_to exchanges the amount properly" do
81
- money = Money.new(100_00, "USD")
82
- money.bank.should_receive(:exchange_with).with(Money.new(100_00, Money::Currency.new("USD")), Money::Currency.new("EUR")).and_return(Money.new(200_00, Money::Currency.new('EUR')))
83
- money.exchange_to("EUR").should == Money.new(200_00, "EUR")
84
- end
85
-
86
- specify "#hash should return the same value for equal objects" do
87
- Money.new(1_00, :eur).hash.should == Money.new(1_00, :eur).hash
88
- Money.new(2_00, :usd).hash.should == Money.new(2_00, :usd).hash
89
- Money.new(1_00, :eur).hash.should_not == Money.new(2_00, :eur).hash
90
- Money.new(1_00, :eur).hash.should_not == Money.new(1_00, :usd).hash
91
- Money.new(1_00, :eur).hash.should_not == Money.new(2_00, :usd).hash
92
- end
93
-
94
- specify "#hash can be used to return the intersection of Money object arrays" do
95
- intersection = [Money.new(1_00, :eur), Money.new(1_00, :usd)] & [Money.new(1_00, :eur)]
96
- intersection.should == [Money.new(1_00, :eur)]
97
- end
98
-
99
-
100
- specify "Money.to_s works" do
101
- Money.new(10_00).to_s.should == "10.00"
102
- Money.new(400_08).to_s.should == "400.08"
103
- Money.new(-237_43).to_s.should == "-237.43"
104
- end
105
-
106
- specify "Money.to_s should respect :subunit_to_unit currency property" do
107
- Money.new(10_00, "BHD").to_s.should == "1.000"
108
- Money.new(10_00, "CNY").to_s.should == "10.00"
109
- end
110
-
111
- specify "Money.to_s shouldn't have decimal when :subunit_to_unit is 1" do
112
- Money.new(10_00, "CLP").to_s.should == "1000"
113
- end
114
-
115
- specify "Money.to_s should work with :subunit_to_unit == 5" do
116
- Money.new(10_00, "MGA").to_s.should == "200.0"
117
- end
118
-
119
- specify "Money.to_s should respect :decimal_mark" do
120
- Money.new(10_00, "BRL").to_s.should == "10,00"
121
- end
122
-
123
- specify "Money.to_d works" do
124
- decimal = Money.new(10_00).to_d
125
- decimal.should be_instance_of(BigDecimal)
126
- decimal.should == 10.0
127
- end
128
-
129
- specify "Money.to_d should respect :subunit_to_unit currency property" do
130
- decimal = Money.new(10_00, "BHD").to_d
131
- decimal.should be_instance_of(BigDecimal)
132
- decimal.should == 1.0
133
- end
134
-
135
- specify "Money.to_d should work with float :subunit_to_unit currency property" do
136
- money = Money.new(10_00, "BHD")
137
- money.currency.stub(:subunit_to_unit).and_return(1000.0)
138
-
139
- decimal = money.to_d
140
- decimal.should be_instance_of(BigDecimal)
141
- decimal.should == 1.0
142
- end
143
-
144
- specify "Money.to_f works" do
145
- Money.new(10_00).to_f.should == 10.0
146
- end
147
-
148
- specify "Money.to_f should respect :subunit_to_unit currency property" do
149
- Money.new(10_00, "BHD").to_f.should == 1.0
150
- end
151
-
152
- specify "#symbol works as documented" do
153
- currency = Money::Currency.new("EUR")
154
- currency.should_receive(:symbol).and_return("€")
155
- Money.empty(currency).symbol.should == "€"
156
-
157
- currency = Money::Currency.new("EUR")
158
- currency.should_receive(:symbol).and_return(nil)
159
- Money.empty(currency).symbol.should == "¤"
160
- end
161
-
162
- describe "Money.empty" do
163
- it "Money.empty creates a new Money object of 0 cents" do
164
- Money.empty.should == Money.new(0)
165
- end
166
- end
167
-
168
- describe "Money.ca_dollar" do
169
- it "creates a new Money object of the given value in CAD" do
170
- Money.ca_dollar(50).should == Money.new(50, "CAD")
171
- end
172
- end
173
-
174
- describe "Money.us_dollar" do
175
- it "creates a new Money object of the given value in USD" do
176
- Money.us_dollar(50).should == Money.new(50, "USD")
177
- end
178
- end
179
-
180
- describe "Money.euro" do
181
- it "creates a new Money object of the given value in EUR" do
182
- Money.euro(50).should == Money.new(50, "EUR")
183
- end
184
- end
185
-
186
-
187
- describe "Money.new_with_dollars" do
188
- it "converts given amount to cents" do
189
- Money.new_with_dollars(1).should == Money.new(100)
190
- Money.new_with_dollars(1, "USD").should == Money.new(100, "USD")
191
- Money.new_with_dollars(1, "EUR").should == Money.new(100, "EUR")
192
- end
193
-
194
- it "should respect :subunit_to_unit currency property" do
195
- Money.new_with_dollars(1, "USD").should == Money.new(1_00, "USD")
196
- Money.new_with_dollars(1, "TND").should == Money.new(1_000, "TND")
197
- Money.new_with_dollars(1, "CLP").should == Money.new(1, "CLP")
198
- end
199
-
200
- it "should not loose precision" do
201
- Money.new_with_dollars(1234).cents.should == 1234_00
202
- Money.new_with_dollars(100.37).cents.should == 100_37
203
- Money.new_with_dollars(BigDecimal.new('1234')).cents.should == 1234_00
204
- end
205
-
206
- it "accepts a currency options" do
207
- m = Money.new_with_dollars(1)
208
- m.currency.should == Money.default_currency
209
-
210
- m = Money.new_with_dollars(1, Money::Currency.wrap("EUR"))
211
- m.currency.should == Money::Currency.wrap("EUR")
212
-
213
- m = Money.new_with_dollars(1, "EUR")
214
- m.currency.should == Money::Currency.wrap("EUR")
215
- end
216
-
217
- it "accepts a bank options" do
218
- m = Money.new_with_dollars(1)
219
- m.bank.should == Money.default_bank
220
-
221
- m = Money.new_with_dollars(1, "EUR", bank = Object.new)
222
- m.bank.should == bank
223
- end
224
-
225
- it "is associated to the singleton instance of Bank::VariableExchange by default" do
226
- Money.new_with_dollars(0).bank.should be_equal(Money::Bank::VariableExchange.instance)
227
- end
228
- end
229
-
230
- describe "split" do
231
- specify "#split needs at least one party" do
232
- lambda {Money.us_dollar(1).split(0)}.should raise_error(ArgumentError)
233
- lambda {Money.us_dollar(1).split(-1)}.should raise_error(ArgumentError)
234
- end
235
-
236
-
237
- specify "#gives 1 cent to both people if we start with 2" do
238
- Money.us_dollar(2).split(2).should == [Money.us_dollar(1), Money.us_dollar(1)]
239
- end
240
-
241
- specify "#split may distribute no money to some parties if there isnt enough to go around" do
242
- Money.us_dollar(2).split(3).should == [Money.us_dollar(1), Money.us_dollar(1), Money.us_dollar(0)]
243
- end
244
-
245
- specify "#split does not lose pennies" do
246
- Money.us_dollar(5).split(2).should == [Money.us_dollar(3), Money.us_dollar(2)]
247
- end
248
-
249
- specify "#split a dollar" do
250
- moneys = Money.us_dollar(100).split(3)
251
- moneys[0].cents.should == 34
252
- moneys[1].cents.should == 33
253
- moneys[2].cents.should == 33
254
- end
255
- end
256
-
257
- describe "allocation" do
258
- specify "#allocate takes no action when one gets all" do
259
- Money.us_dollar(005).allocate([1.0]).should == [Money.us_dollar(5)]
260
- end
261
-
262
- specify "#allocate keeps currencies intact" do
263
- Money.ca_dollar(005).allocate([1]).should == [Money.ca_dollar(5)]
264
- end
265
-
266
- specify "#allocate does not loose pennies" do
267
- moneys = Money.us_dollar(5).allocate([0.3,0.7])
268
- moneys[0].should == Money.us_dollar(2)
269
- moneys[1].should == Money.us_dollar(3)
270
- end
271
-
272
- specify "#allocate does not loose pennies" do
273
- moneys = Money.us_dollar(100).allocate([0.333,0.333, 0.333])
274
- moneys[0].cents.should == 34
275
- moneys[1].cents.should == 33
276
- moneys[2].cents.should == 33
277
- end
278
-
279
- specify "#allocate requires total to be less then 1" do
280
- lambda { Money.us_dollar(0.05).allocate([0.5,0.6]) }.should raise_error(ArgumentError)
281
- end
282
- end
283
-
284
- describe "Money.add_rate" do
285
- it "saves rate into current bank" do
286
- Money.add_rate("EUR", "USD", 10)
287
- Money.new(10_00, "EUR").exchange_to("USD").should == Money.new(100_00, "USD")
288
- end
289
- end
290
-
291
- end
292
-
1
+ # encoding: utf-8
2
+
3
+ require "spec_helper"
4
+
5
+ describe Money do
6
+
7
+ describe "#new" do
8
+ it "rounds the given cents to an integer" do
9
+ Money.new(1.00, "USD").cents.should == 1
10
+ Money.new(1.01, "USD").cents.should == 1
11
+ Money.new(1.50, "USD").cents.should == 2
12
+ end
13
+
14
+ it "is associated to the singleton instance of Bank::VariableExchange by default" do
15
+ Money.new(0).bank.should be_equal(Money::Bank::VariableExchange.instance)
16
+ end
17
+
18
+ end
19
+
20
+ describe "#cents" do
21
+ it "returns the amount of cents passed to the constructor" do
22
+ Money.new(200_00, "USD").cents.should == 200_00
23
+ end
24
+
25
+ it "stores cents as an integer regardless of what is passed into the constructor" do
26
+ [ Money.new(100), 1.to_money, 1.00.to_money, BigDecimal('1.00').to_money ].each do |m|
27
+ m.cents.should == 100
28
+ m.cents.should be_an_instance_of(Fixnum)
29
+ end
30
+ end
31
+ end
32
+
33
+ describe "#dollars" do
34
+ it "gets cents as dollars" do
35
+ Money.new_with_dollars(1).should == Money.new(100)
36
+ Money.new_with_dollars(1, "USD").should == Money.new(100, "USD")
37
+ Money.new_with_dollars(1, "EUR").should == Money.new(100, "EUR")
38
+ end
39
+
40
+ it "should respect :subunit_to_unit currency property" do
41
+ Money.new(1_00, "USD").dollars.should == 1
42
+ Money.new(1_000, "TND").dollars.should == 1
43
+ Money.new(1, "CLP").dollars.should == 1
44
+ end
45
+
46
+ it "should not loose precision" do
47
+ Money.new(100_37).dollars.should == 100.37
48
+ Money.new_with_dollars(100.37).dollars.should == 100.37
49
+ end
50
+ end
51
+
52
+ specify "#currency returns the currency passed to the constructor" do
53
+ Money.new(200_00, "USD").currency.should == Money::Currency.new("USD")
54
+ end
55
+
56
+ specify "#currency_string returns the iso_code of the currency object" do
57
+ Money.new(200_00, "USD").currency_as_string.should == Money::Currency.new("USD").to_s
58
+ Money.new(200_00, "USD").currency_as_string.should == "USD"
59
+ Money.new(200_00, "EUR").currency_as_string.should == "EUR"
60
+ Money.new(200_00, "YEN").currency_as_string.should == "YEN"
61
+ end
62
+
63
+ specify "#currency_string= set the currency object using the provided string" do
64
+ obj = Money.new(200_00, "USD")
65
+ obj.currency_as_string = "EUR"
66
+ obj.currency.should == Money::Currency.new("EUR")
67
+ obj.currency_as_string = "YEN"
68
+ obj.currency.should == Money::Currency.new("YEN")
69
+ obj.currency_as_string = "USD"
70
+ obj.currency.should == Money::Currency.new("USD")
71
+ end
72
+
73
+
74
+ specify "#exchange_to exchanges the amount via its exchange bank" do
75
+ money = Money.new(100_00, "USD")
76
+ money.bank.should_receive(:exchange_with).with(Money.new(100_00, Money::Currency.new("USD")), Money::Currency.new("EUR")).and_return(Money.new(200_00, Money::Currency.new('EUR')))
77
+ money.exchange_to("EUR")
78
+ end
79
+
80
+ specify "#exchange_to exchanges the amount properly" do
81
+ money = Money.new(100_00, "USD")
82
+ money.bank.should_receive(:exchange_with).with(Money.new(100_00, Money::Currency.new("USD")), Money::Currency.new("EUR")).and_return(Money.new(200_00, Money::Currency.new('EUR')))
83
+ money.exchange_to("EUR").should == Money.new(200_00, "EUR")
84
+ end
85
+
86
+ specify "#hash should return the same value for equal objects" do
87
+ Money.new(1_00, :eur).hash.should == Money.new(1_00, :eur).hash
88
+ Money.new(2_00, :usd).hash.should == Money.new(2_00, :usd).hash
89
+ Money.new(1_00, :eur).hash.should_not == Money.new(2_00, :eur).hash
90
+ Money.new(1_00, :eur).hash.should_not == Money.new(1_00, :usd).hash
91
+ Money.new(1_00, :eur).hash.should_not == Money.new(2_00, :usd).hash
92
+ end
93
+
94
+ specify "#hash can be used to return the intersection of Money object arrays" do
95
+ intersection = [Money.new(1_00, :eur), Money.new(1_00, :usd)] & [Money.new(1_00, :eur)]
96
+ intersection.should == [Money.new(1_00, :eur)]
97
+ end
98
+
99
+
100
+ specify "Money.to_s works" do
101
+ Money.new(10_00).to_s.should == "10.00"
102
+ Money.new(400_08).to_s.should == "400.08"
103
+ Money.new(-237_43).to_s.should == "-237.43"
104
+ end
105
+
106
+ specify "Money.to_s should respect :subunit_to_unit currency property" do
107
+ Money.new(10_00, "BHD").to_s.should == "1.000"
108
+ Money.new(10_00, "CNY").to_s.should == "10.00"
109
+ end
110
+
111
+ specify "Money.to_s shouldn't have decimal when :subunit_to_unit is 1" do
112
+ Money.new(10_00, "CLP").to_s.should == "1000"
113
+ end
114
+
115
+ specify "Money.to_s should work with :subunit_to_unit == 5" do
116
+ Money.new(10_00, "MGA").to_s.should == "200.0"
117
+ end
118
+
119
+ specify "Money.to_s should respect :decimal_mark" do
120
+ Money.new(10_00, "BRL").to_s.should == "10,00"
121
+ end
122
+
123
+ specify "Money.to_d works" do
124
+ decimal = Money.new(10_00).to_d
125
+ decimal.should be_instance_of(BigDecimal)
126
+ decimal.should == 10.0
127
+ end
128
+
129
+ specify "Money.to_d should respect :subunit_to_unit currency property" do
130
+ decimal = Money.new(10_00, "BHD").to_d
131
+ decimal.should be_instance_of(BigDecimal)
132
+ decimal.should == 1.0
133
+ end
134
+
135
+ specify "Money.to_d should work with float :subunit_to_unit currency property" do
136
+ money = Money.new(10_00, "BHD")
137
+ money.currency.stub(:subunit_to_unit).and_return(1000.0)
138
+
139
+ decimal = money.to_d
140
+ decimal.should be_instance_of(BigDecimal)
141
+ decimal.should == 1.0
142
+ end
143
+
144
+ specify "Money.to_f works" do
145
+ Money.new(10_00).to_f.should == 10.0
146
+ end
147
+
148
+ specify "Money.to_f should respect :subunit_to_unit currency property" do
149
+ Money.new(10_00, "BHD").to_f.should == 1.0
150
+ end
151
+
152
+ specify "#symbol works as documented" do
153
+ currency = Money::Currency.new("EUR")
154
+ currency.should_receive(:symbol).and_return("€")
155
+ Money.empty(currency).symbol.should == "€"
156
+
157
+ currency = Money::Currency.new("EUR")
158
+ currency.should_receive(:symbol).and_return(nil)
159
+ Money.empty(currency).symbol.should == "¤"
160
+ end
161
+
162
+ describe "Money.empty" do
163
+ it "Money.empty creates a new Money object of 0 cents" do
164
+ Money.empty.should == Money.new(0)
165
+ end
166
+ end
167
+
168
+ describe "Money.ca_dollar" do
169
+ it "creates a new Money object of the given value in CAD" do
170
+ Money.ca_dollar(50).should == Money.new(50, "CAD")
171
+ end
172
+ end
173
+
174
+ describe "Money.us_dollar" do
175
+ it "creates a new Money object of the given value in USD" do
176
+ Money.us_dollar(50).should == Money.new(50, "USD")
177
+ end
178
+ end
179
+
180
+ describe "Money.euro" do
181
+ it "creates a new Money object of the given value in EUR" do
182
+ Money.euro(50).should == Money.new(50, "EUR")
183
+ end
184
+ end
185
+
186
+
187
+ describe "Money.new_with_dollars" do
188
+ it "converts given amount to cents" do
189
+ Money.new_with_dollars(1).should == Money.new(100)
190
+ Money.new_with_dollars(1, "USD").should == Money.new(100, "USD")
191
+ Money.new_with_dollars(1, "EUR").should == Money.new(100, "EUR")
192
+ end
193
+
194
+ it "should respect :subunit_to_unit currency property" do
195
+ Money.new_with_dollars(1, "USD").should == Money.new(1_00, "USD")
196
+ Money.new_with_dollars(1, "TND").should == Money.new(1_000, "TND")
197
+ Money.new_with_dollars(1, "CLP").should == Money.new(1, "CLP")
198
+ end
199
+
200
+ it "should not loose precision" do
201
+ Money.new_with_dollars(1234).cents.should == 1234_00
202
+ Money.new_with_dollars(100.37).cents.should == 100_37
203
+ Money.new_with_dollars(BigDecimal.new('1234')).cents.should == 1234_00
204
+ end
205
+
206
+ it "accepts a currency options" do
207
+ m = Money.new_with_dollars(1)
208
+ m.currency.should == Money.default_currency
209
+
210
+ m = Money.new_with_dollars(1, Money::Currency.wrap("EUR"))
211
+ m.currency.should == Money::Currency.wrap("EUR")
212
+
213
+ m = Money.new_with_dollars(1, "EUR")
214
+ m.currency.should == Money::Currency.wrap("EUR")
215
+ end
216
+
217
+ it "accepts a bank options" do
218
+ m = Money.new_with_dollars(1)
219
+ m.bank.should == Money.default_bank
220
+
221
+ m = Money.new_with_dollars(1, "EUR", bank = Object.new)
222
+ m.bank.should == bank
223
+ end
224
+
225
+ it "is associated to the singleton instance of Bank::VariableExchange by default" do
226
+ Money.new_with_dollars(0).bank.should be_equal(Money::Bank::VariableExchange.instance)
227
+ end
228
+ end
229
+
230
+ describe "split" do
231
+ specify "#split needs at least one party" do
232
+ lambda {Money.us_dollar(1).split(0)}.should raise_error(ArgumentError)
233
+ lambda {Money.us_dollar(1).split(-1)}.should raise_error(ArgumentError)
234
+ end
235
+
236
+
237
+ specify "#gives 1 cent to both people if we start with 2" do
238
+ Money.us_dollar(2).split(2).should == [Money.us_dollar(1), Money.us_dollar(1)]
239
+ end
240
+
241
+ specify "#split may distribute no money to some parties if there isnt enough to go around" do
242
+ Money.us_dollar(2).split(3).should == [Money.us_dollar(1), Money.us_dollar(1), Money.us_dollar(0)]
243
+ end
244
+
245
+ specify "#split does not lose pennies" do
246
+ Money.us_dollar(5).split(2).should == [Money.us_dollar(3), Money.us_dollar(2)]
247
+ end
248
+
249
+ specify "#split a dollar" do
250
+ moneys = Money.us_dollar(100).split(3)
251
+ moneys[0].cents.should == 34
252
+ moneys[1].cents.should == 33
253
+ moneys[2].cents.should == 33
254
+ end
255
+ end
256
+
257
+ describe "allocation" do
258
+ specify "#allocate takes no action when one gets all" do
259
+ Money.us_dollar(005).allocate([1.0]).should == [Money.us_dollar(5)]
260
+ end
261
+
262
+ specify "#allocate keeps currencies intact" do
263
+ Money.ca_dollar(005).allocate([1]).should == [Money.ca_dollar(5)]
264
+ end
265
+
266
+ specify "#allocate does not loose pennies" do
267
+ moneys = Money.us_dollar(5).allocate([0.3,0.7])
268
+ moneys[0].should == Money.us_dollar(2)
269
+ moneys[1].should == Money.us_dollar(3)
270
+ end
271
+
272
+ specify "#allocate does not loose pennies" do
273
+ moneys = Money.us_dollar(100).allocate([0.333,0.333, 0.333])
274
+ moneys[0].cents.should == 34
275
+ moneys[1].cents.should == 33
276
+ moneys[2].cents.should == 33
277
+ end
278
+
279
+ specify "#allocate requires total to be less then 1" do
280
+ lambda { Money.us_dollar(0.05).allocate([0.5,0.6]) }.should raise_error(ArgumentError)
281
+ end
282
+ end
283
+
284
+ describe "Money.add_rate" do
285
+ it "saves rate into current bank" do
286
+ Money.add_rate("EUR", "USD", 10)
287
+ Money.new(10_00, "EUR").exchange_to("USD").should == Money.new(100_00, "USD")
288
+ end
289
+ end
290
+
291
+ end
292
+