monetize 1.4.0 → 1.9.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 7f96f9f99c2fc04ab625a2977f370eff77d33696
4
- data.tar.gz: 75817ce67a91ae35019f6ef3a3b290b937b64749
3
+ metadata.gz: 7c921047a6f291ae61ceb19db130de7b0288d8e2
4
+ data.tar.gz: f48eb20c8582b1453ef6114df30793f9367d934e
5
5
  SHA512:
6
- metadata.gz: 657c4f4be74370f9a8b2b1f4fcb91e60a013e9d2e01f39f95258a48c47710c5418767770af32ca61c19d52b0a94ccaa875fd3a4b7d8f21023ff7f4b036700c90
7
- data.tar.gz: 4cb6265937f209b0797cc4c0d2e78b4fa27a9f27f9f045cfac8d00812dcb2ccb86072672897b7fb36f7337dab52cbb62c3e58739b9cdcdc9ec32b73393bedd9a
6
+ metadata.gz: 9b4a49126c30cfd92968d6fed6cd43a806e5cda807f8dfd0c8956d434e0e3a3331191d9e228e5648c4d11157f01d3c3fcdb72f72f21e52f96002ab803b70265a
7
+ data.tar.gz: 571ec0ec170014d408f4ba0208a1b40f04cdf3436b2939e7d43b922cfe2ce3e981fb5a51a6dc79eab8d07ccad4ecfbc270548e15b4293428df87dbc0c912d277
@@ -1,8 +1,17 @@
1
+ sudo: false
1
2
  language: ruby
2
3
  rvm:
3
4
  - 1.9.3
4
5
  - 2.0.0
5
- - 2.1.2
6
+ - 2.1.10
7
+ - 2.2.10
8
+ - 2.3.7
9
+ - 2.4.4
10
+ - 2.5.1
11
+ - 2.6.0
12
+ - jruby-9.0.5.0
13
+ before_install:
14
+ - gem install bundler --version '~> 1.17'
6
15
  script: bundle exec rspec spec
7
16
  notifications:
8
17
  recipients:
@@ -1,21 +1,86 @@
1
1
  # Changelog
2
2
 
3
- ## 1.4.0
4
- - Required Forwardable on Collection to resolve NameError [\#44](https://github.com/RubyMoney/monetize/issues/44)
5
- - Add capability to parse currency amounts given with suffixes (K, M, B, and T)
3
+ ## 1.9.1
4
+ - Ruby 2.6 support
6
5
 
7
- ## 1.3.0
8
- - Add NilClass extension
9
- - Added correct parsing of Brazilian Real $R symbol
10
- - Add testing task for Brazilian Real parsing
11
- - Add Lira Sign (₤) as a symbol for GBP
6
+ ## 1.9.0
7
+ - Relax Money gem dependency to ~> 6.12
8
+ - Refactor `Monetize::Parser`
9
+ - Ruby 2.5 support
12
10
 
13
- ## 1.3.1
14
- - Updated Money version dependency to 6.6
11
+ ## 1.8.0
12
+ - Money version updated to 6.11.2
13
+ - Fix rounding problem in `.from_bigdecimal`
14
+
15
+ ## 1.7.0
16
+ - Add South Korean Won currency
17
+ - Money version updated to 6.9
18
+ - Coveralls version update to 0.8.20
19
+ - Add South Korean Won currency
20
+ - Improve conversion to Money from Hash
21
+
22
+ ## 1.6.0
23
+ - Ruby 2.4.0 support
24
+ - Money version updated to 6.8
15
25
 
16
- ## master
26
+ ## 1.5.0
27
+ - Fix issue where parsing a Money object resulted in a Money object with its currency set to `Money.default_currency`,
28
+ rather than the currency that it was sent in as.
29
+ - Add extra currencies:
30
+ - Azerbaijani manat
31
+ - Chinese yuan
32
+ - Czech koruna
33
+ - Hungarian forint
34
+ - Indian rupee
35
+ - Russian ruble
36
+ - Turkish Lira
37
+ - Ukrainian Hryvnia
38
+ - Swiss Frank
39
+ - Polish Zloty
40
+ - Kazakhstani Tenge
41
+ - Fix issue with losing precision on BigDecimal input
42
+ - Add Swedish krona
43
+ - Exclude ambiguous kr symbol from parsing
44
+ - Fix JPY parsing
45
+ - Subclass all errors to Monetize::Error
46
+ - Fix ruby 1.9.3 compatibility
47
+ - Suppress errors when using parse. Use `parse!` instead
48
+ - Strip currency symbol prefix when parsing input
49
+
50
+ ## 1.4.0
17
51
  - Fixed support for <code>Money.infinite_precision = true</code> in .to_money
18
52
  - Add Rubocop config to project
19
53
  - Reformat code to adapt to Rubocop guidelines
20
54
  - Add config setting to always enforce currency delimiters
21
55
  - Add rake console task
56
+ - Required Forwardable on Collection to resolve NameError [\#44](https://github.com/RubyMoney/monetize/issues/44)
57
+ - Add capability to parse currency amounts given with suffixes (K, M, B, and T)
58
+
59
+ ## 1.3.1
60
+ - Updated Money version dependency to 6.6
61
+
62
+ ## 1.3.0
63
+ - Add Lira Sign (₤) as a symbol for GBP
64
+
65
+ ## 1.2.0
66
+ - Add support for parsing Yen symbol
67
+ - Add `Monetize.parse_collection` and `Monetize::Collection` class for parsing multiple values
68
+ - Add parsing of C$ for Canadian Dollar
69
+ - Add NilClass extension
70
+ - Add Hash extension
71
+
72
+ ## 1.1.0
73
+ - Add :assume_from_symbol option to #parse
74
+ - Enable #parse to detect currency with signed amounts
75
+ - Updated Money version dependency to 6.5.0
76
+
77
+ ## 1.0.0
78
+ - Updated Money version dependency to 6.4.0
79
+
80
+ ## 0.4.1
81
+ - Updated Money version dependency to 6.2.1
82
+
83
+ ## 0.4.0
84
+ - Added correct parsing of Brazilian Real $R symbol
85
+ - Add testing task for Brazilian Real parsing
86
+ - Updated Money version dependency to 6.2.0
data/Gemfile CHANGED
@@ -1,5 +1,15 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
- gem 'coveralls', require: false
3
+ gem 'coveralls', '>= 0.8.20', require: false
4
+
5
+ # JSON and I18n gem no longer supports ruby < 2.0.0
6
+ if defined?(JRUBY_VERSION)
7
+ gem 'json'
8
+ elsif RUBY_VERSION =~ /^1/
9
+ gem 'json', '~> 1.8.3'
10
+ gem 'tins', '~> 1.6.0'
11
+ gem 'term-ansicolor', '~> 1.3.0'
12
+ gem 'i18n', '~> 0.9'
13
+ end
4
14
 
5
15
  gemspec
data/README.md CHANGED
@@ -1,11 +1,11 @@
1
1
  # Monetize
2
2
 
3
- [![Gem Version](https://badge.fury.io/rb/monetize.png)](http://badge.fury.io/rb/monetize)
4
- [![Build Status](https://travis-ci.org/RubyMoney/monetize.png?branch=master)](https://travis-ci.org/RubyMoney/monetize)
5
- [![Code Climate](https://codeclimate.com/github/RubyMoney/monetize.png)](https://codeclimate.com/github/RubyMoney/monetize)
6
- [![Coverage Status](https://coveralls.io/repos/RubyMoney/monetize/badge.png)](https://coveralls.io/r/RubyMoney/monetize)
7
- [![Dependency Status](https://gemnasium.com/RubyMoney/monetize.png)](https://gemnasium.com/RubyMoney/monetize)
8
- [![License](http://img.shields.io/license/MIT.png?color=green)](http://opensource.org/licenses/MIT)
3
+ [![Gem Version](https://badge.fury.io/rb/monetize.svg)](http://badge.fury.io/rb/monetize)
4
+ [![Build Status](https://travis-ci.org/RubyMoney/monetize.svg?branch=master)](https://travis-ci.org/RubyMoney/monetize)
5
+ [![Code Climate](https://codeclimate.com/github/RubyMoney/monetize.svg)](https://codeclimate.com/github/RubyMoney/monetize)
6
+ [![Coverage Status](https://coveralls.io/repos/RubyMoney/monetize/badge.svg)](https://coveralls.io/r/RubyMoney/monetize)
7
+ [![Dependency Status](https://gemnasium.com/RubyMoney/monetize.svg)](https://gemnasium.com/RubyMoney/monetize)
8
+ [![License](https://img.shields.io/badge/license-MIT-green.svg)](http://opensource.org/licenses/MIT)
9
9
 
10
10
  A library for converting various objects into `Money` objects.
11
11
 
@@ -33,6 +33,16 @@ Monetize.parse("GBP 100") == Money.new(100_00, "GBP")
33
33
  "100".to_money == Money.new(100_00, "USD")
34
34
  ```
35
35
 
36
+ `parse` will return `nil` if it is unable to parse the input. Use `parse!` instead if you want a `Monetize::Error` (or one of the subclasses) to be raised instead:
37
+
38
+ ```ruby
39
+ >> Monetize.parse('OMG 100')
40
+ => nil
41
+
42
+ >> Monetize.parse!('OMG 100')
43
+ Monetize::ParseError: Unknown currency 'omg'
44
+ ```
45
+
36
46
  Optionally, enable the ability to assume the currency from a passed symbol. Otherwise, currency symbols will be ignored, and USD used as the default currency:
37
47
 
38
48
  ```ruby
@@ -2,30 +2,12 @@
2
2
 
3
3
  require 'money'
4
4
  require 'monetize/core_extensions'
5
+ require 'monetize/errors'
5
6
  require 'monetize/version'
6
- require 'collection'
7
+ require 'monetize/parser'
8
+ require 'monetize/collection'
7
9
 
8
10
  module Monetize
9
- CURRENCY_SYMBOLS = {
10
- '$' => 'USD',
11
- '€' => 'EUR',
12
- '£' => 'GBP',
13
- '₤' => 'GBP',
14
- 'R$' => 'BRL',
15
- 'R' => 'ZAR',
16
- '¥' => 'JPY',
17
- 'C$' => 'CAD'
18
- }
19
-
20
- MULTIPLIER_SUFFIXES = {
21
- 'K' => 3,
22
- 'M' => 6,
23
- 'B' => 9,
24
- 'T' => 12
25
- }
26
- MULTIPLIER_SUFFIXES.default = 0
27
- MULTIPLIER_REGEXP = Regexp.new(format('^(.*?\d)(%s)\b([^\d]*)$', MULTIPLIER_SUFFIXES.keys.join('|')), 'i')
28
-
29
11
  # Class methods
30
12
  class << self
31
13
  # @attr_accessor [true, false] assume_from_symbol Use this to enable the
@@ -37,195 +19,54 @@ module Monetize
37
19
  # though, it will try to determine the correct separator by itself. Set this
38
20
  # to true to enforce the delimiters set in the currency all the time.
39
21
  attr_accessor :enforce_currency_delimiters
40
- end
41
-
42
- def self.parse(input, currency = Money.default_currency, options = {})
43
- input = input.to_s.strip
44
22
 
45
- computed_currency = if options.fetch(:assume_from_symbol) { assume_from_symbol }
46
- compute_currency(input)
47
- else
48
- input[/[A-Z]{2,3}/]
49
- end
50
-
51
- currency = computed_currency || currency || Money.default_currency
52
- currency = Money::Currency.wrap(currency)
53
-
54
- fractional = extract_cents(input, currency)
55
- Money.new(fractional, currency)
56
- end
57
-
58
- def self.parse_collection(input, currency = Money.default_currency, options = {})
59
- Collection.parse(input, currency, options)
60
- end
61
-
62
- def self.from_string(value, currency = Money.default_currency)
63
- value = BigDecimal.new(value.to_s)
64
- from_bigdecimal(value, currency)
65
- end
66
-
67
- def self.from_fixnum(value, currency = Money.default_currency)
68
- currency = Money::Currency.wrap(currency)
69
- value *= currency.subunit_to_unit
70
- Money.new(value, currency)
71
- end
72
-
73
- def self.from_float(value, currency = Money.default_currency)
74
- value = BigDecimal.new(value.to_s)
75
- from_bigdecimal(value, currency)
76
- end
77
-
78
- def self.from_bigdecimal(value, currency = Money.default_currency)
79
- currency = Money::Currency.wrap(currency)
80
- value *= currency.subunit_to_unit
81
- value = value.round unless Money.infinite_precision
82
- Money.new(value, currency)
83
- end
84
-
85
- def self.from_numeric(value, currency = Money.default_currency)
86
- case value
87
- when Fixnum
88
- from_fixnum(value, currency)
89
- when Numeric
90
- value = BigDecimal.new(value.to_s)
91
- from_bigdecimal(value, currency)
92
- else
93
- fail ArgumentError, "'value' should be a type of Numeric"
23
+ def parse(input, currency = Money.default_currency, options = {})
24
+ parse! input, currency, options
25
+ rescue Error
26
+ nil
94
27
  end
95
- end
96
-
97
- def self.extract_cents(input, currency = Money.default_currency)
98
- multiplier_exp, input = extract_multiplier(input)
99
-
100
- num = input.gsub(/[^\d.,'-]/, '')
101
-
102
- negative, num = extract_sign(num)
103
-
104
- num.chop! if num.match(/[\.|,]$/)
105
-
106
- major, minor = extract_major_minor(num, currency)
107
-
108
- cents = major.to_i * currency.subunit_to_unit
109
28
 
110
- cents, minor = apply_multiplier(multiplier_exp, cents, minor)
29
+ def parse!(input, currency = Money.default_currency, options = {})
30
+ return input if input.is_a?(Money)
31
+ return from_numeric(input, currency) if input.is_a?(Numeric)
111
32
 
112
- cents += set_minor_precision(minor, currency)
33
+ parser = Monetize::Parser.new(input, currency, options)
34
+ currency_from_input = Money::Currency.wrap(parser.parse_currency)
113
35
 
114
- apply_sign(negative, cents)
115
- end
116
-
117
- private
118
-
119
- def self.apply_multiplier(multiplier_exp, cents, minor)
120
- cents *= (10**multiplier_exp)
121
- minor = minor.to_s + ('0' * multiplier_exp)
122
- shift = minor[0...multiplier_exp].to_i * 100
123
- cents += shift
124
- minor = (minor[multiplier_exp..-1] || '')
125
- [cents, minor]
126
- end
127
-
128
- def self.apply_sign(negative, cents)
129
- negative ? cents * -1 : cents
130
- end
131
-
132
- def self.contains_currency_symbol?(amount)
133
- amount =~ currency_symbol_regex
134
- end
135
-
136
- def self.compute_currency(amount)
137
- if contains_currency_symbol?(amount)
138
- matches = amount.match(currency_symbol_regex)
139
- CURRENCY_SYMBOLS[matches[:symbol]]
140
- else
141
- amount[/[A-Z]{2,3}/]
36
+ Money.new(parser.parse_cents(currency_from_input), currency_from_input)
37
+ rescue Money::Currency::UnknownCurrency => e
38
+ fail ParseError, e.message
142
39
  end
143
- end
144
-
145
- def self.extract_major_minor(num, currency)
146
- used_delimiters = num.scan(/[^\d]/).uniq
147
40
 
148
- case used_delimiters.length
149
- when 0
150
- [num, 0]
151
- when 2
152
- thousands_separator, decimal_mark = used_delimiters
153
- split_major_minor(num.gsub(thousands_separator, ''), decimal_mark)
154
- when 1
155
- extract_major_minor_with_single_delimiter(num, currency, used_delimiters.first)
156
- else
157
- fail ArgumentError, 'Invalid currency amount'
41
+ def parse_collection(input, currency = Money.default_currency, options = {})
42
+ Collection.parse(input, currency, options)
158
43
  end
159
- end
160
44
 
161
- def self.extract_major_minor_with_single_delimiter(num, currency, delimiter)
162
- if delimiter == currency.decimal_mark
163
- split_major_minor(num, delimiter)
164
- elsif enforce_currency_delimiters and delimiter == currency.thousands_separator
165
- [num.gsub(delimiter, ''), 0]
166
- else
167
- extract_major_minor_with_tentative_delimiter(num, delimiter)
45
+ def from_string(value, currency = Money.default_currency)
46
+ value = BigDecimal(value.to_s)
47
+ Money.from_amount(value, currency)
168
48
  end
169
- end
170
-
171
- def self.extract_major_minor_with_tentative_delimiter(num, delimiter)
172
- if num.scan(delimiter).length > 1
173
- # Multiple matches; treat as thousands separator
174
- [num.gsub(delimiter, ''), '00']
175
- else
176
- possible_major, possible_minor = split_major_minor(num, delimiter)
177
49
 
178
- if possible_minor.length != 3 or possible_major.length > 3 or delimiter == '.'
179
- # Doesn't look like thousands separator
180
- [possible_major, possible_minor]
181
- else
182
- ["#{possible_major}#{possible_minor}", '00']
183
- end
50
+ def from_fixnum(value, currency = Money.default_currency)
51
+ Money.from_amount(value, currency)
184
52
  end
185
- end
53
+ alias_method :from_integer, :from_fixnum
186
54
 
187
- def self.extract_multiplier(input)
188
- if (matches = MULTIPLIER_REGEXP.match(input))
189
- multiplier_suffix = matches[2].upcase
190
- [MULTIPLIER_SUFFIXES[multiplier_suffix], "#{$1}#{$3}"]
191
- else
192
- [0, input]
55
+ def from_float(value, currency = Money.default_currency)
56
+ Money.from_amount(value, currency)
193
57
  end
194
- end
195
-
196
- def self.extract_sign(input)
197
- result = (input =~ /^-+(.*)$/ or input =~ /^(.*)-+$/) ? [true, $1] : [false, input]
198
- fail ArgumentError, 'Invalid currency amount (hyphen)' if result[1].include?('-')
199
- result
200
- end
201
58
 
202
- def self.regex_safe_symbols
203
- CURRENCY_SYMBOLS.keys.map { |key| Regexp.escape(key) }.join('|')
204
- end
205
-
206
- def self.set_minor_precision(minor, currency)
207
- if Money.infinite_precision
208
- (BigDecimal.new(minor) / (10**minor.size)) * currency.subunit_to_unit
209
- elsif minor.size < currency.decimal_places
210
- (minor + ('0' * currency.decimal_places))[0, currency.decimal_places].to_i
211
- elsif minor.size > currency.decimal_places
212
- if minor[currency.decimal_places, 1].to_i >= 5
213
- minor[0, currency.decimal_places].to_i + 1
214
- else
215
- minor[0, currency.decimal_places].to_i
216
- end
217
- else
218
- minor.to_i
59
+ def from_bigdecimal(value, currency = Money.default_currency)
60
+ Money.from_amount(value, currency)
219
61
  end
220
- end
221
62
 
222
- def self.split_major_minor(num, delimiter)
223
- major, minor = num.split(delimiter)
224
- minor = '00' unless minor
225
- [major, minor]
226
- end
63
+ def from_numeric(value, currency = Money.default_currency)
64
+ fail ArgumentError, "'value' should be a type of Numeric" unless value.is_a?(Numeric)
65
+ Money.from_amount(value, currency)
66
+ end
227
67
 
228
- def self.currency_symbol_regex
229
- /\A[\+|\-]?(?<symbol>#{regex_safe_symbols})/
68
+ def extract_cents(input, currency = Money.default_currency)
69
+ Monetize::Parser.new(input).parse_cents(currency)
70
+ end
230
71
  end
231
72
  end
@@ -1,6 +1,5 @@
1
1
  # encoding: utf-8
2
2
 
3
- require 'monetize'
4
3
  require 'forwardable'
5
4
 
6
5
  module Monetize
@@ -2,6 +2,7 @@
2
2
 
3
3
  class Hash
4
4
  def to_money(currency = nil)
5
- Money.new(self[:cents], self[:currency] || currency || Money.default_currency)
5
+ hash_currency = self[:currency].is_a?(Hash) ? self[:currency][:iso_code] : self[:currency]
6
+ Money.new(self[:cents] || self[:fractional], hash_currency || currency || Money.default_currency)
6
7
  end
7
8
  end
@@ -2,7 +2,7 @@
2
2
 
3
3
  class String
4
4
  def to_money(currency = nil)
5
- Monetize.parse(self, currency)
5
+ Monetize.parse!(self, currency)
6
6
  end
7
7
 
8
8
  def to_currency
@@ -0,0 +1,6 @@
1
+ module Monetize
2
+ class Error < StandardError; end
3
+
4
+ class ParseError < Error; end
5
+ class ArgumentError < Error; end
6
+ end
@@ -0,0 +1,178 @@
1
+ # encoding: utf-8
2
+
3
+ module Monetize
4
+ class Parser
5
+ CURRENCY_SYMBOLS = {
6
+ '$' => 'USD',
7
+ '€' => 'EUR',
8
+ '£' => 'GBP',
9
+ '₤' => 'GBP',
10
+ 'R$' => 'BRL',
11
+ 'R' => 'ZAR',
12
+ '¥' => 'JPY',
13
+ 'C$' => 'CAD',
14
+ '₼' => 'AZN',
15
+ '元' => 'CNY',
16
+ 'Kč' => 'CZK',
17
+ 'Ft' => 'HUF',
18
+ '₹' => 'INR',
19
+ '₽' => 'RUB',
20
+ '₺' => 'TRY',
21
+ '₴' => 'UAH',
22
+ 'Fr' => 'CHF',
23
+ 'zł' => 'PLN',
24
+ '₸' => 'KZT',
25
+ "₩" => 'KRW',
26
+ }
27
+
28
+ MULTIPLIER_SUFFIXES = { 'K' => 3, 'M' => 6, 'B' => 9, 'T' => 12 }
29
+ MULTIPLIER_SUFFIXES.default = 0
30
+ MULTIPLIER_REGEXP = Regexp.new(format('^(.*?\d)(%s)\b([^\d]*)$', MULTIPLIER_SUFFIXES.keys.join('|')), 'i')
31
+
32
+ def initialize(input, fallback_currency = Money.default_currency, options = {})
33
+ @input = input.to_s.strip
34
+ @fallback_currency = fallback_currency
35
+ @options = options
36
+ end
37
+
38
+ def parse_cents(currency)
39
+ multiplier_exp, input = extract_multiplier
40
+
41
+ num = input.gsub(/(?:^#{currency.symbol}|[^\d.,'-]+)/, '')
42
+
43
+ negative, num = extract_sign(num)
44
+
45
+ num.chop! if num =~ /[\.|,]$/
46
+
47
+ major, minor = extract_major_minor(num, currency)
48
+
49
+ major, minor = apply_multiplier(multiplier_exp, major.to_i, minor)
50
+
51
+ cents = major.to_i * currency.subunit_to_unit
52
+
53
+ cents += set_minor_precision(minor, currency)
54
+
55
+ apply_sign(negative, cents)
56
+ end
57
+
58
+ def parse_currency
59
+ computed_currency = nil
60
+ computed_currency = compute_currency if assume_from_symbol?
61
+ computed_currency ||= input[/[A-Z]{2,3}/]
62
+
63
+ computed_currency || fallback_currency || Money.default_currency
64
+ end
65
+
66
+ private
67
+
68
+ attr_reader :input, :fallback_currency, :options
69
+
70
+ def assume_from_symbol?
71
+ options.fetch(:assume_from_symbol) { Monetize.assume_from_symbol }
72
+ end
73
+
74
+ def apply_multiplier(multiplier_exp, major, minor)
75
+ major *= 10**multiplier_exp
76
+ minor = minor.to_s + ('0' * multiplier_exp)
77
+ shift = minor[0...multiplier_exp].to_i
78
+ major += shift
79
+ minor = (minor[multiplier_exp..-1] || '')
80
+ [major, minor]
81
+ end
82
+
83
+ def apply_sign(negative, cents)
84
+ negative ? cents * -1 : cents
85
+ end
86
+
87
+ def compute_currency
88
+ matches = input.match(currency_symbol_regex)
89
+ CURRENCY_SYMBOLS[matches[:symbol]] if matches
90
+ end
91
+
92
+ def extract_major_minor(num, currency)
93
+ used_delimiters = num.scan(/[^\d]/).uniq
94
+
95
+ case used_delimiters.length
96
+ when 0
97
+ [num, 0]
98
+ when 2
99
+ thousands_separator, decimal_mark = used_delimiters
100
+ split_major_minor(num.gsub(thousands_separator, ''), decimal_mark)
101
+ when 1
102
+ extract_major_minor_with_single_delimiter(num, currency, used_delimiters.first)
103
+ else
104
+ fail ParseError, 'Invalid amount'
105
+ end
106
+ end
107
+
108
+ def extract_major_minor_with_single_delimiter(num, currency, delimiter)
109
+ if delimiter == currency.decimal_mark
110
+ split_major_minor(num, delimiter)
111
+ elsif Monetize.enforce_currency_delimiters && delimiter == currency.thousands_separator
112
+ [num.gsub(delimiter, ''), 0]
113
+ else
114
+ extract_major_minor_with_tentative_delimiter(num, delimiter)
115
+ end
116
+ end
117
+
118
+ def extract_major_minor_with_tentative_delimiter(num, delimiter)
119
+ if num.scan(delimiter).length > 1
120
+ # Multiple matches; treat as thousands separator
121
+ [num.gsub(delimiter, ''), '00']
122
+ else
123
+ possible_major, possible_minor = split_major_minor(num, delimiter)
124
+
125
+ if possible_minor.length != 3 || possible_major.length > 3 || delimiter == '.'
126
+ # Doesn't look like thousands separator
127
+ [possible_major, possible_minor]
128
+ else
129
+ ["#{possible_major}#{possible_minor}", '00']
130
+ end
131
+ end
132
+ end
133
+
134
+ def extract_multiplier
135
+ if (matches = MULTIPLIER_REGEXP.match(input))
136
+ multiplier_suffix = matches[2].upcase
137
+ [MULTIPLIER_SUFFIXES[multiplier_suffix], "#{$1}#{$3}"]
138
+ else
139
+ [0, input]
140
+ end
141
+ end
142
+
143
+ def extract_sign(input)
144
+ result = (input =~ /^-+(.*)$/ || input =~ /^(.*)-+$/) ? [true, $1] : [false, input]
145
+ fail ParseError, 'Invalid amount (hyphen)' if result[1].include?('-')
146
+ result
147
+ end
148
+
149
+ def regex_safe_symbols
150
+ CURRENCY_SYMBOLS.keys.map { |key| Regexp.escape(key) }.join('|')
151
+ end
152
+
153
+ def set_minor_precision(minor, currency)
154
+ if Money.infinite_precision
155
+ (BigDecimal(minor) / (10**minor.size)) * currency.subunit_to_unit
156
+ elsif minor.size < currency.decimal_places
157
+ (minor + ('0' * currency.decimal_places))[0, currency.decimal_places].to_i
158
+ elsif minor.size > currency.decimal_places
159
+ if minor[currency.decimal_places, 1].to_i >= 5
160
+ minor[0, currency.decimal_places].to_i + 1
161
+ else
162
+ minor[0, currency.decimal_places].to_i
163
+ end
164
+ else
165
+ minor.to_i
166
+ end
167
+ end
168
+
169
+ def split_major_minor(num, delimiter)
170
+ major, minor = num.split(delimiter)
171
+ [major, minor || '00']
172
+ end
173
+
174
+ def currency_symbol_regex
175
+ /\A[\+|\-]?(?<symbol>#{regex_safe_symbols})/
176
+ end
177
+ end
178
+ end
@@ -1,5 +1,5 @@
1
1
  # encoding: utf-8
2
2
 
3
3
  module Monetize
4
- VERSION = '1.4.0'
4
+ VERSION = '1.9.1'
5
5
  end
@@ -19,9 +19,15 @@ Gem::Specification.new do |spec|
19
19
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
20
20
  spec.require_paths = ['lib']
21
21
 
22
- spec.add_dependency 'money', '~> 6.7'
22
+ spec.add_dependency 'money', '~> 6.12'
23
23
 
24
- spec.add_development_dependency 'bundler', '~> 1.3'
25
- spec.add_development_dependency 'rake'
26
- spec.add_development_dependency 'rspec', '~> 3.0.0.beta1'
24
+ spec.add_development_dependency 'bundler'
25
+ spec.add_development_dependency 'rake', '~> 10.2'
26
+ spec.add_development_dependency 'rspec', '~> 3.0'
27
+
28
+ if spec.respond_to?(:metadata)
29
+ spec.metadata['changelog_uri'] = 'https://github.com/RubyMoney/monetize/blob/master/CHANGELOG.md'
30
+ spec.metadata['source_code_uri'] = 'https://github.com/RubyMoney/monetize/'
31
+ spec.metadata['bug_tracker_uri'] = 'https://github.com/RubyMoney/monetize/issues'
32
+ end
27
33
  end
@@ -31,7 +31,7 @@ describe Monetize, 'core extensions' do
31
31
  expect(money.cents).to eq 100_37
32
32
  expect(money.currency).to eq Money.default_currency
33
33
 
34
- money = BigDecimal.new('1234').to_money
34
+ money = BigDecimal('1234').to_money
35
35
  expect(money.cents).to eq 1_234_00
36
36
  expect(money.currency).to eq Money.default_currency
37
37
  end
@@ -182,6 +182,14 @@ describe Monetize, 'core extensions' do
182
182
  end
183
183
  end
184
184
 
185
+ context 'when currency argument is a hash' do
186
+ subject(:hash) { {cents: 100, currency: {iso_code: 'EUR'}} }
187
+
188
+ it 'converts Hash to Money using iso_code from currency hash' do
189
+ expect(hash.to_money).to eq(Money.new(100, 'EUR'))
190
+ end
191
+ end
192
+
185
193
  context 'when no currency is passed' do
186
194
  subject(:hash) { {cents: 123} }
187
195
 
@@ -191,6 +199,14 @@ describe Monetize, 'core extensions' do
191
199
  expect(hash.to_money('USD')).to eq(Money.new(123, 'USD'))
192
200
  end
193
201
  end
202
+
203
+ context "when key name is 'fractional'" do
204
+ subject(:hash) { {fractional: 100} }
205
+
206
+ it 'converts Hash to Money, interpreting fractional as cents' do
207
+ expect(hash.to_money).to eq(Money.new(100, 'USD'))
208
+ end
209
+ end
194
210
  end
195
211
  end
196
212
 
@@ -56,76 +56,69 @@ describe Monetize do
56
56
  Monetize.assume_from_symbol = false
57
57
  end
58
58
 
59
- it 'parses formatted inputs with Euros passed as a symbol' do
60
- expect(Monetize.parse('€5.95')).to eq Money.new(595, 'EUR')
61
- end
62
-
63
- it 'parses formatted inputs with Euros passed as a symbol with surrounding space' do
64
- expect(Monetize.parse(' €5.95 ')).to eq Money.new(595, 'EUR')
65
- end
66
-
67
- it 'parses formatted inputs with British Pounds Sterling passed as a symbol' do
68
- expect(Monetize.parse('£9.99')).to eq Money.new(999, 'GBP')
69
- end
70
-
71
- it 'parses formatted inputs with British Pounds Sterling passed as a lira sign symbol' do
72
- expect(Monetize.parse('₤9.99')).to eq Money.new(999, 'GBP')
73
- end
74
-
75
- it 'parses formatted inputs with South African Rand passed as a symbol' do
76
- expect(Monetize.parse('R9.99')).to eq Money.new(999, 'ZAR')
77
- end
78
-
79
- it 'parses formatted inputs with Brazilian real passed as a symbol' do
80
- expect(Monetize.parse('R$R9.99')).to eq Money.new(999, 'BRL')
81
- end
82
-
83
- it 'parses formatted inputs with Japanese Yen passed as a symbol' do
84
- expect(Monetize.parse('¥999')).to eq Money.new(999, 'JPY')
85
- end
86
-
87
- it 'parses formatted inputs with Canadian Dollar passed as a symbol' do
88
- expect(Monetize.parse('C$9.99')).to eq Money.new(999, 'CAD')
59
+ Monetize::Parser::CURRENCY_SYMBOLS.each_pair do |symbol, iso_code|
60
+ context iso_code do
61
+ let(:currency) { Money::Currency.find(iso_code) }
62
+ let(:amount) { 5_95 }
63
+ let(:amount_in_units) { amount.to_f / currency.subunit_to_unit }
64
+
65
+ it 'ensures correct amount calculations for test' do
66
+ expect(amount_in_units * currency.subunit_to_unit).to eq(amount)
67
+ end
68
+
69
+ it "parses formatted inputs with #{iso_code} passed as a symbol" do
70
+ expect(Monetize.parse("#{symbol}#{amount_in_units}")).to eq Money.new(amount, iso_code)
71
+ end
72
+
73
+ context 'prefix' do
74
+ it 'parses formatted inputs with plus sign and currency as a symbol' do
75
+ expect(Monetize.parse("+#{symbol}#{amount_in_units}")).to eq Money.new(amount, iso_code)
76
+ end
77
+
78
+ it 'parses formatted inputs with minus sign and currency as a symbol' do
79
+ expect(Monetize.parse("-#{symbol}#{amount_in_units}")).to eq Money.new(-amount, iso_code)
80
+ end
81
+ end
82
+
83
+ context 'postfix' do
84
+ it 'parses formatted inputs with currency symbol and postfix minus sign' do
85
+ expect(Monetize.parse("#{symbol}#{amount_in_units}-")).to eq Money.new(-amount, iso_code)
86
+ end
87
+
88
+ it 'parses formatted inputs with currency symbol and postfix plus sign' do
89
+ expect(Monetize.parse("#{symbol}#{amount_in_units}+")).to eq Money.new(amount, iso_code)
90
+ end
91
+ end
92
+
93
+ context 'amount suffixes' do
94
+ it 'parses formatted inputs with amounts given with suffixes' do
95
+ expect(Monetize.parse("#{symbol}1.26K")).to eq Money.new(1_260 * currency.subunit_to_unit, iso_code)
96
+ expect(Monetize.parse("#{symbol}126.36M")).to eq Money.new(126_360_000 * currency.subunit_to_unit, iso_code)
97
+ expect(Monetize.parse("#{symbol}.45B")).to eq Money.new(450_000_000 * currency.subunit_to_unit, iso_code)
98
+ expect(Monetize.parse("-#{symbol}2.45B")).to eq Money.new(-2_450_000_000 * currency.subunit_to_unit, iso_code)
99
+ expect(Monetize.parse("#{symbol}1.65T")).to eq Money.new(1_650_000_000_000 * currency.subunit_to_unit, iso_code)
100
+ end
101
+ end
102
+
103
+ it 'parses formatted inputs with symbol and surrounding spaces' do
104
+ expect(Monetize.parse(" #{symbol}#{amount_in_units} ")).to eq Money.new(amount, iso_code)
105
+ end
106
+
107
+ it 'parses formatted inputs without currency detection when overridden' do
108
+ expect(Monetize.parse("#{symbol}5.95", nil, assume_from_symbol: false)).to eq Money.new(amount, 'USD')
109
+ end
110
+ end
89
111
  end
90
112
 
91
113
  it 'should assume default currency if not a recognised symbol' do
92
114
  expect(Monetize.parse('L9.99')).to eq Money.new(999, 'USD')
93
115
  end
94
116
 
95
- it 'parses formatted inputs without currency detection when overridden' do
96
- expect(Monetize.parse('£9.99', nil, assume_from_symbol: false)).to eq Money.new(999, 'USD')
97
- end
98
-
99
- it 'parses formatted inputs with minus sign and currency symbol' do
100
- expect(Monetize.parse('-€9.99')).to eq Money.new(-999, 'EUR')
101
- expect(Monetize.parse('-£9.99')).to eq Money.new(-999, 'GBP')
102
- expect(Monetize.parse('-R$R9.99')).to eq Money.new(-999, 'BRL')
103
- expect(Monetize.parse('-¥999')).to eq Money.new(-999, 'JPY')
104
- expect(Monetize.parse('-C$9.99')).to eq Money.new(-999, 'CAD')
105
- end
106
-
107
- it 'parses formatted inputs with plus and GBP passed as symbol' do
108
- expect(Monetize.parse('+€9.99')).to eq Money.new(999, 'EUR')
109
- expect(Monetize.parse('+£9.99')).to eq Money.new(999, 'GBP')
110
- expect(Monetize.parse('+R$R9.99')).to eq Money.new(999, 'BRL')
111
- expect(Monetize.parse('+¥999')).to eq Money.new(999, 'JPY')
112
- expect(Monetize.parse('+C$9.99')).to eq Money.new(999, 'CAD')
113
- end
114
-
115
- it 'parses formatted inputs with currency symbol and postfix minus sign' do
116
- expect(Monetize.parse('€9.99-')).to eq Money.new(-999, 'EUR')
117
- end
118
-
119
- it 'parses formatted inputs with currency symbol and postfix plus sign' do
120
- expect(Monetize.parse('€9.99+')).to eq Money.new(999, 'EUR')
121
- end
122
-
123
- it 'parses formatted inputs with amounts given with suffixes' do
124
- expect(Monetize.parse('$1.26K')).to eq Money.new(1_260_00, 'USD')
125
- expect(Monetize.parse('$126.36M')).to eq Money.new(126_360_000_00, 'USD')
126
- expect(Monetize.parse('€.45B')).to eq Money.new(450_000_000_00, 'EUR')
127
- expect(Monetize.parse('-$2.45B')).to eq Money.new(-2_450_000_000_00, 'USD')
128
- expect(Monetize.parse('€1.65T')).to eq Money.new(1_650_000_000_000_00, 'EUR')
117
+ context 'negatives' do
118
+ it 'ignores the ambiguous kr symbol' do
119
+ # Could mean either of DKK, EEK, ISK, NOK, SEK
120
+ expect(Monetize.parse('kr9.99')).to eq Money.new(999, 'USD')
121
+ end
129
122
  end
130
123
  end
131
124
 
@@ -158,6 +151,18 @@ describe Monetize do
158
151
  it 'should opt out by default' do
159
152
  expect(Monetize.assume_from_symbol).to be_falsy
160
153
  end
154
+
155
+ context 'ISO code' do
156
+ it 'parses currency given as ISO code' do
157
+ expect('20.00 USD'.to_money).to eq Money.new(20_00, 'USD')
158
+ expect('20.00 EUR'.to_money).to eq Money.new(20_00, 'EUR')
159
+ expect('20.00 GBP'.to_money).to eq Money.new(20_00, 'GBP')
160
+ end
161
+
162
+ it 'raises an error if currency code is invalid' do
163
+ expect { '20.00 OMG'.to_money }.to raise_error Monetize::ParseError
164
+ end
165
+ end
161
166
  end
162
167
 
163
168
  it 'parses USD-formatted inputs under $10' do
@@ -177,10 +182,16 @@ describe Monetize do
177
182
  expect(Monetize.parse('1,111,234,567.89')).to eq Money.new(1_111_234_567_89, 'USD')
178
183
  end
179
184
 
180
- it 'does not return a price if there is a price range' do
181
- expect { Monetize.parse('$5.95-10.95') }.to raise_error ArgumentError
182
- expect { Monetize.parse('$5.95 - 10.95') }.to raise_error ArgumentError
183
- expect { Monetize.parse('$5.95 - $10.95') }.to raise_error ArgumentError
185
+ it 'parses DKK-formatted inputs' do
186
+ expect(Monetize.parse('kr.123,45', 'DKK')).to eq Money.new(123_45, 'DKK')
187
+ expect(Monetize.parse('kr.123.45', 'DKK')).to eq Money.new(123_45, 'DKK')
188
+ expect(Monetize.parse('kr.45k', 'DKK')).to eq Money.new(45_000_00, 'DKK')
189
+ end
190
+
191
+ it 'returns nil if input is a price range' do
192
+ expect(Monetize.parse('$5.95-10.95')).to be_nil
193
+ expect(Monetize.parse('$5.95 - 10.95')).to be_nil
194
+ expect(Monetize.parse('$5.95 - $10.95')).to be_nil
184
195
  end
185
196
 
186
197
  it 'does not return a price for completely invalid input' do
@@ -197,8 +208,16 @@ describe Monetize do
197
208
  expect(Monetize.parse('$5.95-')).to eq five_ninety_five
198
209
  end
199
210
 
200
- it 'raises ArgumentError when unable to detect polarity' do
201
- expect { Monetize.parse('-$5.95-') }.to raise_error ArgumentError
211
+ it 'returns nil when unable to detect polarity' do
212
+ expect(Monetize.parse('-$5.95-')).to be_nil
213
+ end
214
+
215
+ it 'returns nil when more than 2 digit separators are used' do
216
+ expect(Monetize.parse("123.34,56'89 EUR")).to be_nil
217
+ end
218
+
219
+ it 'parses correctly strings with repeated digit separator' do
220
+ expect(Monetize.parse('19.12.89', 'EUR')).to eq Money.new(191_289_00, 'EUR')
202
221
  end
203
222
 
204
223
  it 'parses correctly strings with exactly 3 decimal digits' do
@@ -210,6 +229,32 @@ describe Monetize do
210
229
  Monetize.enforce_currency_delimiters = false
211
230
  end
212
231
 
232
+ context 'Money object attempting to be parsed' do
233
+ let(:money) { Money.new(595, 'GBP') }
234
+
235
+ it 'returns the original Money object' do
236
+ expect(Monetize.parse(money)).to eq money
237
+ expect(Monetize.parse(money).currency).to eq 'GBP'
238
+ expect(Monetize.parse(money).cents).to eq 595
239
+ end
240
+ end
241
+
242
+ context 'parsing an instance of Numeric class' do
243
+ let(:integer) { 10 }
244
+ let(:float) { 10.0 }
245
+ let(:big_decimal) { BigDecimal('10') }
246
+
247
+ [:integer, :float, :big_decimal].each do |type|
248
+ it "returns a new Money object based on the #{type} input" do
249
+ money = Monetize.parse(send(type), 'USD')
250
+
251
+ expect(money).to be_instance_of(Money)
252
+ expect(money.currency).to eq('USD')
253
+ expect(money.cents).to eq(10_00)
254
+ end
255
+ end
256
+ end
257
+
213
258
  context 'custom currencies with 4 decimal places' do
214
259
  before :each do
215
260
  Money::Currency.register(JSON.parse(bar, symbolize_names: true))
@@ -265,6 +310,18 @@ describe Monetize do
265
310
  end
266
311
  end
267
312
 
313
+ describe '.parse!' do
314
+ it 'does not return a price if there is a price range' do
315
+ expect { Monetize.parse!('$5.95-10.95') }.to raise_error Monetize::ParseError
316
+ expect { Monetize.parse!('$5.95 - 10.95') }.to raise_error Monetize::ParseError
317
+ expect { Monetize.parse!('$5.95 - $10.95') }.to raise_error Monetize::ParseError
318
+ end
319
+
320
+ it 'raises ArgumentError when unable to detect polarity' do
321
+ expect { Monetize.parse!('-$5.95-') }.to raise_error Monetize::ParseError
322
+ end
323
+ end
324
+
268
325
  describe '.parse_collection' do
269
326
  it 'parses into a Money::Collection' do
270
327
  expect(Monetize.parse_collection('$7')).to be_a Monetize::Collection
@@ -287,6 +344,10 @@ describe Monetize do
287
344
  expect(collection.first).to eq Monetize.parse('$4')
288
345
  expect(collection.last).to eq Monetize.parse('$10')
289
346
  end
347
+
348
+ it 'raises an error if argument is invalid' do
349
+ expect { Monetize.parse_collection(nil) }.to raise_error Monetize::ArgumentError
350
+ end
290
351
  end
291
352
 
292
353
  describe '.from_string' do
@@ -337,6 +398,10 @@ describe Monetize do
337
398
  m = Monetize.from_fixnum(1, 'EUR')
338
399
  expect(m.currency).to eq Money::Currency.wrap('EUR')
339
400
  end
401
+
402
+ it 'is aliased as from_integer' do
403
+ expect(Monetize.from_integer(1)).to eq(Monetize.from_fixnum(1))
404
+ end
340
405
  end
341
406
 
342
407
  describe '.from_float' do
@@ -366,25 +431,31 @@ describe Monetize do
366
431
 
367
432
  describe '.from_bigdecimal' do
368
433
  it 'converts given amount to cents' do
369
- expect(Monetize.from_bigdecimal(BigDecimal.new('1'))).to eq Money.new(1_00)
370
- expect(Monetize.from_bigdecimal(BigDecimal.new('1'))).to eq Money.new(1_00, 'USD')
371
- expect(Monetize.from_bigdecimal(BigDecimal.new('1'), 'EUR')).to eq Money.new(1_00, 'EUR')
434
+ expect(Monetize.from_bigdecimal(BigDecimal('1'))).to eq Money.new(1_00)
435
+ expect(Monetize.from_bigdecimal(BigDecimal('1'))).to eq Money.new(1_00, 'USD')
436
+ expect(Monetize.from_bigdecimal(BigDecimal('1'), 'EUR')).to eq Money.new(1_00, 'EUR')
372
437
  end
373
438
 
374
439
  it 'respects :subunit_to_unit currency property' do
375
- expect(Monetize.from_bigdecimal(BigDecimal.new('1'), 'USD')).to eq Money.new(1_00, 'USD')
376
- expect(Monetize.from_bigdecimal(BigDecimal.new('1'), 'TND')).to eq Money.new(1_000, 'TND')
377
- expect(Monetize.from_bigdecimal(BigDecimal.new('1'), 'JPY')).to eq Money.new(1, 'JPY')
440
+ expect(Monetize.from_bigdecimal(BigDecimal('1'), 'USD')).to eq Money.new(1_00, 'USD')
441
+ expect(Monetize.from_bigdecimal(BigDecimal('1'), 'TND')).to eq Money.new(1_000, 'TND')
442
+ expect(Monetize.from_bigdecimal(BigDecimal('1'), 'JPY')).to eq Money.new(1, 'JPY')
443
+ end
444
+
445
+ it 'respects rounding mode when rounding amount to the nearest cent' do
446
+ amount = BigDecimal('1.005')
447
+
448
+ expect(Monetize.from_bigdecimal(amount, 'USD')).to eq Money.from_amount(amount, 'USD')
378
449
  end
379
450
 
380
451
  it 'accepts a currency options' do
381
- m = Monetize.from_bigdecimal(BigDecimal.new('1'))
452
+ m = Monetize.from_bigdecimal(BigDecimal('1'))
382
453
  expect(m.currency).to eq Money.default_currency
383
454
 
384
- m = Monetize.from_bigdecimal(BigDecimal.new('1'), Money::Currency.wrap('EUR'))
455
+ m = Monetize.from_bigdecimal(BigDecimal('1'), Money::Currency.wrap('EUR'))
385
456
  expect(m.currency).to eq Money::Currency.wrap('EUR')
386
457
 
387
- m = Monetize.from_bigdecimal(BigDecimal.new('1'), 'EUR')
458
+ m = Monetize.from_bigdecimal(BigDecimal('1'), 'EUR')
388
459
  expect(m.currency).to eq Money::Currency.wrap('EUR')
389
460
  end
390
461
 
@@ -398,11 +469,11 @@ describe Monetize do
398
469
  end
399
470
 
400
471
  it 'keeps precision' do
401
- expect(Monetize.from_bigdecimal(BigDecimal.new('1'))).to eq Money.new(100)
402
- expect(Monetize.from_bigdecimal(BigDecimal.new('1.23456'))).to eq Money.new(123.456)
403
- expect(Monetize.from_bigdecimal(BigDecimal.new('-1.23456'))).to eq Money.new(-123.456)
404
- expect(Monetize.from_bigdecimal(BigDecimal.new('1.23456'))).to eq Money.new(123.456, 'USD')
405
- expect(Monetize.from_bigdecimal(BigDecimal.new('1.23456'), 'EUR')).to eq Money.new(123.456, 'EUR')
472
+ expect(Monetize.from_bigdecimal(BigDecimal('1'))).to eq Money.new(100)
473
+ expect(Monetize.from_bigdecimal(BigDecimal('1.23456'))).to eq Money.new(123.456)
474
+ expect(Monetize.from_bigdecimal(BigDecimal('-1.23456'))).to eq Money.new(-123.456)
475
+ expect(Monetize.from_bigdecimal(BigDecimal('1.23456'))).to eq Money.new(123.456, 'USD')
476
+ expect(Monetize.from_bigdecimal(BigDecimal('1.23456'), 'EUR')).to eq Money.new(123.456, 'EUR')
406
477
 
407
478
  expect('1'.to_money).to eq Money.new(100)
408
479
  expect('1.23456'.to_money).to eq Money.new(123.456)
@@ -417,19 +488,11 @@ describe Monetize do
417
488
  it 'converts given amount to cents' do
418
489
  expect(Monetize.from_numeric(1)).to eq Money.new(1_00)
419
490
  expect(Monetize.from_numeric(1.0)).to eq Money.new(1_00)
420
- expect(Monetize.from_numeric(BigDecimal.new('1'))).to eq Money.new(1_00)
491
+ expect(Monetize.from_numeric(BigDecimal('1'))).to eq Money.new(1_00)
421
492
  end
422
493
 
423
494
  it 'raises ArgumentError with unsupported argument' do
424
- expect { Monetize.from_numeric('100') }.to raise_error(ArgumentError)
425
- end
426
-
427
- it 'optimizes workload' do
428
- expect(Monetize).to receive(:from_fixnum).with(1, 'USD').and_return(Money.new(1_00, 'USD'))
429
- expect(Monetize.from_numeric(1, 'USD')).to eq Money.new(1_00, 'USD')
430
- expect(Monetize).to receive(:from_bigdecimal).with(BigDecimal.new('1.0'), 'USD').
431
- and_return(Money.new(1_00, 'USD'))
432
- expect(Monetize.from_numeric(1.0, 'USD')).to eq Money.new(1_00, 'USD')
495
+ expect { Monetize.from_numeric('100') }.to raise_error(Monetize::ArgumentError)
433
496
  end
434
497
 
435
498
  it 'respects :subunit_to_unit currency property' do
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: monetize
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.4.0
4
+ version: 1.9.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Shane Emmons
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-01-15 00:00:00.000000000 Z
11
+ date: 2019-02-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: money
@@ -16,56 +16,56 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '6.7'
19
+ version: '6.12'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '6.7'
26
+ version: '6.12'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: bundler
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - "~>"
31
+ - - ">="
32
32
  - !ruby/object:Gem::Version
33
- version: '1.3'
33
+ version: '0'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - "~>"
38
+ - - ">="
39
39
  - !ruby/object:Gem::Version
40
- version: '1.3'
40
+ version: '0'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: rake
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - ">="
45
+ - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: '0'
47
+ version: '10.2'
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - ">="
52
+ - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: '0'
54
+ version: '10.2'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: rspec
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
59
  - - "~>"
60
60
  - !ruby/object:Gem::Version
61
- version: 3.0.0.beta1
61
+ version: '3.0'
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
- version: 3.0.0.beta1
68
+ version: '3.0'
69
69
  description: A library for converting various objects into `Money` objects.
70
70
  email:
71
71
  - shane@emmons.io
@@ -83,14 +83,16 @@ files:
83
83
  - LICENSE.txt
84
84
  - README.md
85
85
  - Rakefile
86
- - lib/collection.rb
87
86
  - lib/monetize.rb
87
+ - lib/monetize/collection.rb
88
88
  - lib/monetize/core_extensions.rb
89
89
  - lib/monetize/core_extensions/hash.rb
90
90
  - lib/monetize/core_extensions/nil_class.rb
91
91
  - lib/monetize/core_extensions/numeric.rb
92
92
  - lib/monetize/core_extensions/string.rb
93
93
  - lib/monetize/core_extensions/symbol.rb
94
+ - lib/monetize/errors.rb
95
+ - lib/monetize/parser.rb
94
96
  - lib/monetize/version.rb
95
97
  - monetize.gemspec
96
98
  - spec/core_extensions_spec.rb
@@ -99,7 +101,10 @@ files:
99
101
  homepage: https://github.com/RubyMoney/monetize
100
102
  licenses:
101
103
  - MIT
102
- metadata: {}
104
+ metadata:
105
+ changelog_uri: https://github.com/RubyMoney/monetize/blob/master/CHANGELOG.md
106
+ source_code_uri: https://github.com/RubyMoney/monetize/
107
+ bug_tracker_uri: https://github.com/RubyMoney/monetize/issues
103
108
  post_install_message:
104
109
  rdoc_options: []
105
110
  require_paths:
@@ -116,7 +121,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
116
121
  version: '0'
117
122
  requirements: []
118
123
  rubyforge_project:
119
- rubygems_version: 2.4.5.1
124
+ rubygems_version: 2.6.8
120
125
  signing_key:
121
126
  specification_version: 4
122
127
  summary: A library for converting various objects into `Money` objects.
@@ -124,4 +129,3 @@ test_files:
124
129
  - spec/core_extensions_spec.rb
125
130
  - spec/monetize_spec.rb
126
131
  - spec/spec_helper.rb
127
- has_rdoc: