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,246 +1,246 @@
1
- class Money
2
- module Arithmetic
3
-
4
- # Checks whether two money objects have the same currency and the same
5
- # amount. Checks against money objects with a different currency and checks
6
- # against objects that do not respond to #to_money will always return false.
7
- #
8
- # @param [Money] other_money Value to compare with.
9
- #
10
- # @return [Boolean]
11
- #
12
- # @example
13
- # Money.new(100) == Money.new(101) #=> false
14
- # Money.new(100) == Money.new(100) #=> true
15
- def ==(other_money)
16
- if other_money.respond_to?(:to_money)
17
- other_money = other_money.to_money
18
- cents == other_money.cents && self.currency == other_money.currency
19
- else
20
- false
21
- end
22
- end
23
-
24
- # Synonymous with +#==+.
25
- #
26
- # @param [Money] other_money Value to compare with.
27
- #
28
- # @return [Money]
29
- #
30
- # @see #==
31
- def eql?(other_money)
32
- self == other_money
33
- end
34
-
35
- def <=>(other_money)
36
- if other_money.respond_to?(:to_money)
37
- other_money = other_money.to_money
38
- if self.currency == other_money.currency
39
- cents <=> other_money.cents
40
- else
41
- cents <=> other_money.exchange_to(currency).cents
42
- end
43
- else
44
- raise ArgumentError, "Comparison of #{self.class} with #{other_money.inspect} failed"
45
- end
46
- end
47
-
48
- # Returns a new Money object containing the sum of the two operands' monetary
49
- # values. If +other_money+ has a different currency then its monetary value
50
- # is automatically exchanged to this object's currency using +exchange_to+.
51
- #
52
- # @param [Money] other_money Other +Money+ object to add.
53
- #
54
- # @return [Money]
55
- #
56
- # @example
57
- # Money.new(100) + Money.new(100) #=> #<Money @cents=200>
58
- def +(other_money)
59
- if currency == other_money.currency
60
- Money.new(cents + other_money.cents, other_money.currency)
61
- else
62
- Money.new(cents + other_money.exchange_to(currency).cents, currency)
63
- end
64
- end
65
-
66
- # Returns a new Money object containing the difference between the two
67
- # operands' monetary values. If +other_money+ has a different currency then
68
- # its monetary value is automatically exchanged to this object's currency
69
- # using +exchange_to+.
70
- #
71
- # @param [Money] other_money Other +Money+ object to subtract.
72
- #
73
- # @return [Money]
74
- #
75
- # @example
76
- # Money.new(100) - Money.new(99) #=> #<Money @cents=1>
77
- def -(other_money)
78
- if currency == other_money.currency
79
- Money.new(cents - other_money.cents, other_money.currency)
80
- else
81
- Money.new(cents - other_money.exchange_to(currency).cents, currency)
82
- end
83
- end
84
-
85
- # Multiplies the monetary value with the given number and returns a new
86
- # +Money+ object with this monetary value and the same currency.
87
- #
88
- # Note that you can't multiply a Money object by an other +Money+ object.
89
- #
90
- # @param [Numeric] value Number to multiply by.
91
- #
92
- # @return [Money] The resulting money.
93
- #
94
- # @raise [ArgumentError] If +value+ is a Money instance.
95
- #
96
- # @example
97
- # Money.new(100) * 2 #=> #<Money @cents=200>
98
- #
99
- def *(value)
100
- if value.is_a?(Money)
101
- raise ArgumentError, "Can't multiply a Money by a Money"
102
- else
103
- Money.new(cents * value, currency)
104
- end
105
- end
106
-
107
- # Divides the monetary value with the given number and returns a new +Money+
108
- # object with this monetary value and the same currency.
109
- # Can also divide by another +Money+ object to get a ratio.
110
- #
111
- # +Money/Numeric+ returns +Money+. +Money/Money+ returns +Float+.
112
- #
113
- # @param [Money, Numeric] value Number to divide by.
114
- #
115
- # @return [Money] The resulting money if you divide Money by a number.
116
- # @return [Float] The resulting number if you divide Money by a Money.
117
- #
118
- # @example
119
- # Money.new(100) / 10 #=> #<Money @cents=10>
120
- # Money.new(100) / Money.new(10) #=> 10.0
121
- #
122
- def /(value)
123
- if value.is_a?(Money)
124
- if currency == value.currency
125
- (cents / BigDecimal.new(value.cents.to_s)).to_f
126
- else
127
- (cents / BigDecimal(value.exchange_to(currency).cents.to_s)).to_f
128
- end
129
- else
130
- Money.new(cents / value, currency)
131
- end
132
- end
133
-
134
- # Synonym for +#/+.
135
- #
136
- # @param [Money, Numeric] value Number to divide by.
137
- #
138
- # @return [Money] The resulting money if you divide Money by a number.
139
- # @return [Float] The resulting number if you divide Money by a Money.
140
- #
141
- # @see #/
142
- #
143
- def div(value)
144
- self / value
145
- end
146
-
147
- # Divide money by money or fixnum and return array containing quotient and
148
- # modulus.
149
- #
150
- # @param [Money, Fixnum] val Number to divmod by.
151
- #
152
- # @return [Array<Money,Money>,Array<Fixnum,Money>]
153
- #
154
- # @example
155
- # Money.new(100).divmod(9) #=> [#<Money @cents=11>, #<Money @cents=1>]
156
- # Money.new(100).divmod(Money.new(9)) #=> [11, #<Money @cents=1>]
157
- def divmod(val)
158
- if val.is_a?(Money)
159
- a = self.cents
160
- b = self.currency == val.currency ? val.cents : val.exchange_to(self.currency).cents
161
- q, m = a.divmod(b)
162
- return [q, Money.new(m, self.currency)]
163
- else
164
- return [self.div(val), Money.new(self.cents.modulo(val), self.currency)]
165
- end
166
- end
167
-
168
- # Equivalent to +self.divmod(val)[1]+
169
- #
170
- # @param [Money, Fixnum] val Number take modulo with.
171
- #
172
- # @return [Money]
173
- #
174
- # @example
175
- # Money.new(100).modulo(9) #=> #<Money @cents=1>
176
- # Money.new(100).modulo(Money.new(9)) #=> #<Money @cents=1>
177
- def modulo(val)
178
- self.divmod(val)[1]
179
- end
180
-
181
- # Synonym for +#modulo+.
182
- #
183
- # @param [Money, Fixnum] val Number take modulo with.
184
- #
185
- # @return [Money]
186
- #
187
- # @see #modulo
188
- def %(val)
189
- self.modulo(val)
190
- end
191
-
192
- # If different signs +self.modulo(val) - val+ otherwise +self.modulo(val)+
193
- #
194
- # @param [Money, Fixnum] val Number to rake remainder with.
195
- #
196
- # @return [Money]
197
- #
198
- # @example
199
- # Money.new(100).remainder(9) #=> #<Money @cents=1>
200
- def remainder(val)
201
- a, b = self, val
202
- b = b.exchange_to(a.currency) if b.is_a?(Money) and a.currency != b.currency
203
-
204
- a_sign, b_sign = :pos, :pos
205
- a_sign = :neg if a.cents < 0
206
- b_sign = :neg if (b.is_a?(Money) and b.cents < 0) or (b < 0)
207
-
208
- return a.modulo(b) if a_sign == b_sign
209
- a.modulo(b) - (b.is_a?(Money) ? b : Money.new(b, a.currency))
210
- end
211
-
212
- # Return absolute value of self as a new Money object.
213
- #
214
- # @return [Money]
215
- #
216
- # @example
217
- # Money.new(-100).abs #=> #<Money @cents=100>
218
- def abs
219
- Money.new(self.cents.abs, self.currency)
220
- end
221
-
222
- # Test if the money amount is zero.
223
- #
224
- # @return [Boolean]
225
- #
226
- # @example
227
- # Money.new(100).zero? #=> false
228
- # Money.new(0).zero? #=> true
229
- def zero?
230
- cents == 0
231
- end
232
-
233
- # Test if the money amount is non-zero. Returns this money object if it is
234
- # non-zero, or nil otherwise, like +Numeric#nonzero?+.
235
- #
236
- # @return [Money, nil]
237
- #
238
- # @example
239
- # Money.new(100).nonzero? #=> #<Money @cents=100>
240
- # Money.new(0).nonzero? #=> nil
241
- def nonzero?
242
- cents != 0 ? self : nil
243
- end
244
-
245
- end
246
- end
1
+ class Money
2
+ module Arithmetic
3
+
4
+ # Checks whether two money objects have the same currency and the same
5
+ # amount. Checks against money objects with a different currency and checks
6
+ # against objects that do not respond to #to_money will always return false.
7
+ #
8
+ # @param [Money] other_money Value to compare with.
9
+ #
10
+ # @return [Boolean]
11
+ #
12
+ # @example
13
+ # Money.new(100) == Money.new(101) #=> false
14
+ # Money.new(100) == Money.new(100) #=> true
15
+ def ==(other_money)
16
+ if other_money.respond_to?(:to_money)
17
+ other_money = other_money.to_money
18
+ cents == other_money.cents && self.currency == other_money.currency
19
+ else
20
+ false
21
+ end
22
+ end
23
+
24
+ # Synonymous with +#==+.
25
+ #
26
+ # @param [Money] other_money Value to compare with.
27
+ #
28
+ # @return [Money]
29
+ #
30
+ # @see #==
31
+ def eql?(other_money)
32
+ self == other_money
33
+ end
34
+
35
+ def <=>(other_money)
36
+ if other_money.respond_to?(:to_money)
37
+ other_money = other_money.to_money
38
+ if self.currency == other_money.currency
39
+ cents <=> other_money.cents
40
+ else
41
+ cents <=> other_money.exchange_to(currency).cents
42
+ end
43
+ else
44
+ raise ArgumentError, "Comparison of #{self.class} with #{other_money.inspect} failed"
45
+ end
46
+ end
47
+
48
+ # Returns a new Money object containing the sum of the two operands' monetary
49
+ # values. If +other_money+ has a different currency then its monetary value
50
+ # is automatically exchanged to this object's currency using +exchange_to+.
51
+ #
52
+ # @param [Money] other_money Other +Money+ object to add.
53
+ #
54
+ # @return [Money]
55
+ #
56
+ # @example
57
+ # Money.new(100) + Money.new(100) #=> #<Money @cents=200>
58
+ def +(other_money)
59
+ if currency == other_money.currency
60
+ Money.new(cents + other_money.cents, other_money.currency)
61
+ else
62
+ Money.new(cents + other_money.exchange_to(currency).cents, currency)
63
+ end
64
+ end
65
+
66
+ # Returns a new Money object containing the difference between the two
67
+ # operands' monetary values. If +other_money+ has a different currency then
68
+ # its monetary value is automatically exchanged to this object's currency
69
+ # using +exchange_to+.
70
+ #
71
+ # @param [Money] other_money Other +Money+ object to subtract.
72
+ #
73
+ # @return [Money]
74
+ #
75
+ # @example
76
+ # Money.new(100) - Money.new(99) #=> #<Money @cents=1>
77
+ def -(other_money)
78
+ if currency == other_money.currency
79
+ Money.new(cents - other_money.cents, other_money.currency)
80
+ else
81
+ Money.new(cents - other_money.exchange_to(currency).cents, currency)
82
+ end
83
+ end
84
+
85
+ # Multiplies the monetary value with the given number and returns a new
86
+ # +Money+ object with this monetary value and the same currency.
87
+ #
88
+ # Note that you can't multiply a Money object by an other +Money+ object.
89
+ #
90
+ # @param [Numeric] value Number to multiply by.
91
+ #
92
+ # @return [Money] The resulting money.
93
+ #
94
+ # @raise [ArgumentError] If +value+ is a Money instance.
95
+ #
96
+ # @example
97
+ # Money.new(100) * 2 #=> #<Money @cents=200>
98
+ #
99
+ def *(value)
100
+ if value.is_a?(Money)
101
+ raise ArgumentError, "Can't multiply a Money by a Money"
102
+ else
103
+ Money.new(cents * value, currency)
104
+ end
105
+ end
106
+
107
+ # Divides the monetary value with the given number and returns a new +Money+
108
+ # object with this monetary value and the same currency.
109
+ # Can also divide by another +Money+ object to get a ratio.
110
+ #
111
+ # +Money/Numeric+ returns +Money+. +Money/Money+ returns +Float+.
112
+ #
113
+ # @param [Money, Numeric] value Number to divide by.
114
+ #
115
+ # @return [Money] The resulting money if you divide Money by a number.
116
+ # @return [Float] The resulting number if you divide Money by a Money.
117
+ #
118
+ # @example
119
+ # Money.new(100) / 10 #=> #<Money @cents=10>
120
+ # Money.new(100) / Money.new(10) #=> 10.0
121
+ #
122
+ def /(value)
123
+ if value.is_a?(Money)
124
+ if currency == value.currency
125
+ (cents / BigDecimal.new(value.cents.to_s)).to_f
126
+ else
127
+ (cents / BigDecimal(value.exchange_to(currency).cents.to_s)).to_f
128
+ end
129
+ else
130
+ Money.new(cents / value, currency)
131
+ end
132
+ end
133
+
134
+ # Synonym for +#/+.
135
+ #
136
+ # @param [Money, Numeric] value Number to divide by.
137
+ #
138
+ # @return [Money] The resulting money if you divide Money by a number.
139
+ # @return [Float] The resulting number if you divide Money by a Money.
140
+ #
141
+ # @see #/
142
+ #
143
+ def div(value)
144
+ self / value
145
+ end
146
+
147
+ # Divide money by money or fixnum and return array containing quotient and
148
+ # modulus.
149
+ #
150
+ # @param [Money, Fixnum] val Number to divmod by.
151
+ #
152
+ # @return [Array<Money,Money>,Array<Fixnum,Money>]
153
+ #
154
+ # @example
155
+ # Money.new(100).divmod(9) #=> [#<Money @cents=11>, #<Money @cents=1>]
156
+ # Money.new(100).divmod(Money.new(9)) #=> [11, #<Money @cents=1>]
157
+ def divmod(val)
158
+ if val.is_a?(Money)
159
+ a = self.cents
160
+ b = self.currency == val.currency ? val.cents : val.exchange_to(self.currency).cents
161
+ q, m = a.divmod(b)
162
+ return [q, Money.new(m, self.currency)]
163
+ else
164
+ return [self.div(val), Money.new(self.cents.modulo(val), self.currency)]
165
+ end
166
+ end
167
+
168
+ # Equivalent to +self.divmod(val)[1]+
169
+ #
170
+ # @param [Money, Fixnum] val Number take modulo with.
171
+ #
172
+ # @return [Money]
173
+ #
174
+ # @example
175
+ # Money.new(100).modulo(9) #=> #<Money @cents=1>
176
+ # Money.new(100).modulo(Money.new(9)) #=> #<Money @cents=1>
177
+ def modulo(val)
178
+ self.divmod(val)[1]
179
+ end
180
+
181
+ # Synonym for +#modulo+.
182
+ #
183
+ # @param [Money, Fixnum] val Number take modulo with.
184
+ #
185
+ # @return [Money]
186
+ #
187
+ # @see #modulo
188
+ def %(val)
189
+ self.modulo(val)
190
+ end
191
+
192
+ # If different signs +self.modulo(val) - val+ otherwise +self.modulo(val)+
193
+ #
194
+ # @param [Money, Fixnum] val Number to rake remainder with.
195
+ #
196
+ # @return [Money]
197
+ #
198
+ # @example
199
+ # Money.new(100).remainder(9) #=> #<Money @cents=1>
200
+ def remainder(val)
201
+ a, b = self, val
202
+ b = b.exchange_to(a.currency) if b.is_a?(Money) and a.currency != b.currency
203
+
204
+ a_sign, b_sign = :pos, :pos
205
+ a_sign = :neg if a.cents < 0
206
+ b_sign = :neg if (b.is_a?(Money) and b.cents < 0) or (b < 0)
207
+
208
+ return a.modulo(b) if a_sign == b_sign
209
+ a.modulo(b) - (b.is_a?(Money) ? b : Money.new(b, a.currency))
210
+ end
211
+
212
+ # Return absolute value of self as a new Money object.
213
+ #
214
+ # @return [Money]
215
+ #
216
+ # @example
217
+ # Money.new(-100).abs #=> #<Money @cents=100>
218
+ def abs
219
+ Money.new(self.cents.abs, self.currency)
220
+ end
221
+
222
+ # Test if the money amount is zero.
223
+ #
224
+ # @return [Boolean]
225
+ #
226
+ # @example
227
+ # Money.new(100).zero? #=> false
228
+ # Money.new(0).zero? #=> true
229
+ def zero?
230
+ cents == 0
231
+ end
232
+
233
+ # Test if the money amount is non-zero. Returns this money object if it is
234
+ # non-zero, or nil otherwise, like +Numeric#nonzero?+.
235
+ #
236
+ # @return [Money, nil]
237
+ #
238
+ # @example
239
+ # Money.new(100).nonzero? #=> #<Money @cents=100>
240
+ # Money.new(0).nonzero? #=> nil
241
+ def nonzero?
242
+ cents != 0 ? self : nil
243
+ end
244
+
245
+ end
246
+ end