money 4.0.2 → 5.0.0.rc1
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.md +18 -0
- data/README.md +23 -7
- data/config/currency.json +3 -3
- data/lib/money/bank/variable_exchange.rb +1 -1
- data/lib/money/currency.rb +105 -69
- data/lib/money/money.rb +9 -1
- data/lib/money/money/arithmetic.rb +26 -0
- data/lib/money/money/formatting.rb +9 -3
- data/lib/money/money/parsing.rb +54 -34
- data/money.gemspec +1 -1
- data/spec/bank/variable_exchange_spec.rb +1 -1
- data/spec/currency_spec.rb +16 -19
- data/spec/money/arithmetic_spec.rb +28 -0
- data/spec/money/formatting_spec.rb +51 -7
- data/spec/money/parsing_spec.rb +97 -0
- metadata +11 -11
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,23 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## 5.0.0
|
4
|
+
- Minor bugfix - incorrect use of character range resulted in
|
5
|
+
botched results for Money::Parsing#extract_cents (GH-162)
|
6
|
+
- Money::Currency::TABLE removed. Use Money::Currency.register to add
|
7
|
+
additional currencies (GH-143)
|
8
|
+
- Fix rounding error in Numeric.to_money (GH-145)
|
9
|
+
- Allow on-the-fly calculation of decimal places if not known already
|
10
|
+
(GH-146,GH-147,GH-148)
|
11
|
+
- Move Euro symbol ahead of amount (GH-151)
|
12
|
+
- Changed settings for Polish currency (GH-152)
|
13
|
+
- Fall back to symbol if there is no html_entity present (GH-153)
|
14
|
+
- Optionally Allow parsing of money values prefixed by symbols in key
|
15
|
+
currencies (GH-155)
|
16
|
+
- Fix bug where rates exported to a file from VariableExchange leave the File
|
17
|
+
object open (GH-154)
|
18
|
+
- Added Money#positive? and Money#negative? methods (GH-157)
|
19
|
+
- Fix format function output for custom currencies (GH-156)
|
20
|
+
- Fix parsing of strings with 3 decimal digits (GH-158)
|
3
21
|
|
4
22
|
## 4.0.2
|
5
23
|
|
data/README.md
CHANGED
@@ -2,6 +2,12 @@
|
|
2
2
|
|
3
3
|
[](http://travis-ci.org/RubyMoney/money)
|
4
4
|
|
5
|
+
## Contributing
|
6
|
+
|
7
|
+
When contributing, please make sure to update the CHANGELOG and AUTHORS files
|
8
|
+
when you submit your pull request. Upon merging of your first pull request,
|
9
|
+
you will be given commit access to the repository.
|
10
|
+
|
5
11
|
## Introduction
|
6
12
|
|
7
13
|
This library aids one in handling money and different currencies.
|
@@ -64,6 +70,12 @@ Money.new(1000, "USD") - Money.new(200, "USD") == Money.new(800, "USD")
|
|
64
70
|
Money.new(1000, "USD") / 5 == Money.new(200, "USD")
|
65
71
|
Money.new(1000, "USD") * 5 == Money.new(5000, "USD")
|
66
72
|
|
73
|
+
# Assumptive Currencies
|
74
|
+
Money.assume_from_symbol = true
|
75
|
+
Money.new("$100") == Money.new(10000, "USD")
|
76
|
+
Money.new("€100") == Money.new(10000, "EUR")
|
77
|
+
Money.new("£100") == Money.new(10000, "GBP")
|
78
|
+
|
67
79
|
# Currency conversions
|
68
80
|
some_code_to_setup_exchange_rates
|
69
81
|
Money.new(1000, "USD").exchange_to("EUR") == Money.new(some_value, "EUR")
|
@@ -89,12 +101,11 @@ currency.iso_code #=> "USD"
|
|
89
101
|
currency.name #=> "United States Dollar"
|
90
102
|
```
|
91
103
|
|
92
|
-
To define a new `Money::Currency`
|
93
|
-
|
94
|
-
object and the value is a hash containing all the currency attributes.
|
104
|
+
To define a new `Money::Currency` use `Money::Currency.register` as shown
|
105
|
+
below.
|
95
106
|
|
96
107
|
``` ruby
|
97
|
-
|
108
|
+
curr = {
|
98
109
|
:priority => 1,
|
99
110
|
:iso_code => "USD",
|
100
111
|
:iso_numeric => "840",
|
@@ -105,6 +116,8 @@ object and the value is a hash containing all the currency attributes.
|
|
105
116
|
:separator => ".",
|
106
117
|
:delimiter => ","
|
107
118
|
}
|
119
|
+
|
120
|
+
Money::Currency.register(curr)
|
108
121
|
```
|
109
122
|
|
110
123
|
The pre-defined set of attributes includes:
|
@@ -154,10 +167,10 @@ def all_currencies(hash)
|
|
154
167
|
hash.keys
|
155
168
|
end
|
156
169
|
|
157
|
-
major_currencies(Money::Currency
|
170
|
+
major_currencies(Money::Currency.table)
|
158
171
|
# => [ :usd, :eur, :bgp, :cad ]
|
159
172
|
|
160
|
-
all_currencies(Money::Currency
|
173
|
+
all_currencies(Money::Currency.table)
|
161
174
|
# => [ :aed, :afn, all, ... ]
|
162
175
|
```
|
163
176
|
|
@@ -217,6 +230,9 @@ implementations.
|
|
217
230
|
|
218
231
|
## Ruby on Rails
|
219
232
|
|
233
|
+
To integrate money in a rails application use [money-rails](http://github.com/RubyMoney/money-rails)
|
234
|
+
gem or follow the instructions below.
|
235
|
+
|
220
236
|
Use the `composed_of` helper to let Active Record deal with embedding the money
|
221
237
|
object in your models. The following example requires 2 columns:
|
222
238
|
|
@@ -241,7 +257,7 @@ definition:
|
|
241
257
|
``` ruby
|
242
258
|
composed_of :price,
|
243
259
|
:class_name => "Money",
|
244
|
-
:mapping => [%w(
|
260
|
+
:mapping => [%w(price_cents cents), %w(currency currency)],
|
245
261
|
:constructor => Proc.new { |cents, currency| Money.new(cents || 0, currency || Money.default_currency) }
|
246
262
|
```
|
247
263
|
|
data/config/currency.json
CHANGED
@@ -565,7 +565,7 @@
|
|
565
565
|
"symbol": "€",
|
566
566
|
"subunit": "Cent",
|
567
567
|
"subunit_to_unit": 100,
|
568
|
-
"symbol_first":
|
568
|
+
"symbol_first": true,
|
569
569
|
"html_entity": "€",
|
570
570
|
"decimal_mark": ",",
|
571
571
|
"thousands_separator": ".",
|
@@ -1451,8 +1451,8 @@
|
|
1451
1451
|
"subunit_to_unit": 100,
|
1452
1452
|
"symbol_first": false,
|
1453
1453
|
"html_entity": "",
|
1454
|
-
"decimal_mark": "
|
1455
|
-
"thousands_separator": "
|
1454
|
+
"decimal_mark": ",",
|
1455
|
+
"thousands_separator": " ",
|
1456
1456
|
"iso_numeric": "985"
|
1457
1457
|
},
|
1458
1458
|
"pyg": {
|
data/lib/money/currency.rb
CHANGED
@@ -12,24 +12,81 @@ class Money
|
|
12
12
|
# Thrown when an unknown currency is requested.
|
13
13
|
class UnknownCurrency < StandardError; end
|
14
14
|
|
15
|
-
|
16
|
-
#
|
17
|
-
# == monetary unit
|
18
|
-
# The standard unit of value of a currency, as the dollar in the United States or the peso in Mexico.
|
19
|
-
# http://www.answers.com/topic/monetary-unit
|
20
|
-
# == fractional monetary unit, subunit
|
21
|
-
# A monetary unit that is valued at a fraction (usually one hundredth) of the basic monetary unit
|
22
|
-
# http://www.answers.com/topic/fractional-monetary-unit-subunit
|
23
|
-
#
|
24
|
-
# See http://en.wikipedia.org/wiki/List_of_circulating_currencies and
|
25
|
-
# http://search.cpan.org/~tnguyen/Locale-Currency-Format-1.28/Format.pm
|
15
|
+
class << self
|
26
16
|
|
27
|
-
|
17
|
+
# Lookup a currency with given +id+ an returns a +Currency+ instance on
|
18
|
+
# success, +nil+ otherwise.
|
19
|
+
#
|
20
|
+
# @param [String, Symbol, #to_s] id Used to look into +table+ and
|
21
|
+
# retrieve the applicable attributes.
|
22
|
+
#
|
23
|
+
# @return [Money::Currency]
|
24
|
+
#
|
25
|
+
# @example
|
26
|
+
# Money::Currency.find(:eur) #=> #<Money::Currency id: eur ...>
|
27
|
+
# Money::Currency.find(:foo) #=> nil
|
28
|
+
def find(id)
|
29
|
+
id = id.to_s.downcase.to_sym
|
30
|
+
new(id) if self.table[id]
|
31
|
+
end
|
28
32
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
+
# Wraps the object in a +Currency+ unless it's already a +Currency+
|
34
|
+
# object.
|
35
|
+
#
|
36
|
+
# @param [Object] object The object to attempt and wrap as a +Currency+
|
37
|
+
# object.
|
38
|
+
#
|
39
|
+
# @return [Money::Currency]
|
40
|
+
#
|
41
|
+
# @example
|
42
|
+
# c1 = Money::Currency.new(:usd)
|
43
|
+
# Money::Currency.wrap(nil) #=> nil
|
44
|
+
# Money::Currency.wrap(c1) #=> #<Money::Currency id: usd ...>
|
45
|
+
# Money::Currency.wrap("usd") #=> #<Money::Currency id: usd ...>
|
46
|
+
def wrap(object)
|
47
|
+
if object.nil?
|
48
|
+
nil
|
49
|
+
elsif object.is_a?(Currency)
|
50
|
+
object
|
51
|
+
else
|
52
|
+
Currency.new(object)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
# List of known currencies.
|
57
|
+
#
|
58
|
+
# == monetary unit
|
59
|
+
# The standard unit of value of a currency, as the dollar in the United States or the peso in Mexico.
|
60
|
+
# http://www.answers.com/topic/monetary-unit
|
61
|
+
# == fractional monetary unit, subunit
|
62
|
+
# A monetary unit that is valued at a fraction (usually one hundredth) of the basic monetary unit
|
63
|
+
# http://www.answers.com/topic/fractional-monetary-unit-subunit
|
64
|
+
#
|
65
|
+
# See http://en.wikipedia.org/wiki/List_of_circulating_currencies and
|
66
|
+
# http://search.cpan.org/~tnguyen/Locale-Currency-Format-1.28/Format.pm
|
67
|
+
def table
|
68
|
+
@table ||= load_currencies
|
69
|
+
end
|
70
|
+
|
71
|
+
# We need a string-based validator before creating an unbounded number of symbols.
|
72
|
+
# http://www.randomhacks.net/articles/2007/01/20/13-ways-of-looking-at-a-ruby-symbol#11
|
73
|
+
# https://github.com/RubyMoney/money/issues/132
|
74
|
+
def stringified_keys
|
75
|
+
@stringified_keys ||= stringify_keys
|
76
|
+
end
|
77
|
+
|
78
|
+
def register(curr)
|
79
|
+
key = curr[:iso_code].downcase.to_sym
|
80
|
+
@table[key] = curr
|
81
|
+
@stringified_keys = stringify_keys
|
82
|
+
end
|
83
|
+
|
84
|
+
private
|
85
|
+
|
86
|
+
def stringify_keys
|
87
|
+
table.keys.map{|k| k.to_s.downcase}
|
88
|
+
end
|
89
|
+
end
|
33
90
|
|
34
91
|
# The symbol used to identify the currency, usually the lowercase
|
35
92
|
# +iso_code+ attribute.
|
@@ -94,53 +151,9 @@ class Money
|
|
94
151
|
# @return [boolean]
|
95
152
|
attr_reader :symbol_first
|
96
153
|
|
97
|
-
|
98
|
-
class << self
|
99
|
-
|
100
|
-
# Lookup a currency with given +id+ an returns a +Currency+ instance on
|
101
|
-
# success, +nil+ otherwise.
|
102
|
-
#
|
103
|
-
# @param [String, Symbol, #to_s] id Used to look into +TABLE+ and
|
104
|
-
# retrieve the applicable attributes.
|
105
|
-
#
|
106
|
-
# @return [Money::Currency]
|
107
|
-
#
|
108
|
-
# @example
|
109
|
-
# Money::Currency.find(:eur) #=> #<Money::Currency id: eur ...>
|
110
|
-
# Money::Currency.find(:foo) #=> nil
|
111
|
-
def find(id)
|
112
|
-
id = id.to_s.downcase.to_sym
|
113
|
-
new(id) if self::TABLE[id]
|
114
|
-
end
|
115
|
-
|
116
|
-
# Wraps the object in a +Currency+ unless it's already a +Currency+
|
117
|
-
# object.
|
118
|
-
#
|
119
|
-
# @param [Object] object The object to attempt and wrap as a +Currency+
|
120
|
-
# object.
|
121
|
-
#
|
122
|
-
# @return [Money::Currency]
|
123
|
-
#
|
124
|
-
# @example
|
125
|
-
# c1 = Money::Currency.new(:usd)
|
126
|
-
# Money::Currency.wrap(nil) #=> nil
|
127
|
-
# Money::Currency.wrap(c1) #=> #<Money::Currency id: usd ...>
|
128
|
-
# Money::Currency.wrap("usd") #=> #<Money::Currency id: usd ...>
|
129
|
-
def wrap(object)
|
130
|
-
if object.nil?
|
131
|
-
nil
|
132
|
-
elsif object.is_a?(Currency)
|
133
|
-
object
|
134
|
-
else
|
135
|
-
Currency.new(object)
|
136
|
-
end
|
137
|
-
end
|
138
|
-
end
|
139
|
-
|
140
|
-
|
141
154
|
# Create a new +Currency+ object.
|
142
155
|
#
|
143
|
-
# @param [String, Symbol, #to_s] id Used to look into +
|
156
|
+
# @param [String, Symbol, #to_s] id Used to look into +table+ and retrieve
|
144
157
|
# the applicable attributes.
|
145
158
|
#
|
146
159
|
# @return [Money::Currency]
|
@@ -149,10 +162,10 @@ class Money
|
|
149
162
|
# Money::Currency.new(:usd) #=> #<Money::Currency id: usd ...>
|
150
163
|
def initialize(id)
|
151
164
|
id = id.to_s.downcase
|
152
|
-
raise(UnknownCurrency, "Unknown currency `#{id}'") unless
|
165
|
+
raise(UnknownCurrency, "Unknown currency `#{id}'") unless self.class.stringified_keys.include?(id)
|
153
166
|
|
154
167
|
@id = id.to_sym
|
155
|
-
data =
|
168
|
+
data = self.class.table[@id]
|
156
169
|
data.each_pair do |key, value|
|
157
170
|
instance_variable_set(:"@#{key}", value)
|
158
171
|
end
|
@@ -263,18 +276,41 @@ class Money
|
|
263
276
|
!!@symbol_first
|
264
277
|
end
|
265
278
|
|
279
|
+
# Cache decimal places for subunit_to_unit values. Common ones pre-cached.
|
280
|
+
def self.decimal_places_cache
|
281
|
+
@decimal_places_cache ||= {
|
282
|
+
1 => 0,
|
283
|
+
10 => 1,
|
284
|
+
100 => 2,
|
285
|
+
1000 => 3
|
286
|
+
}
|
287
|
+
end
|
288
|
+
|
266
289
|
# The number of decimal places needed.
|
267
290
|
#
|
268
291
|
# @return [Integer]
|
269
292
|
def decimal_places
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
293
|
+
cache = self.class.decimal_places_cache
|
294
|
+
places = cache[subunit_to_unit]
|
295
|
+
unless places
|
296
|
+
places = calculate_decimal_places(subunit_to_unit)
|
297
|
+
cache[subunit_to_unit] = places
|
298
|
+
end
|
299
|
+
places
|
300
|
+
end
|
301
|
+
|
302
|
+
# If we need to figure out how many decimal places we need we
|
303
|
+
# use repeated integer division.
|
304
|
+
def calculate_decimal_places(num)
|
305
|
+
return 0 if num == 1
|
306
|
+
i = 1
|
307
|
+
while num >= 10
|
308
|
+
num /= 10
|
309
|
+
i += 1 if num >= 10
|
276
310
|
end
|
311
|
+
i
|
277
312
|
end
|
313
|
+
private :calculate_decimal_places
|
278
314
|
|
279
315
|
end
|
280
316
|
end
|
data/lib/money/money.rb
CHANGED
@@ -30,7 +30,7 @@ class Money
|
|
30
30
|
class << self
|
31
31
|
# Each Money object is associated to a bank object, which is responsible
|
32
32
|
# for currency exchange. This property allows you to specify the default
|
33
|
-
# bank object. The default value for this property is an instance
|
33
|
+
# bank object. The default value for this property is an instance of
|
34
34
|
# +Bank::VariableExchange.+ It allows one to specify custom exchange rates.
|
35
35
|
#
|
36
36
|
# @return [Money::Bank::*]
|
@@ -47,6 +47,11 @@ class Money
|
|
47
47
|
#
|
48
48
|
# @return [true,false]
|
49
49
|
attr_accessor :use_i18n
|
50
|
+
|
51
|
+
# Use this to enable the ability to assume the currency from a passed symbol
|
52
|
+
#
|
53
|
+
# @return [true,false]
|
54
|
+
attr_accessor :assume_from_symbol
|
50
55
|
end
|
51
56
|
|
52
57
|
# Set the default bank for creating new +Money+ objects.
|
@@ -58,6 +63,9 @@ class Money
|
|
58
63
|
# Default to using i18n
|
59
64
|
self.use_i18n = true
|
60
65
|
|
66
|
+
# Default to not using currency symbol assumptions when parsing
|
67
|
+
self.assume_from_symbol = false
|
68
|
+
|
61
69
|
# Create a new money object with value 0.
|
62
70
|
#
|
63
71
|
# @param [Currency, String, Symbol] currency The currency to use.
|
@@ -56,6 +56,32 @@ class Money
|
|
56
56
|
end
|
57
57
|
end
|
58
58
|
|
59
|
+
# Test if the amount is positive. Returns +true+ if the money amount is
|
60
|
+
# greater than 0, +false+ otherwise.
|
61
|
+
#
|
62
|
+
# @return [Boolean]
|
63
|
+
#
|
64
|
+
# @example
|
65
|
+
# Money.new(1).positive? #=> true
|
66
|
+
# Money.new(0).positive? #=> false
|
67
|
+
# Money.new(-1).positive? #=> false
|
68
|
+
def positive?
|
69
|
+
cents > 0
|
70
|
+
end
|
71
|
+
|
72
|
+
# Test if the amount is negative. Returns +true+ if the money amount is
|
73
|
+
# less than 0, +false+ otherwise.
|
74
|
+
#
|
75
|
+
# @return [Boolean]
|
76
|
+
#
|
77
|
+
# @example
|
78
|
+
# Money.new(-1).negative? #=> true
|
79
|
+
# Money.new(0).negative? #=> false
|
80
|
+
# Money.new(1).negative? #=> false
|
81
|
+
def negative?
|
82
|
+
cents < 0
|
83
|
+
end
|
84
|
+
|
59
85
|
# Returns a new Money object containing the sum of the two operands' monetary
|
60
86
|
# values. If +other_money+ has a different currency then its monetary value
|
61
87
|
# is automatically exchanged to this object's currency using +exchange_to+.
|
@@ -163,13 +163,13 @@ class Money
|
|
163
163
|
""
|
164
164
|
end
|
165
165
|
elsif rules[:html]
|
166
|
-
currency.html_entity
|
166
|
+
currency.html_entity == '' ? currency.symbol : currency.html_entity
|
167
167
|
else
|
168
168
|
symbol
|
169
169
|
end
|
170
170
|
|
171
171
|
formatted = rules[:no_cents] ? "#{self.to_s.to_i}" : self.to_s
|
172
|
-
|
172
|
+
|
173
173
|
if rules[:no_cents_if_whole] && cents % currency.subunit_to_unit == 0
|
174
174
|
formatted = "#{self.to_s.to_i}"
|
175
175
|
end
|
@@ -204,7 +204,13 @@ class Money
|
|
204
204
|
end
|
205
205
|
|
206
206
|
# Apply thousands_separator
|
207
|
-
|
207
|
+
regexp_decimal = Regexp.escape(decimal_mark)
|
208
|
+
regexp_format = if formatted =~ /#{regexp_decimal}/
|
209
|
+
/(\d)(?=(?:\d{3})+(?:#{regexp_decimal}))/
|
210
|
+
else
|
211
|
+
/(\d)(?=(?:\d{3})+(?:[^\d]{1}|$))/
|
212
|
+
end
|
213
|
+
formatted.gsub!(regexp_format, "\\1#{thousands_separator_value}")
|
208
214
|
|
209
215
|
if rules[:with_currency]
|
210
216
|
formatted << " "
|
data/lib/money/money/parsing.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
#encoding: utf-8
|
2
|
+
|
1
3
|
class Money
|
2
4
|
module Parsing
|
3
5
|
def self.included(base)
|
@@ -32,11 +34,21 @@ class Money
|
|
32
34
|
# @see Money.from_string
|
33
35
|
#
|
34
36
|
def parse(input, currency = nil)
|
35
|
-
i = input.to_s
|
37
|
+
i = input.to_s.strip
|
38
|
+
|
39
|
+
# raise Money::Currency.table.collect{|c| c[1][:symbol]}.inspect
|
36
40
|
|
37
|
-
#
|
38
|
-
|
39
|
-
|
41
|
+
# Check the first character for a currency symbol, alternatively get it
|
42
|
+
# from the stated currency string
|
43
|
+
c = if Money.assume_from_symbol && i =~ /^(\$|€|£)/
|
44
|
+
case i
|
45
|
+
when /^$/ then "USD"
|
46
|
+
when /^€/ then "EUR"
|
47
|
+
when /^£/ then "GBP"
|
48
|
+
end
|
49
|
+
else
|
50
|
+
i[/[A-Z]{2,3}/]
|
51
|
+
end
|
40
52
|
|
41
53
|
# check that currency passed and embedded currency are the same,
|
42
54
|
# and negotiate the final currency
|
@@ -172,7 +184,7 @@ class Money
|
|
172
184
|
def from_bigdecimal(value, currency = Money.default_currency)
|
173
185
|
currency = Money::Currency.wrap(currency)
|
174
186
|
amount = value * currency.subunit_to_unit
|
175
|
-
new(amount.
|
187
|
+
new(amount.round, currency)
|
176
188
|
end
|
177
189
|
|
178
190
|
# Converts a Numeric value into a Money object treating the +value+
|
@@ -227,11 +239,14 @@ class Money
|
|
227
239
|
#
|
228
240
|
def extract_cents(input, currency = Money.default_currency)
|
229
241
|
# remove anything that's not a number, potential thousands_separator, or minus sign
|
230
|
-
num = input.gsub(/[^\d
|
242
|
+
num = input.gsub(/[^\d.,'-]/, '')
|
231
243
|
|
232
244
|
# set a boolean flag for if the number is negative or not
|
233
245
|
negative = num =~ /^-|-$/ ? true : false
|
234
246
|
|
247
|
+
# decimal mark character
|
248
|
+
decimal_char = currency.decimal_mark
|
249
|
+
|
235
250
|
# if negative, remove the minus sign from the number
|
236
251
|
# if it's not negative, the hyphen makes the value invalid
|
237
252
|
if negative
|
@@ -279,41 +294,47 @@ class Money
|
|
279
294
|
# assign first decimal_mark for reusability
|
280
295
|
decimal_mark = used_decimal_marks.first
|
281
296
|
|
282
|
-
#
|
283
|
-
if
|
284
|
-
major, minor = num.
|
285
|
-
else
|
286
|
-
# ex: 1,000 - 1.0000 - 10001.000
|
287
|
-
# split number into possible major (dollars) and minor (cents) values
|
288
|
-
possible_major, possible_minor = num.split(decimal_mark)
|
289
|
-
possible_major ||= "0"
|
290
|
-
possible_minor ||= "00"
|
297
|
+
# When we have identified the decimal mark character
|
298
|
+
if decimal_char == decimal_mark
|
299
|
+
major, minor = num.split(decimal_char)
|
291
300
|
|
292
|
-
|
293
|
-
#
|
294
|
-
|
295
|
-
|
296
|
-
# 1.2 => 1.20
|
297
|
-
if possible_minor.length != 3 # thousands_separator
|
298
|
-
major, minor = possible_major, possible_minor
|
301
|
+
else
|
302
|
+
# decimal_mark is used as a decimal_mark when there are multiple instances, always
|
303
|
+
if num.scan(decimal_mark).length > 1 # multiple matches; treat as decimal_mark
|
304
|
+
major, minor = num.gsub(decimal_mark, ''), 0
|
299
305
|
else
|
300
|
-
#
|
301
|
-
#
|
306
|
+
# ex: 1,000 - 1.0000 - 10001.000
|
307
|
+
# split number into possible major (dollars) and minor (cents) values
|
308
|
+
possible_major, possible_minor = num.split(decimal_mark)
|
309
|
+
possible_major ||= "0"
|
310
|
+
possible_minor ||= "00"
|
302
311
|
|
303
|
-
# the
|
304
|
-
# the comma or period is used as a thousands_separator
|
312
|
+
# if the minor (cents) length isn't 3, assign major/minor from the possibles
|
305
313
|
# e.g.
|
306
|
-
#
|
307
|
-
#
|
308
|
-
|
314
|
+
# 1,00 => 1.00
|
315
|
+
# 1.0000 => 1.00
|
316
|
+
# 1.2 => 1.20
|
317
|
+
if possible_minor.length != 3 # thousands_separator
|
309
318
|
major, minor = possible_major, possible_minor
|
310
319
|
else
|
311
|
-
#
|
312
|
-
#
|
313
|
-
|
320
|
+
# minor length is three
|
321
|
+
# let's try to figure out intent of the thousands_separator
|
322
|
+
|
323
|
+
# the major length is greater than three, which means
|
324
|
+
# the comma or period is used as a thousands_separator
|
325
|
+
# e.g.
|
326
|
+
# 1000,000
|
327
|
+
# 100000,000
|
328
|
+
if possible_major.length > 3
|
314
329
|
major, minor = possible_major, possible_minor
|
315
330
|
else
|
316
|
-
|
331
|
+
# number is in format ###{sep}### or ##{sep}### or #{sep}###
|
332
|
+
# handle as , is sep, . is thousands_separator
|
333
|
+
if decimal_mark == '.'
|
334
|
+
major, minor = possible_major, possible_minor
|
335
|
+
else
|
336
|
+
major, minor = "#{possible_major}#{possible_minor}", 0
|
337
|
+
end
|
317
338
|
end
|
318
339
|
end
|
319
340
|
end
|
@@ -344,7 +365,6 @@ class Money
|
|
344
365
|
# if negative, multiply by -1; otherwise, return positive cents
|
345
366
|
negative ? cents * -1 : cents
|
346
367
|
end
|
347
|
-
|
348
368
|
end
|
349
369
|
end
|
350
370
|
end
|
data/money.gemspec
CHANGED
@@ -146,7 +146,7 @@ describe Money::Bank::VariableExchange do
|
|
146
146
|
context "with :file provided" do
|
147
147
|
it "writes rates to file" do
|
148
148
|
f = mock('IO')
|
149
|
-
File.should_receive(:open).with('null', 'w').
|
149
|
+
File.should_receive(:open).with('null', 'w').and_yield(f)
|
150
150
|
f.should_receive(:write).with(@rates.to_json)
|
151
151
|
|
152
152
|
subject.export_rates(:json, 'null')
|
data/spec/currency_spec.rb
CHANGED
@@ -4,18 +4,17 @@ require "spec_helper"
|
|
4
4
|
|
5
5
|
describe Money::Currency do
|
6
6
|
|
7
|
+
FOO = '{ "priority": 1, "iso_code": "FOO", "iso_numeric": "840", "name": "United States Dollar", "symbol": "$", "subunit": "Cent", "subunit_to_unit": 450, "symbol_first": true, "html_entity": "$", "decimal_mark": ".", "thousands_separator": "," }'
|
8
|
+
|
7
9
|
describe ".find" do
|
8
10
|
it "returns currency matching given id" do
|
9
|
-
|
10
|
-
Money::Currency::TABLE[:usd] = JSON.parse(%Q({ "priority": 1, "iso_code": "USD", "iso_numeric": "840", "name": "United States Dollar", "symbol": "$", "subunit": "Cent", "subunit_to_unit": 100, "symbol_first": true, "html_entity": "$", "decimal_mark": ".", "thousands_separator": "," }))
|
11
|
-
Money::Currency::TABLE[:eur] = JSON.parse(%Q({ "priority": 2, "iso_code": "EUR", "iso_numeric": "978", "name": "Euro", "symbol": "€", "subunit": "Cent", "subunit_to_unit": 100, "symbol_first": false, "html_entity": "€", "decimal_mark": ",", "thousands_separator": "." }))
|
11
|
+
Money::Currency.register(JSON.parse(FOO, :symbolize_names => true))
|
12
12
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
end
|
13
|
+
expected = Money::Currency.new(:foo)
|
14
|
+
Money::Currency.find(:foo).should == expected
|
15
|
+
Money::Currency.find(:FOO).should == expected
|
16
|
+
Money::Currency.find("foo").should == expected
|
17
|
+
Money::Currency.find("FOO").should == expected
|
19
18
|
end
|
20
19
|
|
21
20
|
it "returns nil unless currency matching given id" do
|
@@ -123,17 +122,15 @@ describe Money::Currency do
|
|
123
122
|
end
|
124
123
|
end
|
125
124
|
|
125
|
+
describe "#decimal_places" do
|
126
|
+
it "proper places for known currency" do
|
127
|
+
Money::Currency.new(:mro).decimal_places == 1
|
128
|
+
Money::Currency.new(:usd).decimal_places == 2
|
129
|
+
end
|
126
130
|
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
Money::Currency::TABLE.clear
|
131
|
-
yield
|
132
|
-
ensure
|
133
|
-
silence_warnings do
|
134
|
-
Money::Currency.const_set("TABLE", old)
|
135
|
-
end
|
131
|
+
it "proper places for custom currency" do
|
132
|
+
Money::Currency.register(JSON.parse(FOO, :symbolize_names => true))
|
133
|
+
Money::Currency.new(:foo).decimal_places == 3
|
136
134
|
end
|
137
135
|
end
|
138
|
-
|
139
136
|
end
|
@@ -164,6 +164,34 @@ describe Money do
|
|
164
164
|
end
|
165
165
|
end
|
166
166
|
|
167
|
+
describe "#positive?" do
|
168
|
+
it "returns true if the amount is greater than 0" do
|
169
|
+
Money.new(1).should be_positive
|
170
|
+
end
|
171
|
+
|
172
|
+
it "returns false if the amount is 0" do
|
173
|
+
Money.new(0).should_not be_positive
|
174
|
+
end
|
175
|
+
|
176
|
+
it "returns false if the amount is negative" do
|
177
|
+
Money.new(-1).should_not be_positive
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
describe "#negative?" do
|
182
|
+
it "returns true if the amount is less than 0" do
|
183
|
+
Money.new(-1).should be_negative
|
184
|
+
end
|
185
|
+
|
186
|
+
it "returns false if the amount is 0" do
|
187
|
+
Money.new(0).should_not be_negative
|
188
|
+
end
|
189
|
+
|
190
|
+
it "returns false if the amount is greater than 0" do
|
191
|
+
Money.new(1).should_not be_negative
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
167
195
|
describe "#+" do
|
168
196
|
it "adds other amount to current amount (same currency)" do
|
169
197
|
(Money.new(10_00, "USD") + Money.new(90, "USD")).should == Money.new(10_90, "USD")
|
@@ -4,6 +4,9 @@ require "spec_helper"
|
|
4
4
|
|
5
5
|
describe Money, "formatting" do
|
6
6
|
|
7
|
+
BAR = '{ "priority": 1, "iso_code": "BAR", "iso_numeric": "840", "name": "Dollar with 4 decimal places", "symbol": "$", "subunit": "Cent", "subunit_to_unit": 10000, "symbol_first": true, "html_entity": "$", "decimal_mark": ".", "thousands_separator": "," }'
|
8
|
+
EU4 = '{ "priority": 1, "iso_code": "EU4", "iso_numeric": "841", "name": "Euro with 4 decimal places", "symbol": "€", "subunit": "Cent", "subunit_to_unit": 10000, "symbol_first": true, "html_entity": "€", "decimal_mark": ",", "thousands_separator": "." }'
|
9
|
+
|
7
10
|
context "without i18n" do
|
8
11
|
subject { Money.empty("USD") }
|
9
12
|
|
@@ -117,7 +120,7 @@ describe Money, "formatting" do
|
|
117
120
|
one_thousand["CNY"].should == "¥1,000.00"
|
118
121
|
|
119
122
|
# Euro
|
120
|
-
one_thousand["EUR"].should == "1.000,00
|
123
|
+
one_thousand["EUR"].should == "€1.000,00"
|
121
124
|
|
122
125
|
# Rupees
|
123
126
|
one_thousand["INR"].should == "₨1,000.00"
|
@@ -139,8 +142,8 @@ describe Money, "formatting" do
|
|
139
142
|
end
|
140
143
|
|
141
144
|
it "inserts thousands separator into the result if the amount is sufficiently large and the currency symbol is at the end" do
|
142
|
-
Money.euro(1_234_567_12).format.should == "1.234.567,12
|
143
|
-
Money.euro(1_234_567_12).format(:no_cents => true).should == "1.234.567
|
145
|
+
Money.euro(1_234_567_12).format.should == "€1.234.567,12"
|
146
|
+
Money.euro(1_234_567_12).format(:no_cents => true).should == "€1.234.567"
|
144
147
|
end
|
145
148
|
|
146
149
|
describe ":with_currency option" do
|
@@ -216,7 +219,7 @@ describe Money, "formatting" do
|
|
216
219
|
one["CNY"].should == "¥1.00"
|
217
220
|
|
218
221
|
# Euro
|
219
|
-
one["EUR"].should == "1,00
|
222
|
+
one["EUR"].should == "€1,00"
|
220
223
|
|
221
224
|
# Rupees
|
222
225
|
one["INR"].should == "₨1.00"
|
@@ -235,12 +238,12 @@ describe Money, "formatting" do
|
|
235
238
|
specify "(:symbol => true) returns $ when currency code is not recognized" do
|
236
239
|
currency = Money::Currency.new("EUR")
|
237
240
|
currency.should_receive(:symbol).and_return(nil)
|
238
|
-
Money.new(100, currency).format(:symbol => true).should == "1,00
|
241
|
+
Money.new(100, currency).format(:symbol => true).should == "¤1,00"
|
239
242
|
end
|
240
243
|
|
241
244
|
specify "(:symbol => some non-Boolean value that evaluates to true) returns symbol based on the given currency code" do
|
242
245
|
Money.new(100, "GBP").format(:symbol => true).should == "£1.00"
|
243
|
-
Money.new(100, "EUR").format(:symbol => true).should == "1,00
|
246
|
+
Money.new(100, "EUR").format(:symbol => true).should == "€1,00"
|
244
247
|
Money.new(100, "SEK").format(:symbol => true).should == "kr1.00"
|
245
248
|
end
|
246
249
|
|
@@ -259,7 +262,7 @@ describe Money, "formatting" do
|
|
259
262
|
money.format.should == "£1.00"
|
260
263
|
|
261
264
|
money = Money.new(100, "EUR")
|
262
|
-
money.format.should == "1,00
|
265
|
+
money.format.should == "€1,00"
|
263
266
|
end
|
264
267
|
end
|
265
268
|
|
@@ -310,6 +313,11 @@ describe Money, "formatting" do
|
|
310
313
|
string = Money.ca_dollar(570).format(:html => true, :with_currency => true)
|
311
314
|
string.should == "$5.70 <span class=\"currency\">CAD</span>"
|
312
315
|
end
|
316
|
+
|
317
|
+
specify "should fallback to symbol if entity is not available" do
|
318
|
+
string = Money.new(570, 'DKK').format(:html => true)
|
319
|
+
string.should == "5,70 kr"
|
320
|
+
end
|
313
321
|
end
|
314
322
|
|
315
323
|
describe ":symbol_position option" do
|
@@ -398,5 +406,41 @@ describe Money, "formatting" do
|
|
398
406
|
end
|
399
407
|
end
|
400
408
|
|
409
|
+
context "custom currencies with 4 decimal places" do
|
410
|
+
before :each do
|
411
|
+
Money::Currency.register(JSON.parse(BAR, :symbolize_names => true))
|
412
|
+
Money::Currency.register(JSON.parse(EU4, :symbolize_names => true))
|
413
|
+
end
|
414
|
+
|
415
|
+
it "respects custom subunit to unit, decimal and thousands separator" do
|
416
|
+
Money.new(4, "BAR").format.should == "$0.0004"
|
417
|
+
Money.new(4, "EU4").format.should == "€0,0004"
|
418
|
+
|
419
|
+
Money.new(24, "BAR").format.should == "$0.0024"
|
420
|
+
Money.new(24, "EU4").format.should == "€0,0024"
|
421
|
+
|
422
|
+
Money.new(324, "BAR").format.should == "$0.0324"
|
423
|
+
Money.new(324, "EU4").format.should == "€0,0324"
|
424
|
+
|
425
|
+
Money.new(5324, "BAR").format.should == "$0.5324"
|
426
|
+
Money.new(5324, "EU4").format.should == "€0,5324"
|
427
|
+
|
428
|
+
Money.new(65324, "BAR").format.should == "$6.5324"
|
429
|
+
Money.new(65324, "EU4").format.should == "€6,5324"
|
430
|
+
|
431
|
+
Money.new(865324, "BAR").format.should == "$86.5324"
|
432
|
+
Money.new(865324, "EU4").format.should == "€86,5324"
|
433
|
+
|
434
|
+
Money.new(1865324, "BAR").format.should == "$186.5324"
|
435
|
+
Money.new(1865324, "EU4").format.should == "€186,5324"
|
436
|
+
|
437
|
+
Money.new(33310034, "BAR").format.should == "$3,331.0034"
|
438
|
+
Money.new(33310034, "EU4").format.should == "€3.331,0034"
|
439
|
+
|
440
|
+
Money.new(88833310034, "BAR").format.should == "$8,883,331.0034"
|
441
|
+
Money.new(88833310034, "EU4").format.should == "€8.883.331,0034"
|
442
|
+
end
|
443
|
+
|
444
|
+
end
|
401
445
|
end
|
402
446
|
|
data/spec/money/parsing_spec.rb
CHANGED
@@ -4,6 +4,9 @@ require "spec_helper"
|
|
4
4
|
|
5
5
|
describe Money, "parsing" do
|
6
6
|
|
7
|
+
bar = '{ "priority": 1, "iso_code": "BAR", "iso_numeric": "840", "name": "Dollar with 4 decimal places", "symbol": "$", "subunit": "Cent", "subunit_to_unit": 10000, "symbol_first": true, "html_entity": "$", "decimal_mark": ".", "thousands_separator": "," }'
|
8
|
+
eu4 = '{ "priority": 1, "iso_code": "EU4", "iso_numeric": "841", "name": "Euro with 4 decimal places", "symbol": "€", "subunit": "Cent", "subunit_to_unit": 10000, "symbol_first": true, "html_entity": "€", "decimal_mark": ",", "thousands_separator": "." }'
|
9
|
+
|
7
10
|
describe ".parse" do
|
8
11
|
it "parses european-formatted inputs under 10EUR" do
|
9
12
|
five_ninety_five = Money.new(595, 'EUR')
|
@@ -19,6 +22,38 @@ describe Money, "parsing" do
|
|
19
22
|
Money.parse('EUR 1.111.234.567,89').should == Money.new(111123456789, 'EUR')
|
20
23
|
end
|
21
24
|
|
25
|
+
describe 'currency assumption' do
|
26
|
+
context 'opted in' do
|
27
|
+
before do
|
28
|
+
Money.assume_from_symbol = true
|
29
|
+
end
|
30
|
+
it "parses formatted inputs with the currency passed as a symbol" do
|
31
|
+
Money.parse("$5.95").should == Money.new(595, 'USD')
|
32
|
+
Money.parse("€5.95").should == Money.new(595, 'EUR')
|
33
|
+
Money.parse(" €5.95 ").should == Money.new(595, 'EUR')
|
34
|
+
Money.parse("£9.99").should == Money.new(999, 'GBP')
|
35
|
+
end
|
36
|
+
it 'should assume default currency if not a recognised symbol' do
|
37
|
+
Money.parse("L9.99").should == Money.new(999, 'USD')
|
38
|
+
end
|
39
|
+
end
|
40
|
+
context 'opted out' do
|
41
|
+
before do
|
42
|
+
Money.assume_from_symbol = false
|
43
|
+
end
|
44
|
+
it "parses formatted inputs with the currency passed as a symbol but ignores the symbol" do
|
45
|
+
Money.parse("$5.95").should == Money.new(595, 'USD')
|
46
|
+
Money.parse("€5.95").should == Money.new(595, 'USD')
|
47
|
+
Money.parse(" €5.95 ").should == Money.new(595, 'USD')
|
48
|
+
Money.parse("£9.99").should == Money.new(999, 'USD')
|
49
|
+
|
50
|
+
end
|
51
|
+
end
|
52
|
+
it 'should opt out by default' do
|
53
|
+
Money.assume_from_symbol.should be_false
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
22
57
|
it "parses USD-formatted inputs under $10" do
|
23
58
|
five_ninety_five = Money.new(595, 'USD')
|
24
59
|
|
@@ -63,6 +98,56 @@ describe Money, "parsing" do
|
|
63
98
|
it "raises ArgumentError when unable to detect polarity" do
|
64
99
|
lambda { Money.parse('-$5.95-') }.should raise_error ArgumentError
|
65
100
|
end
|
101
|
+
|
102
|
+
it "parses correctly strings with exactly 3 decimal digits" do
|
103
|
+
Money.parse("6,534", "EUR").should == Money.new(653, "EUR")
|
104
|
+
end
|
105
|
+
|
106
|
+
context "custom currencies with 4 decimal places" do
|
107
|
+
before :each do
|
108
|
+
Money::Currency.register(JSON.parse(bar, :symbolize_names => true))
|
109
|
+
Money::Currency.register(JSON.parse(eu4, :symbolize_names => true))
|
110
|
+
end
|
111
|
+
|
112
|
+
# String#to_money(Currency) is equivalent to Money.parse(String, Currency)
|
113
|
+
it "parses strings respecting subunit to unit, decimal and thousands separator" do
|
114
|
+
"$0.4".to_money("BAR").should == Money.new(4000, "BAR")
|
115
|
+
"€0,4".to_money("EU4").should == Money.new(4000, "EU4")
|
116
|
+
|
117
|
+
"$0.04".to_money("BAR").should == Money.new(400, "BAR")
|
118
|
+
"€0,04".to_money("EU4").should == Money.new(400, "EU4")
|
119
|
+
|
120
|
+
"$0.004".to_money("BAR").should == Money.new(40, "BAR")
|
121
|
+
"€0,004".to_money("EU4").should == Money.new(40, "EU4")
|
122
|
+
|
123
|
+
"$0.0004".to_money("BAR").should == Money.new(4, "BAR")
|
124
|
+
"€0,0004".to_money("EU4").should == Money.new(4, "EU4")
|
125
|
+
|
126
|
+
"$0.0024".to_money("BAR").should == Money.new(24, "BAR")
|
127
|
+
"€0,0024".to_money("EU4").should == Money.new(24, "EU4")
|
128
|
+
|
129
|
+
"$0.0324".to_money("BAR").should == Money.new(324, "BAR")
|
130
|
+
"€0,0324".to_money("EU4").should == Money.new(324, "EU4")
|
131
|
+
|
132
|
+
"$0.5324".to_money("BAR").should == Money.new(5324, "BAR")
|
133
|
+
"€0,5324".to_money("EU4").should == Money.new(5324, "EU4")
|
134
|
+
|
135
|
+
"$6.5324".to_money("BAR").should == Money.new(65324, "BAR")
|
136
|
+
"€6,5324".to_money("EU4").should == Money.new(65324, "EU4")
|
137
|
+
|
138
|
+
"$86.5324".to_money("BAR").should == Money.new(865324, "BAR")
|
139
|
+
"€86,5324".to_money("EU4").should == Money.new(865324, "EU4")
|
140
|
+
|
141
|
+
"$186.5324".to_money("BAR").should == Money.new(1865324, "BAR")
|
142
|
+
"€186,5324".to_money("EU4").should == Money.new(1865324, "EU4")
|
143
|
+
|
144
|
+
"$3,331.0034".to_money("BAR").should == Money.new(33310034, "BAR")
|
145
|
+
"€3.331,0034".to_money("EU4").should == Money.new(33310034, "EU4")
|
146
|
+
|
147
|
+
"$8,883,331.0034".to_money("BAR").should == Money.new(88833310034, "BAR")
|
148
|
+
"€8.883.331,0034".to_money("EU4").should == Money.new(88833310034, "EU4")
|
149
|
+
end
|
150
|
+
end
|
66
151
|
end
|
67
152
|
|
68
153
|
describe ".from_string" do
|
@@ -207,4 +292,16 @@ describe Money, "parsing" do
|
|
207
292
|
end
|
208
293
|
end
|
209
294
|
|
295
|
+
describe ".extract_cents" do
|
296
|
+
it "correctly treats pipe marks '|' in input (regression test)" do
|
297
|
+
Money.extract_cents('100|0').should == Money.extract_cents('100!0')
|
298
|
+
end
|
299
|
+
end
|
300
|
+
|
301
|
+
context "given the same inputs to .parse and .from_*" do
|
302
|
+
it "gives the same results" do
|
303
|
+
4.635.to_money.should == "4.635".to_money
|
304
|
+
end
|
305
|
+
end
|
306
|
+
|
210
307
|
end
|
metadata
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: money
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
5
|
-
prerelease:
|
4
|
+
version: 5.0.0.rc1
|
5
|
+
prerelease: 6
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Tobias Luetke
|
@@ -13,11 +13,11 @@ authors:
|
|
13
13
|
autorequire:
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
|
-
date: 2012-02
|
16
|
+
date: 2012-04-02 00:00:00.000000000 Z
|
17
17
|
dependencies:
|
18
18
|
- !ruby/object:Gem::Dependency
|
19
19
|
name: i18n
|
20
|
-
requirement: &
|
20
|
+
requirement: &70315360313800 !ruby/object:Gem::Requirement
|
21
21
|
none: false
|
22
22
|
requirements:
|
23
23
|
- - ~>
|
@@ -25,10 +25,10 @@ dependencies:
|
|
25
25
|
version: '0.4'
|
26
26
|
type: :runtime
|
27
27
|
prerelease: false
|
28
|
-
version_requirements: *
|
28
|
+
version_requirements: *70315360313800
|
29
29
|
- !ruby/object:Gem::Dependency
|
30
30
|
name: json
|
31
|
-
requirement: &
|
31
|
+
requirement: &70315360313420 !ruby/object:Gem::Requirement
|
32
32
|
none: false
|
33
33
|
requirements:
|
34
34
|
- - ! '>='
|
@@ -36,10 +36,10 @@ dependencies:
|
|
36
36
|
version: '0'
|
37
37
|
type: :runtime
|
38
38
|
prerelease: false
|
39
|
-
version_requirements: *
|
39
|
+
version_requirements: *70315360313420
|
40
40
|
- !ruby/object:Gem::Dependency
|
41
41
|
name: rspec
|
42
|
-
requirement: &
|
42
|
+
requirement: &70315360312880 !ruby/object:Gem::Requirement
|
43
43
|
none: false
|
44
44
|
requirements:
|
45
45
|
- - ~>
|
@@ -47,10 +47,10 @@ dependencies:
|
|
47
47
|
version: 2.8.0
|
48
48
|
type: :development
|
49
49
|
prerelease: false
|
50
|
-
version_requirements: *
|
50
|
+
version_requirements: *70315360312880
|
51
51
|
- !ruby/object:Gem::Dependency
|
52
52
|
name: yard
|
53
|
-
requirement: &
|
53
|
+
requirement: &70315360328840 !ruby/object:Gem::Requirement
|
54
54
|
none: false
|
55
55
|
requirements:
|
56
56
|
- - ! '>='
|
@@ -58,7 +58,7 @@ dependencies:
|
|
58
58
|
version: '0'
|
59
59
|
type: :development
|
60
60
|
prerelease: false
|
61
|
-
version_requirements: *
|
61
|
+
version_requirements: *70315360328840
|
62
62
|
description: This library aids one in handling money and different currencies.
|
63
63
|
email:
|
64
64
|
- semmons99+RubyMoney@gmail.com
|