money 2.3.0 → 3.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.
data/CHANGELOG.rdoc CHANGED
@@ -1,3 +1,8 @@
1
+ == Money 3.0.0
2
+ * Version Bump due to compatibility changes with ActiveRecord. See
3
+ http://github.com/FooBarWidget/money/issues#issue/4/comment/224880 for more
4
+ information.
5
+
1
6
  == Money 2.3.0
2
7
  * Currency is now represented by a Currency Object instead of a string.
3
8
 
data/README.rdoc CHANGED
@@ -2,13 +2,13 @@
2
2
 
3
3
  This library aids one in handling money and different currencies. Features:
4
4
 
5
- - Provides a Money class which encapsulates all information about an certain
5
+ - Provides a <tt>Money</tt> class which encapsulates all information about an certain
6
6
  amount of money, such as its value and its currency.
7
- - Provies a Currency class which encapsulates all information about
7
+ - Provies a <tt>Money::Currency</tt> class which encapsulates all information about
8
8
  a monerary unit.
9
9
  - Represents monetary values as integers, in cents. This avoids floating point
10
10
  rounding errors.
11
- - Represents currency as Currency instances providing an high level of flexibility.
11
+ - Represents currency as <tt>Money::Currency</tt> instances providing an high level of flexibility.
12
12
  - Provides APIs for exchanging money from one currency to another.
13
13
  - Has the ability to parse a money and currency strings
14
14
  into the corresponding Money/Currency object.
@@ -48,13 +48,13 @@ The development version (hosted on Github) can be installed with:
48
48
 
49
49
  === Currency
50
50
 
51
- Currencies are consistently represented as instances of Money::Currency.
52
- The most part of Money APIs allows you to supply either a String or a Currency.
51
+ Currencies are consistently represented as instances of <tt>Money::Currency</tt>.
52
+ The most part of <tt>Money</tt> APIs allows you to supply either a <tt>String</tt> or a <tt>Money::Currency</tt>.
53
53
 
54
54
  Money.new(1000, "USD") == Money.new(900, Currency.new("USD"))
55
55
  Money.new(1000, "EUR").currency == Currency.new("EUR")
56
56
 
57
- A Money::Currency instance holds all the information about the currency,
57
+ A <tt>Money::Currency</tt> instance holds all the information about the currency,
58
58
  including the currency symbol, name and much more.
59
59
 
60
60
  currency = Money.new(1000, "USD")
@@ -63,8 +63,8 @@ including the currency symbol, name and much more.
63
63
  currency.name
64
64
  # => "United States Dollar"
65
65
 
66
- To define a new Money::Currency simply add a new item to the Money::Currency::TABLE hash,
67
- where the key is the identifier for the Currency object and the value is a hash
66
+ To define a new <tt>Money::Currency</tt> simply add a new item to the <tt>Money::Currency::TABLE</tt> hash,
67
+ where the key is the identifier for the currency object and the value is a hash
68
68
  containing all the currency attributes.
69
69
 
70
70
  Money::Currency::TABLE[:usd] = {
@@ -85,13 +85,13 @@ The pre-defined set of attributes includes:
85
85
  * subunit: the name of the fractional monetary unit
86
86
  * subunit_to_unit: the proportion between the unit and the subunit
87
87
 
88
- All attributes are optional. Some attributes, such as :symbol, are used by the Money class
89
- to print out a representation of the object. Other attributes, such as :name or :priority,
88
+ All attributes are optional. Some attributes, such as <tt>:symbol</tt>, are used by the Money class
89
+ to print out a representation of the object. Other attributes, such as <tt>:name</tt> or <tt>:priority</tt>,
90
90
  exist to provide a basic API you can take advantage of to build your application.
91
91
 
92
92
  ==== priority
93
93
 
94
- The priority attribute is an arbitrary numerical value you can assign to the Currency
94
+ The priority attribute is an arbitrary numerical value you can assign to the <tt>Money::Currency</tt>
95
95
  and use in sorting/grouping operation.
96
96
 
97
97
  For instance, let's assume your Rails application needs to a currency selector
@@ -126,11 +126,11 @@ and all_currencies as follows:
126
126
 
127
127
  === Default Currency
128
128
 
129
- By default Money defaults to USD as its currency. This can be overwritten using
129
+ By default <tt>Money</tt> defaults to USD as its currency. This can be overwritten using
130
130
 
131
131
  Money.default_currency = Money::Currency.new("CAD")
132
132
 
133
- If you use Rails, then environment.rb is a very good place to put this.
133
+ If you use Rails, then <tt>environment.rb</tt> is a very good place to put this.
134
134
 
135
135
  === Currency Exchange
136
136
 
@@ -157,6 +157,13 @@ www.xe.com for the current rates or just returns <tt>rand(2)</tt>:
157
157
 
158
158
  Money.default_bank = ExchangeBankWhichScrapesXeDotCom.new
159
159
 
160
+ === Currency Exchange Implementations
161
+
162
+ The following is a list of Money.gem compatible currency exchange rate
163
+ implementations.
164
+
165
+ * eu_central_bank.gem: http://github.com/liangzan/eu_central_bank
166
+
160
167
  === Ruby on Rails
161
168
 
162
169
  Use the +compose_of+ helper to let Active Record deal with embedding the money
@@ -165,15 +172,40 @@ field.
165
172
 
166
173
  class ProductUnit < ActiveRecord::Base
167
174
  belongs_to :product
168
- composed_of :price, :class_name => "Money", :mapping => [%w(cents cents), %w(currency currency)]
175
+ composed_of :price, :class_name => "Money", :mapping => [%w(cents cents), %w(currency currency_as_string)]
169
176
 
170
- private
177
+ private
171
178
  validate :cents_not_zero
172
-
179
+
173
180
  def cents_not_zero
174
181
  errors.add("cents", "cannot be zero or less") unless cents > 0
175
182
  end
176
183
 
177
184
  validates_presence_of :sku, :currency
178
- validates_uniqueness_of :sku
185
+ validates_uniqueness_of :sku
186
+ end
187
+
188
+ Also, because the <tt>currency</tt> attribute is not a simple <tt>String</tt>
189
+ but a <tt>Money::Currency</tt> object, you need a small tweak to make it work.
190
+
191
+ Extend/hack the <tt>Money</tt> class with two additional methods:
192
+
193
+ # You can put this file in the config/initializers/ folder
194
+ class Money
195
+ def currency_as_string
196
+ currency.to_s
197
+ end
198
+
199
+ def currency_as_string=(value)
200
+ # WARNING: this method might cause data inconsistency.
201
+ # See http://github.com/FooBarWidget/money/issues/4#issue/4/comment/224930
202
+ # currency = Currency.wrap(value)
203
+ end
179
204
  end
205
+
206
+ The hack is not required for Money 2.2.x and previous versions.
207
+ In this case, simply use the following <tt>composed_of</tt> definition:
208
+
209
+ composed_of :price, :class_name => "Money", :mapping => [%w(cents cents), %w(currency currency)]
210
+
211
+ For further details read the full discussion at http://github.com/FooBarWidget/money/issues/4#comment_224880
data/VERSION CHANGED
@@ -1 +1 @@
1
- 2.3.0
1
+ 3.0.0
@@ -34,20 +34,20 @@ class String
34
34
  end
35
35
 
36
36
  private
37
-
37
+
38
38
  def calculate_cents(number)
39
39
  # remove anything that's not a number, potential delimiter, or minus sign
40
40
  num = number.gsub(/[^\d|\.|,|\'|\s|\-]/, '').strip
41
-
41
+
42
42
  # set a boolean flag for if the number is negative or not
43
43
  negative = num.split(//).first == "-"
44
-
44
+
45
45
  # if negative, remove the minus sign from the number
46
46
  num = num.gsub(/^-/, '') if negative
47
-
47
+
48
48
  # gather all separators within the result number
49
49
  used_separators = num.scan /[^\d]/
50
-
50
+
51
51
  # determine the number of unique separators within the number
52
52
  #
53
53
  # e.g.
@@ -58,8 +58,8 @@ class String
58
58
  case used_separators.uniq.length
59
59
  # no separator or delimiter; major (dollars) is the number, and minor (cents) is 0
60
60
  when 0 then major, minor = num, 0
61
-
62
- # two separators, so we know the last item in this array is the
61
+
62
+ # two separators, so we know the last item in this array is the
63
63
  # major/minor delimiter and the rest are separators
64
64
  when 2
65
65
  separator, delimiter = used_separators.uniq
@@ -75,10 +75,10 @@ class String
75
75
  # 1,000,000 - comma is a separator
76
76
  # 10000,00 - comma is a delimiter
77
77
  # 1000,000 - comma is a delimiter
78
-
78
+
79
79
  # assign first separator for reusability
80
80
  separator = used_separators.first
81
-
81
+
82
82
  # separator is used as a separator when there are multiple instances, always
83
83
  if num.scan(separator).length > 1 # multiple matches; treat as separator
84
84
  major, minor = num.gsub(separator, ''), 0
@@ -88,7 +88,7 @@ class String
88
88
  possible_major, possible_minor = num.split(separator)
89
89
  possible_major ||= "0"
90
90
  possible_minor ||= "00"
91
-
91
+
92
92
  # if the minor (cents) length isn't 3, assign major/minor from the possibles
93
93
  # e.g.
94
94
  # 1,00 => 1.00
@@ -99,8 +99,8 @@ class String
99
99
  else
100
100
  # minor length is three
101
101
  # let's try to figure out intent of the delimiter
102
-
103
- # the major length is greater than three, which means
102
+
103
+ # the major length is greater than three, which means
104
104
  # the comma or period is used as a delimiter
105
105
  # e.g.
106
106
  # 1000,000
@@ -121,7 +121,7 @@ class String
121
121
  else
122
122
  raise ArgumentError, "Invalid currency amount"
123
123
  end
124
-
124
+
125
125
  # build the string based on major/minor since separator/delimiters have been removed
126
126
  # avoiding floating point arithmetic here to ensure accuracy
127
127
  cents = (major.to_i * 100)
@@ -136,9 +136,9 @@ class String
136
136
  if minor.size >= 3 && minor[2..2].to_i >= 5
137
137
  cents += 1
138
138
  end
139
-
139
+
140
140
  # if negative, multiply by -1; otherwise, return positive cents
141
141
  negative ? cents * -1 : cents
142
142
  end
143
-
143
+
144
144
  end
@@ -265,7 +265,7 @@ class Money
265
265
  end
266
266
 
267
267
  # Wraps the object in a Currency unless it's a Currency.
268
- #
268
+ #
269
269
  # Currency.wrap(nil)
270
270
  # # => nil
271
271
  # Currency.wrap(Currency.new(:usd))
data/lib/money/money.rb CHANGED
@@ -15,11 +15,11 @@ class Money
15
15
  #
16
16
  # bank1 = MyBank.new
17
17
  # bank2 = MyOtherBank.new
18
- #
18
+ #
19
19
  # Money.default_bank = bank1
20
20
  # money1 = Money.new(10)
21
21
  # money1.bank # => bank1
22
- #
22
+ #
23
23
  # Money.default_bank = bank2
24
24
  # money2 = Money.new(10)
25
25
  # money2.bank # => bank2
@@ -33,17 +33,17 @@ class Money
33
33
  # Money.us_dollar(100).exchange_to("CAD") # => Money.ca_dollar(124)
34
34
  # Money.ca_dollar(100).exchange_to("USD") # => Money.us_dollar(80)
35
35
  attr_accessor :default_bank
36
-
36
+
37
37
  # The default currency, which is used when <tt>Money.new</tt> is called
38
38
  # without an explicit currency argument. The default value is Currency.new("USD").
39
39
  # The value must be a valid <tt>Money::Currency</tt> instance.
40
40
  attr_accessor :default_currency
41
41
  end
42
-
42
+
43
43
  self.default_bank = VariableExchangeBank.instance
44
44
  self.default_currency = Currency.new("USD")
45
-
46
-
45
+
46
+
47
47
  # Create a new money object with value 0.
48
48
  def self.empty(currency = default_currency)
49
49
  Money.new(0, currency)
@@ -58,22 +58,22 @@ class Money
58
58
  def self.us_dollar(cents)
59
59
  Money.new(cents, "USD")
60
60
  end
61
-
61
+
62
62
  # Creates a new Money object of the given value, using the Euro currency.
63
63
  def self.euro(cents)
64
64
  Money.new(cents, "EUR")
65
65
  end
66
-
66
+
67
67
  def self.add_rate(from_currency, to_currency, rate)
68
68
  Money.default_bank.add_rate(from_currency, to_currency, rate)
69
69
  end
70
-
71
-
72
- # Creates a new money object.
73
- # Money.new(100)
74
- #
75
- # Alternativly you can use the convinience methods like
76
- # Money.ca_dollar and Money.us_dollar
70
+
71
+
72
+ # Creates a new money object.
73
+ # Money.new(100)
74
+ #
75
+ # Alternatively you can use the convinience methods like
76
+ # Money.ca_dollar and Money.us_dollar
77
77
  def initialize(cents, currency = Money.default_currency, bank = Money.default_bank)
78
78
  @cents = cents.round
79
79
  if currency.is_a?(Hash)
@@ -101,7 +101,7 @@ class Money
101
101
  false
102
102
  end
103
103
  end
104
-
104
+
105
105
  # Compares this money object against another object. +other_money+ must respond
106
106
  # to #to_money.
107
107
  #
@@ -161,12 +161,17 @@ class Money
161
161
  Money.new(cents / val, currency)
162
162
  end
163
163
  end
164
-
164
+
165
165
  # Test if the money amount is zero
166
166
  def zero?
167
167
  cents == 0
168
168
  end
169
169
 
170
+ # Test if the money amount is non-zero. Returns this money object if it is
171
+ # non-zero, or nil otherwise, like <tt>Numeric#nonzero?</tt>.
172
+ def nonzero?
173
+ cents != 0 ? self : nil
174
+ end
170
175
 
171
176
  # Attempts to pick a symbol that's suitable for the given currency
172
177
  # looking up the Currency::TABLE hashtable.
@@ -201,58 +206,58 @@ class Money
201
206
  # Whether a zero amount of money should be formatted of "free" or as the
202
207
  # supplied string.
203
208
  #
204
- # Money.us_dollar(0).format(:display_free => true) => "free"
205
- # Money.us_dollar(0).format(:display_free => "gratis") => "gratis"
206
- # Money.us_dollar(0).format => "$0.00"
209
+ # Money.us_dollar(0).format(:display_free => true) => "free"
210
+ # Money.us_dollar(0).format(:display_free => "gratis") => "gratis"
211
+ # Money.us_dollar(0).format => "$0.00"
207
212
  #
208
213
  # === +:with_currency+
209
214
  #
210
215
  # Whether the currency name should be appended to the result string.
211
216
  #
212
- # Money.ca_dollar(100).format => "$1.00"
213
- # Money.ca_dollar(100).format(:with_currency => true) => "$1.00 CAD"
214
- # Money.us_dollar(85).format(:with_currency => true) => "$0.85 USD"
217
+ # Money.ca_dollar(100).format => "$1.00"
218
+ # Money.ca_dollar(100).format(:with_currency => true) => "$1.00 CAD"
219
+ # Money.us_dollar(85).format(:with_currency => true) => "$0.85 USD"
215
220
  #
216
221
  # === +:no_cents+
217
222
  #
218
223
  # Whether cents should be omitted.
219
224
  #
220
- # Money.ca_dollar(100).format(:no_cents => true) => "$1"
221
- # Money.ca_dollar(599).format(:no_cents => true) => "$5"
222
- #
223
- # Money.ca_dollar(570).format(:no_cents => true, :with_currency => true) => "$5 CAD"
224
- # Money.ca_dollar(39000).format(:no_cents => true) => "$390"
225
+ # Money.ca_dollar(100).format(:no_cents => true) => "$1"
226
+ # Money.ca_dollar(599).format(:no_cents => true) => "$5"
227
+ #
228
+ # Money.ca_dollar(570).format(:no_cents => true, :with_currency => true) => "$5 CAD"
229
+ # Money.ca_dollar(39000).format(:no_cents => true) => "$390"
225
230
  #
226
231
  # === +:symbol+
227
232
  #
228
233
  # Whether a money symbol should be prepended to the result string. The default is true.
229
234
  # This method attempts to pick a symbol that's suitable for the given currency.
230
235
  #
231
- # Money.new(100, "USD") => "$1.00"
232
- # Money.new(100, "GBP") => "£1.00"
233
- # Money.new(100, "EUR") => "€1.00"
234
- #
235
- # # Same thing.
236
- # Money.new(100, "USD").format(:symbol => true) => "$1.00"
237
- # Money.new(100, "GBP").format(:symbol => true) => "£1.00"
238
- # Money.new(100, "EUR").format(:symbol => true) => "€1.00"
236
+ # Money.new(100, "USD") => "$1.00"
237
+ # Money.new(100, "GBP") => "£1.00"
238
+ # Money.new(100, "EUR") => "€1.00"
239
+ #
240
+ # # Same thing.
241
+ # Money.new(100, "USD").format(:symbol => true) => "$1.00"
242
+ # Money.new(100, "GBP").format(:symbol => true) => "£1.00"
243
+ # Money.new(100, "EUR").format(:symbol => true) => "€1.00"
239
244
  #
240
245
  # You can specify a false expression or an empty string to disable prepending
241
246
  # a money symbol:
242
247
  #
243
- # Money.new(100, "USD").format(:symbol => false) => "1.00"
244
- # Money.new(100, "GBP").format(:symbol => nil) => "1.00"
245
- # Money.new(100, "EUR").format(:symbol => "") => "1.00"
248
+ # Money.new(100, "USD").format(:symbol => false) => "1.00"
249
+ # Money.new(100, "GBP").format(:symbol => nil) => "1.00"
250
+ # Money.new(100, "EUR").format(:symbol => "") => "1.00"
251
+ #
246
252
  #
247
- #
248
253
  # If the symbol for the given currency isn't known, then it will default
249
254
  # to "$" as symbol:
250
255
  #
251
- # Money.new(100, "AWG").format(:symbol => true) => "$1.00"
256
+ # Money.new(100, "AWG").format(:symbol => true) => "$1.00"
252
257
  #
253
258
  # You can specify a string as value to enforce using a particular symbol:
254
259
  #
255
- # Money.new(100, "AWG").format(:symbol => "ƒ") => "ƒ1.00"
260
+ # Money.new(100, "AWG").format(:symbol => "ƒ") => "ƒ1.00"
256
261
  #
257
262
  # === +:separator+
258
263
  #
@@ -260,42 +265,42 @@ class Money
260
265
  #
261
266
  # If a string is specified, it's value is used:
262
267
  #
263
- # Money.new(100, "USD").format(:separator => ",") => "$1,00"
268
+ # Money.new(100, "USD").format(:separator => ",") => "$1,00"
264
269
  #
265
270
  # If the separator for a given currency isn't known, then it will default to
266
271
  # "." as separator:
267
272
  #
268
- # Money.new(100, "FOO").format => "$1.00"
273
+ # Money.new(100, "FOO").format => "$1.00"
269
274
  #
270
275
  # === +:delimiter+
271
276
  #
272
277
  # Whether the currency should be delimited by the specified character or ','
273
278
  #
274
279
  # If false is specified, no delimiter is used:
275
- #
276
- # Money.new(100000, "USD").format(:delimiter => false) => "1000.00"
277
- # Money.new(100000, "USD").format(:delimiter => nil) => "1000.00"
278
- # Money.new(100000, "USD").format(:delimiter => "") => "1000.00"
280
+ #
281
+ # Money.new(100000, "USD").format(:delimiter => false) => "1000.00"
282
+ # Money.new(100000, "USD").format(:delimiter => nil) => "1000.00"
283
+ # Money.new(100000, "USD").format(:delimiter => "") => "1000.00"
279
284
  #
280
285
  # If a string is specified, it's value is used:
281
286
  #
282
- # Money.new(100000, "USD").format(:delimiter => ".") => "$1.000.00"
287
+ # Money.new(100000, "USD").format(:delimiter => ".") => "$1.000.00"
283
288
  #
284
289
  # If the delimiter for a given currency isn't known, then it will default to
285
290
  # "," as delimiter:
286
291
  #
287
- # Money.new(100000, "FOO").format => "$1,000.00"
292
+ # Money.new(100000, "FOO").format => "$1,000.00"
288
293
  #
289
294
  # === +:html+
290
295
  #
291
296
  # Whether the currency should be HTML-formatted. Only useful in combination with +:with_currency+.
292
297
  #
293
- # Money.ca_dollar(570).format(:html => true, :with_currency => true)
294
- # => "$5.70 <span class=\"currency\">CAD</span>"
298
+ # Money.ca_dollar(570).format(:html => true, :with_currency => true)
299
+ # # => "$5.70 <span class=\"currency\">CAD</span>"
295
300
  def format(*rules)
296
301
  # support for old format parameters
297
302
  rules = normalize_formatting_rules(rules)
298
-
303
+
299
304
  if cents == 0
300
305
  if rules[:display_free].respond_to?(:to_str)
301
306
  return rules[:display_free]
@@ -352,10 +357,11 @@ class Money
352
357
  end
353
358
  formatted
354
359
  end
355
-
360
+
356
361
  # Returns the amount of money as a string.
357
362
  #
358
- # Money.ca_dollar(100).to_s => "1.00"
363
+ # Money.ca_dollar(100).to_s => "1.00"
364
+ #
359
365
  def to_s
360
366
  sprintf("%.2f", cents / 100.00)
361
367
  end
@@ -365,12 +371,13 @@ class Money
365
371
  # need to represent currency or working with another system that requires
366
372
  # decimals.
367
373
  #
368
- # Money.us_dollar(100).to_f => 1.0
374
+ # Money.us_dollar(100).to_f => 1.0
375
+ #
369
376
  def to_f
370
377
  cents / 100.0
371
378
  end
372
379
 
373
- # Recieve the amount of this money object in another Currency.
380
+ # Receive the amount of this money object in another Currency.
374
381
  # <tt>other_currency</tt> can be either a <tt>String</tt>
375
382
  # or a <tt>Currency</tt> instance.
376
383
  #
@@ -382,31 +389,31 @@ class Money
382
389
  Money.new(@bank.exchange(self.cents, currency, other_currency), other_currency)
383
390
  end
384
391
 
385
- # Recieve a money object with the same amount as the current Money object
386
- # in american dollar
392
+ # Receive a money object with the same amount as the current Money object
393
+ # in american dollar
387
394
  def as_us_dollar
388
395
  exchange_to("USD")
389
396
  end
390
-
391
- # Recieve a money object with the same amount as the current Money object
392
- # in canadian dollar
397
+
398
+ # Receive a money object with the same amount as the current Money object
399
+ # in canadian dollar
393
400
  def as_ca_dollar
394
401
  exchange_to("CAD")
395
402
  end
396
-
397
- # Recieve a money object with the same amount as the current Money object
403
+
404
+ # Receive a money object with the same amount as the current Money object
398
405
  # in euro
399
406
  def as_euro
400
407
  exchange_to("EUR")
401
408
  end
402
-
409
+
403
410
  # Conversation to self
404
411
  def to_money
405
412
  self
406
413
  end
407
-
414
+
408
415
  private
409
-
416
+
410
417
  def normalize_formatting_rules(rules)
411
418
  if rules.size == 1
412
419
  rules = rules.pop
@@ -9,14 +9,15 @@ require 'money/errors'
9
9
  # One must manually specify them with +add_rate+, after which one can perform
10
10
  # exchanges with +exchange+. For example:
11
11
  #
12
- # bank = Money::VariableExchangeBank.new
13
- # bank.add_rate("USD", "CAD", 1.24515)
14
- # bank.add_rate("CAD", "USD", 0.803115)
15
- #
16
- # # Exchange 100 CAD to USD:
17
- # bank.exchange(100_00, "CAD", "USD") # => 124
18
- # # Exchange 100 USD to CAD:
19
- # bank.exchange(100_00, "USD", "CAD") # => 80
12
+ # bank = Money::VariableExchangeBank.new
13
+ # bank.add_rate("USD", "CAD", 1.24515)
14
+ # bank.add_rate("CAD", "USD", 0.803115)
15
+ #
16
+ # # Exchange 100 CAD to USD:
17
+ # bank.exchange(100_00, "CAD", "USD") # => 124
18
+ # # Exchange 100 USD to CAD:
19
+ # bank.exchange(100_00, "USD", "CAD") # => 80
20
+ #
20
21
  class Money
21
22
  class VariableExchangeBank
22
23
  # Returns the singleton instance of VariableExchangeBank.
@@ -25,27 +26,27 @@ class Money
25
26
  def self.instance
26
27
  @@singleton
27
28
  end
28
-
29
+
29
30
  def initialize
30
31
  @rates = {}
31
32
  @mutex = Mutex.new
32
33
  end
33
-
34
+
34
35
  # Registers a conversion rate. +from+ and +to+ are both currency names.
35
36
  def add_rate(from, to, rate)
36
37
  @mutex.synchronize do
37
38
  @rates["#{from}_TO_#{to}".upcase] = rate
38
39
  end
39
40
  end
40
-
41
+
41
42
  # Gets the rate for exchanging the currency named +from+ to the currency
42
43
  # named +to+. Returns nil if the rate is unknown.
43
44
  def get_rate(from, to)
44
45
  @mutex.synchronize do
45
- @rates["#{from}_TO_#{to}".upcase]
46
+ @rates["#{from}_TO_#{to}".upcase]
46
47
  end
47
48
  end
48
-
49
+
49
50
  # Given two currency names, checks whether they're both the same currency.
50
51
  #
51
52
  # bank = VariableExchangeBank.new
@@ -54,7 +55,7 @@ class Money
54
55
  def same_currency?(currency1, currency2)
55
56
  Currency.wrap(currency1) == Currency.wrap(currency2)
56
57
  end
57
-
58
+
58
59
  # Exchange the given amount of cents in +from_currency+ to +to_currency+.
59
60
  # Returns the amount of cents in +to_currency+ as an integer, rounded down.
60
61
  #
@@ -66,7 +67,7 @@ class Money
66
67
  end
67
68
  (cents * rate).floor
68
69
  end
69
-
70
+
70
71
  @@singleton = VariableExchangeBank.new
71
72
  end
72
73
  end
data/money.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{money}
8
- s.version = "2.3.0"
8
+ s.version = "3.0.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Tobias Luetke", "Hongli Lai", "Jeremy McNevin", "Shane Emmons"]
12
- s.date = %q{2010-04-16}
12
+ s.date = %q{2010-05-07}
13
13
  s.description = %q{Money and currency exchange support library.}
14
14
  s.email = %q{hongli@phusion.nl}
15
15
  s.extra_rdoc_files = [
@@ -55,7 +55,7 @@ describe Money::Currency do
55
55
  with_custom_definitions do
56
56
  Money::Currency::TABLE[:usd] = { :priority => 1, :iso_code => "USD", :name => "United States Dollar", :symbol => "$", :subunit => "Cent", :subunit_to_unit => "100" }
57
57
  Money::Currency::TABLE[:eur] = { :priority => 2, :iso_code => "EUR", :name => "Euro", :symbol => "€", :subunit => "Cent", :subunit_to_unit => "100" }
58
-
58
+
59
59
  expected = Money::Currency.new(:eur)
60
60
  Money::Currency.find(:eur).should == expected
61
61
  Money::Currency.find(:EUR).should == expected
@@ -63,12 +63,12 @@ describe Money::Currency do
63
63
  Money::Currency.find("EUR").should == expected
64
64
  end
65
65
  end
66
-
66
+
67
67
  specify "#self.find should return nil unless currency matching given id" do
68
68
  with_custom_definitions do
69
69
  Money::Currency::TABLE[:usd] = { :position => 1, :iso_code => "USD", :name => "United States Dollar", :symbol => "$", :subunit => "Cent", :subunit_to_unit => "100" }
70
70
  Money::Currency::TABLE[:eur] = { :position => 2, :iso_code => "EUR", :name => "Euro", :symbol => "€", :subunit => "Cent", :subunit_to_unit => "100" }
71
-
71
+
72
72
  expected = Money::Currency.new(:eur)
73
73
  Money::Currency.find(:eur).should == expected
74
74
  Money::Currency.find(:EUR).should == expected
@@ -5,14 +5,14 @@ describe Money::VariableExchangeBank do
5
5
  before :each do
6
6
  @bank = Money::VariableExchangeBank.new
7
7
  end
8
-
8
+
9
9
  it "returns the previously specified conversion rate" do
10
10
  @bank.add_rate("USD", "EUR", 0.788332676)
11
11
  @bank.add_rate("EUR", "YEN", 122.631477)
12
12
  @bank.get_rate("USD", "EUR").should == 0.788332676
13
13
  @bank.get_rate("EUR", "YEN").should == 122.631477
14
14
  end
15
-
15
+
16
16
  it "treats currency names case-insensitively" do
17
17
  @bank.add_rate("usd", "eur", 1)
18
18
  @bank.get_rate("USD", "EUR").should == 1
@@ -23,21 +23,21 @@ describe Money::VariableExchangeBank do
23
23
  it "returns nil if the conversion rate is unknown" do
24
24
  @bank.get_rate("American Pesos", "EUR").should be_nil
25
25
  end
26
-
26
+
27
27
  it "exchanges money from one currency to another according to the specified conversion rates" do
28
28
  @bank.add_rate("USD", "EUR", 0.5)
29
29
  @bank.add_rate("EUR", "YEN", 10)
30
30
  @bank.exchange(10_00, "USD", "EUR").should == 5_00
31
31
  @bank.exchange(500_00, "EUR", "YEN").should == 5000_00
32
32
  end
33
-
33
+
34
34
  it "rounds the exchanged result down" do
35
35
  @bank.add_rate("USD", "EUR", 0.788332676)
36
36
  @bank.add_rate("EUR", "YEN", 122.631477)
37
37
  @bank.exchange(10_00, "USD", "EUR").should == 788
38
38
  @bank.exchange(500_00, "EUR", "YEN").should == 6131573
39
39
  end
40
-
40
+
41
41
  it "raises Money::UnknownRate upon conversion if the conversion rate is unknown" do
42
42
  block = lambda { @bank.exchange(10, "USD", "EUR") }
43
43
  block.should raise_error(Money::UnknownRate)
data/test/money_spec.rb CHANGED
@@ -7,11 +7,11 @@ describe Money do
7
7
  it "is associated to the singleton instance of VariableExchangeBank by default" do
8
8
  Money.new(0).bank.object_id.should == Money::VariableExchangeBank.instance.object_id
9
9
  end
10
-
10
+
11
11
  specify "#cents returns the amount of cents passed to the constructor" do
12
12
  Money.new(200_00, "USD").cents.should == 200_00
13
13
  end
14
-
14
+
15
15
  it "rounds the given cents to an integer" do
16
16
  Money.new(1.00, "USD").cents.should == 1
17
17
  Money.new(1.01, "USD").cents.should == 1
@@ -21,7 +21,7 @@ describe Money do
21
21
  specify "#currency returns the currency passed to the constructor" do
22
22
  Money.new(200_00, "USD").currency.should == Money::Currency.new("USD")
23
23
  end
24
-
24
+
25
25
  specify "#zero? returns whether the amount is 0" do
26
26
  Money.new(0, "USD").should be_zero
27
27
  Money.new(0, "EUR").should be_zero
@@ -29,56 +29,71 @@ describe Money do
29
29
  Money.new(10, "YEN").should_not be_zero
30
30
  Money.new(-1, "EUR").should_not be_zero
31
31
  end
32
-
32
+
33
+ specify "#nonzero? returns whether the amount is not 0" do
34
+ Money.new(0, "USD").should_not be_nonzero
35
+ Money.new(0, "EUR").should_not be_nonzero
36
+ Money.new(1, "USD").should be_nonzero
37
+ Money.new(10, "YEN").should be_nonzero
38
+ Money.new(-1, "EUR").should be_nonzero
39
+ end
40
+
41
+ specify "#nonzero? has the same return-value semantics as Numeric#nonzero?" do
42
+ Money.new(0, "USD").nonzero?.should be_nil
43
+
44
+ money = Money.new(1, "USD")
45
+ money.nonzero?.should be_equal(money)
46
+ end
47
+
33
48
  specify "#exchange_to exchanges the amount via its exchange bank" do
34
49
  money = Money.new(100_00, "USD")
35
50
  money.bank.should_receive(:exchange).with(100_00, Money::Currency.new("USD"), Money::Currency.new("EUR")).and_return(200_00)
36
51
  money.exchange_to("EUR")
37
52
  end
38
-
53
+
39
54
  specify "#exchange_to exchanges the amount properly" do
40
55
  money = Money.new(100_00, "USD")
41
56
  money.bank.should_receive(:exchange).with(100_00, Money::Currency.new("USD"), Money::Currency.new("EUR")).and_return(200_00)
42
57
  money.exchange_to("EUR").should == Money.new(200_00, "EUR")
43
58
  end
44
-
59
+
45
60
  specify "#== returns true if and only if their amount and currency are equal" do
46
61
  Money.new(1_00, "USD").should == Money.new(1_00, "USD")
47
62
  Money.new(1_00, "USD").should_not == Money.new(1_00, "EUR")
48
63
  Money.new(1_00, "USD").should_not == Money.new(2_00, "USD")
49
64
  Money.new(1_00, "USD").should_not == Money.new(99_00, "EUR")
50
65
  end
51
-
66
+
52
67
  specify "#== can be used to compare with a String money value" do
53
68
  Money.new(1_00, "USD").should == "1.00"
54
69
  Money.new(1_00, "USD").should_not == "2.00"
55
70
  Money.new(1_00, "GBP").should_not == "1.00"
56
71
  end
57
-
72
+
58
73
  specify "#== can be used to compare with a Numeric money value" do
59
74
  Money.new(1_00, "USD").should == 1
60
75
  Money.new(1_57, "USD").should == 1.57
61
76
  Money.new(1_00, "USD").should_not == 2
62
77
  Money.new(1_00, "GBP").should_not == 1
63
78
  end
64
-
79
+
65
80
  specify "#== can be used to compare with an object that responds to #to_money" do
66
81
  klass = Class.new do
67
82
  def initialize(money)
68
83
  @money = money
69
84
  end
70
-
85
+
71
86
  def to_money
72
87
  @money
73
88
  end
74
89
  end
75
-
90
+
76
91
  Money.new(1_00, "USD").should == klass.new(Money.new(1_00, "USD"))
77
92
  Money.new(2_50, "USD").should == klass.new(Money.new(2_50, "USD"))
78
93
  Money.new(2_50, "USD").should_not == klass.new(Money.new(3_00, "USD"))
79
94
  Money.new(1_00, "GBP").should_not == klass.new(Money.new(1_00, "USD"))
80
95
  end
81
-
96
+
82
97
  specify "#== returns false if used to compare with an object that doesn't respond to #to_money" do
83
98
  Money.new(1_00, "USD").should_not == Object.new
84
99
  Money.new(1_00, "USD").should_not == Class
@@ -86,35 +101,35 @@ describe Money do
86
101
  Money.new(1_00, "USD").should_not == /foo/
87
102
  Money.new(1_00, "USD").should_not == nil
88
103
  end
89
-
104
+
90
105
  specify "#<=> can be used to compare with a String money value" do
91
106
  (Money.new(1_00) <=> "1.00").should == 0
92
107
  (Money.new(1_00) <=> ".99").should > 0
93
108
  (Money.new(1_00) <=> "2.00").should < 0
94
109
  end
95
-
110
+
96
111
  specify "#<=> can be used to compare with a Numeric money value" do
97
112
  (Money.new(1_00) <=> 1).should == 0
98
113
  (Money.new(1_00) <=> 0.99).should > 0
99
114
  (Money.new(1_00) <=> 2.00).should < 0
100
115
  end
101
-
116
+
102
117
  specify "#<=> can be used to compare with an object that responds to #to_money" do
103
118
  klass = Class.new do
104
119
  def initialize(money)
105
120
  @money = money
106
121
  end
107
-
122
+
108
123
  def to_money
109
124
  @money
110
125
  end
111
126
  end
112
-
127
+
113
128
  (Money.new(1_00) <=> klass.new(Money.new(1_00))).should == 0
114
129
  (Money.new(1_00) <=> klass.new(Money.new(99))).should > 0
115
130
  (Money.new(1_00) <=> klass.new(Money.new(2_00))).should < 0
116
131
  end
117
-
132
+
118
133
  specify "#<=> raises ArgumentError when used to compare with an object that doesn't respond to #to_money" do
119
134
  expected_message = /comparison .+ failed/
120
135
  lambda{ Money.new(1_00) <=> Object.new }.should raise_error(ArgumentError, expected_message)
@@ -122,39 +137,39 @@ describe Money do
122
137
  lambda{ Money.new(1_00) <=> Kernel }.should raise_error(ArgumentError, expected_message)
123
138
  lambda{ Money.new(1_00) <=> /foo/ }.should raise_error(ArgumentError, expected_message)
124
139
  end
125
-
140
+
126
141
  specify "#* multiplies the money's amount by the multiplier while retaining the currency" do
127
142
  (Money.new(1_00, "USD") * 10).should == Money.new(10_00, "USD")
128
143
  end
129
-
144
+
130
145
  specify "#/ divides the money's amount by the divisor while retaining the currency" do
131
146
  (Money.new(10_00, "USD") / 10).should == Money.new(1_00, "USD")
132
147
  end
133
-
148
+
134
149
  specify "Money.empty creates a new Money object of 0 cents" do
135
150
  Money.empty.should == Money.new(0)
136
151
  end
137
-
152
+
138
153
  specify "Money.ca_dollar creates a new Money object of the given value in CAD" do
139
154
  Money.ca_dollar(50).should == Money.new(50, "CAD")
140
155
  end
141
-
156
+
142
157
  specify "Money.ca_dollar creates a new Money object of the given value in USD" do
143
158
  Money.us_dollar(50).should == Money.new(50, "USD")
144
159
  end
145
-
160
+
146
161
  specify "Money.ca_dollar creates a new Money object of the given value in EUR" do
147
162
  Money.euro(50).should == Money.new(50, "EUR")
148
163
  end
149
-
164
+
150
165
  specify "Money.new accepts { :currency => 'foo' } as the value for the 'currency' argument" do
151
166
  money = Money.new(20, :currency => "EUR")
152
167
  money.currency.should == Money::Currency.new("EUR")
153
-
168
+
154
169
  money = Money.new(20, :currency => nil)
155
170
  money.currency.should == Money.default_currency
156
171
  end
157
-
172
+
158
173
  specify "Money.add_rate works" do
159
174
  Money.add_rate("EUR", "USD", 10)
160
175
  Money.new(10_00, "EUR").exchange_to("USD").should == Money.new(100_00, "USD")
@@ -167,7 +182,7 @@ describe Money do
167
182
  specify "Money.to_f works" do
168
183
  Money.new(10_00).to_f.should == 10.0
169
184
  end
170
-
185
+
171
186
  describe "#format" do
172
187
  it "returns the monetary value as a string" do
173
188
  Money.ca_dollar(100).format.should == "$1.00"
@@ -180,50 +195,50 @@ describe Money do
180
195
 
181
196
  # Pounds
182
197
  one_thousand["GBP"].should == "£1,000.00"
183
-
198
+
184
199
  # Dollars
185
200
  one_thousand["USD"].should == "$1,000.00"
186
201
  one_thousand["CAD"].should == "$1,000.00"
187
202
  one_thousand["AUD"].should == "$1,000.00"
188
203
  one_thousand["NZD"].should == "$1,000.00"
189
204
  one_thousand["ZWD"].should == "$1,000.00"
190
-
205
+
191
206
  # Yen
192
- one_thousand["JPY"].should == "¥1,000.00"
193
- one_thousand["CNY"].should == "¥1,000.00"
194
-
207
+ one_thousand["JPY"].should == "¥1,000.00"
208
+ one_thousand["CNY"].should == "¥1,000.00"
209
+
195
210
  # Euro
196
211
  one_thousand["EUR"].should == "€1,000.00"
197
-
212
+
198
213
  # Rupees
199
214
  one_thousand["INR"].should == "₨1,000.00"
200
215
  one_thousand["NPR"].should == "₨1,000.00"
201
216
  one_thousand["SCR"].should == "₨1,000.00"
202
217
  one_thousand["LKR"].should == "₨1,000.00"
203
-
218
+
204
219
  # Brazilian Real
205
220
  one_thousand["BRL"].should == "R$ 1.000,00"
206
-
221
+
207
222
  # Other
208
223
  one_thousand["SEK"].should == "kr1,000.00"
209
224
  one_thousand["GHC"].should == "₵1,000.00"
210
225
  end
211
-
226
+
212
227
  describe "if the monetary value is 0" do
213
228
  before :each do
214
229
  @money = Money.us_dollar(0)
215
230
  end
216
-
231
+
217
232
  it "returns 'free' when :display_free is true" do
218
233
  @money.format(:display_free => true).should == 'free'
219
234
  end
220
-
235
+
221
236
  it "returns '$0.00' when :display_free is false or not given" do
222
237
  @money.format.should == '$0.00'
223
238
  @money.format(:display_free => false).should == '$0.00'
224
239
  @money.format(:display_free => nil).should == '$0.00'
225
240
  end
226
-
241
+
227
242
  it "returns the value specified by :display_free if it's a string-like object" do
228
243
  @money.format(:display_free => 'gratis').should == 'gratis'
229
244
  end
@@ -255,7 +270,7 @@ describe Money do
255
270
  end
256
271
  end
257
272
  end
258
-
273
+
259
274
  specify "#separator works as documented" do
260
275
  begin
261
276
  old = Money::SEPARATORS.dup
@@ -277,12 +292,12 @@ describe Money do
277
292
  Money.us_dollar(85).format(:with_currency => true).should == "$0.85 USD"
278
293
  Money.us_dollar(85).format(:with_currency).should == "$0.85 USD"
279
294
  end
280
-
295
+
281
296
  specify "#format(:with_currency) works as documented" do
282
297
  Money.ca_dollar(100).format(:with_currency).should == "$1.00 CAD"
283
298
  Money.us_dollar(85).format(:with_currency).should == "$0.85 USD"
284
299
  end
285
-
300
+
286
301
  specify "#format(:no_cents => true) works as documented" do
287
302
  Money.ca_dollar(100).format(:no_cents => true).should == "$1"
288
303
  Money.ca_dollar(599).format(:no_cents => true).should == "$5"
@@ -296,11 +311,11 @@ describe Money do
296
311
  Money.ca_dollar(570).format(:no_cents, :with_currency).should == "$5 CAD"
297
312
  Money.ca_dollar(39000).format(:no_cents).should == "$390"
298
313
  end
299
-
314
+
300
315
  specify "#format(:symbol => a symbol string) uses the given value as the money symbol" do
301
316
  Money.new(100, "GBP").format(:symbol => "£").should == "£1.00"
302
317
  end
303
-
318
+
304
319
  specify "#format(:symbol => true) returns symbol based on the given currency code" do
305
320
  one = Proc.new do |currency|
306
321
  Money.new(100, currency).format(:symbol => true)
@@ -308,61 +323,61 @@ describe Money do
308
323
 
309
324
  # Pounds
310
325
  one["GBP"].should == "£1.00"
311
-
326
+
312
327
  # Dollars
313
328
  one["USD"].should == "$1.00"
314
329
  one["CAD"].should == "$1.00"
315
330
  one["AUD"].should == "$1.00"
316
331
  one["NZD"].should == "$1.00"
317
332
  one["ZWD"].should == "$1.00"
318
-
333
+
319
334
  # Yen
320
- one["JPY"].should == "¥1.00"
321
- one["CNY"].should == "¥1.00"
322
-
335
+ one["JPY"].should == "¥1.00"
336
+ one["CNY"].should == "¥1.00"
337
+
323
338
  # Euro
324
339
  one["EUR"].should == "€1.00"
325
-
340
+
326
341
  # Rupees
327
342
  one["INR"].should == "₨1.00"
328
343
  one["NPR"].should == "₨1.00"
329
344
  one["SCR"].should == "₨1.00"
330
345
  one["LKR"].should == "₨1.00"
331
-
346
+
332
347
  # Brazilian Real
333
348
  one["BRL"].should == "R$ 1,00"
334
-
349
+
335
350
  # Other
336
351
  one["SEK"].should == "kr1.00"
337
352
  one["GHC"].should == "₵1.00"
338
353
  end
339
-
354
+
340
355
  specify "#format(:symbol => true) returns $ when currency code is not recognized" do
341
356
  currency = Money::Currency.new("EUR")
342
357
  currency.should_receive(:symbol).and_return(nil)
343
358
  Money.new(100, currency).format(:symbol => true).should == "$1.00"
344
359
  end
345
-
360
+
346
361
  specify "#format(:symbol => some non-Boolean value that evaluates to true) returs symbol based on the given currency code" do
347
362
  Money.new(100, "GBP").format(:symbol => true).should == "£1.00"
348
363
  Money.new(100, "EUR").format(:symbol => true).should == "€1.00"
349
364
  Money.new(100, "SEK").format(:symbol => true).should == "kr1.00"
350
365
  end
351
-
366
+
352
367
  specify "#format with :symbol == "", nil or false returns the amount without a symbol" do
353
368
  money = Money.new(100, "GBP")
354
369
  money.format(:symbol => "").should == "1.00"
355
370
  money.format(:symbol => nil).should == "1.00"
356
371
  money.format(:symbol => false).should == "1.00"
357
372
  end
358
-
373
+
359
374
  specify "#format without :symbol assumes that :symbol is set to true" do
360
375
  money = Money.new(100)
361
376
  money.format.should == "$1.00"
362
-
377
+
363
378
  money = Money.new(100, "GBP")
364
379
  money.format.should == "£1.00"
365
-
380
+
366
381
  money = Money.new(100, "EUR")
367
382
  money.format.should == "€1.00"
368
383
  end
@@ -388,12 +403,12 @@ describe Money do
388
403
  specify "#format will default delimiter to ',' if currency isn't recognized" do
389
404
  Money.new(100000, "ZWD").format.should == "$1,000.00"
390
405
  end
391
-
406
+
392
407
  specify "#format(:html => true) works as documented" do
393
408
  string = Money.ca_dollar(570).format(:html => true, :with_currency => true)
394
409
  string.should == "$5.70 <span class=\"currency\">CAD</span>"
395
410
  end
396
-
411
+
397
412
  it "should insert commas into the result if the amount is sufficiently large" do
398
413
  Money.us_dollar(1_000_000_000_12).format.should == "$1,000,000,000.12"
399
414
  Money.us_dollar(1_000_000_000_12).format(:no_cents => true).should == "$1,000,000,000"
@@ -424,11 +439,11 @@ describe "Actions involving two Money objects" do
424
439
  (Money.new(1_00, "USD") <=> Money.new(99, "USD")).should > 0
425
440
  (Money.new(1_00, "USD") <=> Money.new(2_00, "USD")).should < 0
426
441
  end
427
-
442
+
428
443
  specify "#+ adds the other object's amount to the current object's amount while retaining the currency" do
429
444
  (Money.new(10_00, "USD") + Money.new(90, "USD")).should == Money.new(10_90, "USD")
430
445
  end
431
-
446
+
432
447
  specify "#- substracts the other object's amount from the current object's amount while retaining the currency" do
433
448
  (Money.new(10_00, "USD") - Money.new(90, "USD")).should == Money.new(9_10, "USD")
434
449
  end
@@ -437,28 +452,28 @@ describe "Actions involving two Money objects" do
437
452
  (Money.new(10_00, "USD") / Money.new(100_00, "USD")).should == 0.1
438
453
  end
439
454
  end
440
-
455
+
441
456
  describe "if the other Money object has a different currency" do
442
457
  specify "#<=> compares the two objects' amount after converting the other object's amount to its own currency" do
443
458
  target = Money.new(200_00, "EUR")
444
459
  target.should_receive(:exchange_to).with(Money::Currency.new("USD")).and_return(Money.new(300_00, "USD"))
445
460
  (Money.new(100_00, "USD") <=> target).should < 0
446
-
461
+
447
462
  target = Money.new(200_00, "EUR")
448
463
  target.should_receive(:exchange_to).with(Money::Currency.new("USD")).and_return(Money.new(100_00, "USD"))
449
464
  (Money.new(100_00, "USD") <=> target).should == 0
450
-
465
+
451
466
  target = Money.new(200_00, "EUR")
452
467
  target.should_receive(:exchange_to).with(Money::Currency.new("USD")).and_return(Money.new(99_00, "USD"))
453
468
  (Money.new(100_00, "USD") <=> target).should > 0
454
469
  end
455
-
470
+
456
471
  specify "#+ adds the other object's amount, converted to this object's currency, to this object's amount while retaining its currency" do
457
472
  other = Money.new(90, "EUR")
458
473
  other.should_receive(:exchange_to).with(Money::Currency.new("USD")).and_return(Money.new(9_00, "USD"))
459
474
  (Money.new(10_00, "USD") + other).should == Money.new(19_00, "USD")
460
475
  end
461
-
476
+
462
477
  specify "#- substracts the other object's amount, converted to this object's currency, from this object's amount while retaining its currency" do
463
478
  other = Money.new(90, "EUR")
464
479
  other.should_receive(:exchange_to).with(Money::Currency.new("USD")).and_return(Money.new(9_00, "USD"))
metadata CHANGED
@@ -3,10 +3,10 @@ name: money
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease: false
5
5
  segments:
6
- - 2
7
6
  - 3
8
7
  - 0
9
- version: 2.3.0
8
+ - 0
9
+ version: 3.0.0
10
10
  platform: ruby
11
11
  authors:
12
12
  - Tobias Luetke
@@ -17,7 +17,7 @@ autorequire:
17
17
  bindir: bin
18
18
  cert_chain: []
19
19
 
20
- date: 2010-04-16 00:00:00 -04:00
20
+ date: 2010-05-07 00:00:00 -04:00
21
21
  default_executable:
22
22
  dependencies:
23
23
  - !ruby/object:Gem::Dependency