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
@@ -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