monetize 1.12.0 → 1.13.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.
- checksums.yaml +4 -4
- data/.github/workflows/ruby.yml +2 -2
- data/LICENSE +1 -1
- data/README.md +18 -6
- data/lib/monetize/parser.rb +30 -6
- data/lib/monetize/version.rb +1 -1
- data/lib/monetize.rb +6 -0
- data/spec/monetize_spec.rb +48 -2
- metadata +3 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 07adb2e223118b56f5944a6b90b8c51901df761f6b5ecebea8fd8ee8dea3343e
|
|
4
|
+
data.tar.gz: a61b3fda9d0c22fefb028043db74625c91083787068b31ecf639a05286f92cff
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 6d4774d81cc075b5c68849cd07c69f2311683f16adfbb00075d85e7530f4a1cb052a82a1b772b812b9b029fbe47b8b4400aabb0588ce27a35ef6e9d6340122cb
|
|
7
|
+
data.tar.gz: c5e7266b20bf556a2619974f8d97a690e6817eec1a56e9cd0497c6569bc36c681fc417c19900fa95c1ae7fcf7c10569867bec072d4a25e8c99d6f49c0b9901e1
|
data/.github/workflows/ruby.yml
CHANGED
|
@@ -19,10 +19,10 @@ jobs:
|
|
|
19
19
|
runs-on: ubuntu-latest
|
|
20
20
|
strategy:
|
|
21
21
|
matrix:
|
|
22
|
-
ruby-version: ['2.6', '2.7', '3.0']
|
|
22
|
+
ruby-version: ['2.6', '2.7', '3.0', '3.1', '3.2']
|
|
23
23
|
|
|
24
24
|
steps:
|
|
25
|
-
- uses: actions/checkout@
|
|
25
|
+
- uses: actions/checkout@v3
|
|
26
26
|
- name: Set up Ruby
|
|
27
27
|
# To automatically get bug fixes and new Ruby versions for ruby/setup-ruby,
|
|
28
28
|
# change this to (see https://github.com/ruby/setup-ruby#versioning):
|
data/LICENSE
CHANGED
data/README.md
CHANGED
|
@@ -10,13 +10,9 @@ A library for converting various objects into `Money` objects.
|
|
|
10
10
|
|
|
11
11
|
## Installation
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
Run:
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
And then execute:
|
|
18
|
-
|
|
19
|
-
$ bundle
|
|
15
|
+
bundle add monetize
|
|
20
16
|
|
|
21
17
|
Or install it yourself as:
|
|
22
18
|
|
|
@@ -53,6 +49,22 @@ Monetize.parse("£100") == Money.new(100_00, "GBP")
|
|
|
53
49
|
"€100".to_money == Money.new(100_00, "EUR")
|
|
54
50
|
```
|
|
55
51
|
|
|
52
|
+
Parsing can be improved where the input is not expected to contain fractonal subunits.
|
|
53
|
+
To do this, set `Monetize.expect_whole_subunits = true`
|
|
54
|
+
|
|
55
|
+
```ruby
|
|
56
|
+
Monetize.parse('EUR 10,000') == Money.new(100_00, "EUR")
|
|
57
|
+
|
|
58
|
+
Monetize.expect_whole_subunits = true
|
|
59
|
+
Monetize.parse('EUR 10,000') == Money.new(10_000_00, "EUR")
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
Why does this work? If we expect fractional subunits then the parser will treat a single
|
|
63
|
+
delimiter as a decimal marker if it matches the currency's decimal marker. But often
|
|
64
|
+
this is not the case - a European site will show $10.000 because that's the local format.
|
|
65
|
+
As a human, if this was a stock ticker we might expect fractional cents. If it's a retail price we know it's actually an incorrect thousands separator.
|
|
66
|
+
|
|
67
|
+
|
|
56
68
|
Monetize can also parse a list of values, returning an array-like object ([Monetize::Collection](lib/collection.rb)):
|
|
57
69
|
|
|
58
70
|
```ruby
|
data/lib/monetize/parser.rb
CHANGED
|
@@ -8,6 +8,8 @@ module Monetize
|
|
|
8
8
|
'£' => 'GBP',
|
|
9
9
|
'₤' => 'GBP',
|
|
10
10
|
'R$' => 'BRL',
|
|
11
|
+
'RM' => 'MYR',
|
|
12
|
+
'Rp' => 'IDR',
|
|
11
13
|
'R' => 'ZAR',
|
|
12
14
|
'¥' => 'JPY',
|
|
13
15
|
'C$' => 'CAD',
|
|
@@ -23,6 +25,10 @@ module Monetize
|
|
|
23
25
|
'zł' => 'PLN',
|
|
24
26
|
'₸' => 'KZT',
|
|
25
27
|
"₩" => 'KRW',
|
|
28
|
+
'S$' => 'SGD',
|
|
29
|
+
'HK$'=> 'HKD',
|
|
30
|
+
'NT$'=> 'TWD',
|
|
31
|
+
'₱' => 'PHP',
|
|
26
32
|
}
|
|
27
33
|
|
|
28
34
|
MULTIPLIER_SUFFIXES = { 'K' => 3, 'M' => 6, 'B' => 9, 'T' => 12 }
|
|
@@ -70,6 +76,7 @@ module Monetize
|
|
|
70
76
|
def parse_currency
|
|
71
77
|
computed_currency = nil
|
|
72
78
|
computed_currency = input[/[A-Z]{2,3}/]
|
|
79
|
+
computed_currency = nil unless Monetize::Parser::CURRENCY_SYMBOLS.value?(computed_currency)
|
|
73
80
|
computed_currency ||= compute_currency if assume_from_symbol?
|
|
74
81
|
|
|
75
82
|
|
|
@@ -80,6 +87,10 @@ module Monetize
|
|
|
80
87
|
options.fetch(:assume_from_symbol) { Monetize.assume_from_symbol }
|
|
81
88
|
end
|
|
82
89
|
|
|
90
|
+
def expect_whole_subunits?
|
|
91
|
+
options.fetch(:expect_whole_subunits) { Monetize.expect_whole_subunits }
|
|
92
|
+
end
|
|
93
|
+
|
|
83
94
|
def apply_multiplier(multiplier_exp, amount)
|
|
84
95
|
amount * 10**multiplier_exp
|
|
85
96
|
end
|
|
@@ -109,13 +120,26 @@ module Monetize
|
|
|
109
120
|
end
|
|
110
121
|
end
|
|
111
122
|
|
|
123
|
+
def minor_has_correct_dp_for_currency_subunit?(minor, currency)
|
|
124
|
+
minor.length == currency.subunit_to_unit.to_s.length - 1
|
|
125
|
+
end
|
|
126
|
+
|
|
112
127
|
def extract_major_minor_with_single_delimiter(num, currency, delimiter)
|
|
113
|
-
if
|
|
114
|
-
split_major_minor(num, delimiter)
|
|
115
|
-
|
|
116
|
-
|
|
128
|
+
if expect_whole_subunits?
|
|
129
|
+
possible_major, possible_minor = split_major_minor(num, delimiter)
|
|
130
|
+
if minor_has_correct_dp_for_currency_subunit?(possible_minor, currency)
|
|
131
|
+
split_major_minor(num, delimiter)
|
|
132
|
+
else
|
|
133
|
+
extract_major_minor_with_tentative_delimiter(num, delimiter)
|
|
134
|
+
end
|
|
117
135
|
else
|
|
118
|
-
|
|
136
|
+
if delimiter == currency.decimal_mark
|
|
137
|
+
split_major_minor(num, delimiter)
|
|
138
|
+
elsif Monetize.enforce_currency_delimiters && delimiter == currency.thousands_separator
|
|
139
|
+
[num.gsub(delimiter, ''), 0]
|
|
140
|
+
else
|
|
141
|
+
extract_major_minor_with_tentative_delimiter(num, delimiter)
|
|
142
|
+
end
|
|
119
143
|
end
|
|
120
144
|
end
|
|
121
145
|
|
|
@@ -130,7 +154,7 @@ module Monetize
|
|
|
130
154
|
is_decimal_mark = possible_minor.length != 3 ||
|
|
131
155
|
possible_major.length > 3 ||
|
|
132
156
|
possible_major.to_i == 0 ||
|
|
133
|
-
delimiter == '.'
|
|
157
|
+
(!expect_whole_subunits? && delimiter == '.')
|
|
134
158
|
|
|
135
159
|
if is_decimal_mark
|
|
136
160
|
[possible_major, possible_minor]
|
data/lib/monetize/version.rb
CHANGED
data/lib/monetize.rb
CHANGED
|
@@ -20,6 +20,12 @@ module Monetize
|
|
|
20
20
|
# to true to enforce the delimiters set in the currency all the time.
|
|
21
21
|
attr_accessor :enforce_currency_delimiters
|
|
22
22
|
|
|
23
|
+
|
|
24
|
+
# Where this set to true, the behavior for parsing thousands separators is changed to
|
|
25
|
+
# expect that eg. €10.000 is EUR 10 000 and not EUR 10.000 - it's incredibly rare when parsing
|
|
26
|
+
# human text that we're dealing with fractions of cents.
|
|
27
|
+
attr_accessor :expect_whole_subunits
|
|
28
|
+
|
|
23
29
|
def parse(input, currency = Money.default_currency, options = {})
|
|
24
30
|
parse! input, currency, options
|
|
25
31
|
rescue Error
|
data/spec/monetize_spec.rb
CHANGED
|
@@ -172,8 +172,28 @@ describe Monetize do
|
|
|
172
172
|
expect('20.00 GBP'.to_money).to eq Money.new(20_00, 'GBP')
|
|
173
173
|
end
|
|
174
174
|
|
|
175
|
-
|
|
176
|
-
|
|
175
|
+
context 'with default currency' do
|
|
176
|
+
before do
|
|
177
|
+
Money.default_currency = Money::Currency.new('USD')
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
it 'parses currency given using default currency' do
|
|
181
|
+
expect('20.00 OMG'.to_money).to eq Money.new(20_00, 'USD')
|
|
182
|
+
end
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
context 'without default currency' do
|
|
186
|
+
before do
|
|
187
|
+
Money.default_currency = nil
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
after do
|
|
191
|
+
Money.default_currency = Money::Currency.new('USD')
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
it 'raises an error if currency code is invalid' do
|
|
195
|
+
expect { '20.00 OMG'.to_money }.to raise_error
|
|
196
|
+
end
|
|
177
197
|
end
|
|
178
198
|
end
|
|
179
199
|
end
|
|
@@ -344,6 +364,32 @@ describe Monetize do
|
|
|
344
364
|
expect('€0.5324'.to_money('EU4')).to eq Money.new(5324, 'EU4')
|
|
345
365
|
end
|
|
346
366
|
end
|
|
367
|
+
|
|
368
|
+
describe "expecting whole subunits" do
|
|
369
|
+
before(:all) do
|
|
370
|
+
Monetize.expect_whole_subunits = true
|
|
371
|
+
Monetize.assume_from_symbol = true
|
|
372
|
+
end
|
|
373
|
+
|
|
374
|
+
after(:all) do
|
|
375
|
+
Monetize.expect_whole_subunits = false
|
|
376
|
+
Monetize.assume_from_symbol = false
|
|
377
|
+
end
|
|
378
|
+
|
|
379
|
+
it "handles euros" do
|
|
380
|
+
expect(Monetize.parse('€10,000')).to eq Money.new(10_000_00, 'EUR')
|
|
381
|
+
expect(Monetize.parse('€10,00')).to eq Money.new(10_00, 'EUR')
|
|
382
|
+
expect(Monetize.parse('€10.00')).to eq Money.new(10_00, 'EUR')
|
|
383
|
+
expect(Monetize.parse('EUR 10,000.00')).to eq Money.new(10_000_00, 'EUR')
|
|
384
|
+
end
|
|
385
|
+
|
|
386
|
+
it "handles GBP" do
|
|
387
|
+
expect(Monetize.parse('£10,000')).to eq Money.new(10_000_00, 'GBP')
|
|
388
|
+
expect(Monetize.parse('£10.000')).to eq Money.new(10_000_00, 'GBP')
|
|
389
|
+
expect(Monetize.parse('£10,00')).to eq Money.new(10_00, 'GBP')
|
|
390
|
+
expect(Monetize.parse('£10.00')).to eq Money.new(10_00, 'GBP')
|
|
391
|
+
end
|
|
392
|
+
end
|
|
347
393
|
end
|
|
348
394
|
|
|
349
395
|
describe '.parse!' do
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: monetize
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.13.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Shane Emmons
|
|
@@ -9,7 +9,7 @@ authors:
|
|
|
9
9
|
autorequire:
|
|
10
10
|
bindir: bin
|
|
11
11
|
cert_chain: []
|
|
12
|
-
date:
|
|
12
|
+
date: 2024-01-29 00:00:00.000000000 Z
|
|
13
13
|
dependencies:
|
|
14
14
|
- !ruby/object:Gem::Dependency
|
|
15
15
|
name: money
|
|
@@ -121,7 +121,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
121
121
|
- !ruby/object:Gem::Version
|
|
122
122
|
version: '0'
|
|
123
123
|
requirements: []
|
|
124
|
-
rubygems_version: 3.
|
|
124
|
+
rubygems_version: 3.5.3
|
|
125
125
|
signing_key:
|
|
126
126
|
specification_version: 4
|
|
127
127
|
summary: A library for converting various objects into `Money` objects.
|