money 6.8.4 → 6.9.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/CHANGELOG.md +3 -0
- data/README.md +4 -0
- data/lib/money.rb +0 -13
- data/lib/money/currency/heuristics.rb +1 -144
- data/lib/money/version.rb +1 -1
- data/money.gemspec +0 -1
- data/spec/currency/heuristics_spec.rb +2 -153
- metadata +2 -22
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: f268faeee9a1901f8a4e482e8497370697eb436a
|
|
4
|
+
data.tar.gz: 54f37ca793f33929f7c1dd10de33d58c813495fe
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: b9d33bfe048a6ba6fe92391ac9223a92268f31bd6c1f0ef932f2d202fd3a45e7df013c5c96d5ac99b98aacde1ece7a905fda77949aa9e4ad7625698b16b5914f
|
|
7
|
+
data.tar.gz: b3b255302aec3569a1b7e1b4dc5a7e1a77b1b4129c09eb65f295461eadc48cc342f09de81236a229a6d4139a5038069108fdc53660d09255c9d3fa1130d22a02
|
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
|
@@ -435,6 +435,10 @@ m = Money.new('123', :gbp) # => #<Money fractional:123 currency:GBP>
|
|
|
435
435
|
m.format( symbol: m.currency.to_s + ' ') # => "GBP 1.23"
|
|
436
436
|
```
|
|
437
437
|
|
|
438
|
+
## Heuristics
|
|
439
|
+
|
|
440
|
+
Prior to v6.9.0 heuristic analysis of string input was part of this gem. Since then it was extracted in to [money-heuristics gem](https://github.com/RubyMoney/money-heuristics).
|
|
441
|
+
|
|
438
442
|
## Migration Notes
|
|
439
443
|
|
|
440
444
|
#### Version 6.0.0
|
data/lib/money.rb
CHANGED
|
@@ -2,18 +2,5 @@ require "bigdecimal"
|
|
|
2
2
|
require "bigdecimal/util"
|
|
3
3
|
require "set"
|
|
4
4
|
require "i18n"
|
|
5
|
-
require "sixarm_ruby_unaccent"
|
|
6
5
|
require "money/currency"
|
|
7
6
|
require "money/money"
|
|
8
|
-
|
|
9
|
-
# Overwrites unaccent method of sixarm_ruby_unaccent.
|
|
10
|
-
class String
|
|
11
|
-
def unaccent
|
|
12
|
-
accentmap = ACCENTMAP
|
|
13
|
-
accentmap.delete("\u{0142}") # Delete ł symbol from ACCENTMAP used in PLN currency
|
|
14
|
-
accentmap.delete("\u{010D}") # Delete č symbol from ACCENTMAP used in CZK currency
|
|
15
|
-
accentmap.delete("\u{FDFC}") # Delete ﷼ symbol from ACCENTMAP used in IRR, SAR and YER currencies
|
|
16
|
-
accentmap.delete("\u{20A8}") # Delete ₨ symbol from ACCENTMAP used in INR, LKR, MUR, NPR, PKR and SCR currencies
|
|
17
|
-
split(//u).map {|c| accentmap[c] || c }.join("")
|
|
18
|
-
end
|
|
19
|
-
end
|
|
@@ -3,152 +3,9 @@
|
|
|
3
3
|
class Money
|
|
4
4
|
class Currency
|
|
5
5
|
module Heuristics
|
|
6
|
-
|
|
7
|
-
# An robust and efficient algorithm for finding currencies in
|
|
8
|
-
# text. Using several algorithms it can find symbols, iso codes and
|
|
9
|
-
# even names of currencies.
|
|
10
|
-
# Although not recommendable, it can also attempt to find the given
|
|
11
|
-
# currency in an entire sentence
|
|
12
|
-
#
|
|
13
|
-
# Returns: Array (matched results)
|
|
14
6
|
def analyze(str)
|
|
15
|
-
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
private
|
|
19
|
-
|
|
20
|
-
# Build a search tree from the currency database
|
|
21
|
-
def search_tree
|
|
22
|
-
@_search_tree ||= {
|
|
23
|
-
:by_symbol => currencies_by_symbol,
|
|
24
|
-
:by_iso_code => currencies_by_iso_code,
|
|
25
|
-
:by_name => currencies_by_name
|
|
26
|
-
}
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
def currencies_by_symbol
|
|
30
|
-
{}.tap do |r|
|
|
31
|
-
table.each do |dummy, c|
|
|
32
|
-
symbol = (c[:symbol]||"").downcase
|
|
33
|
-
symbol.chomp!('.')
|
|
34
|
-
(r[symbol] ||= []) << c
|
|
35
|
-
|
|
36
|
-
(c[:alternate_symbols]||[]).each do |ac|
|
|
37
|
-
ac = ac.downcase
|
|
38
|
-
ac.chomp!('.')
|
|
39
|
-
(r[ac] ||= []) << c
|
|
40
|
-
end
|
|
41
|
-
end
|
|
42
|
-
end
|
|
43
|
-
end
|
|
44
|
-
|
|
45
|
-
def currencies_by_iso_code
|
|
46
|
-
{}.tap do |r|
|
|
47
|
-
table.each do |dummy,c|
|
|
48
|
-
(r[c[:iso_code].downcase] ||= []) << c
|
|
49
|
-
end
|
|
50
|
-
end
|
|
51
|
-
end
|
|
52
|
-
|
|
53
|
-
def currencies_by_name
|
|
54
|
-
{}.tap do |r|
|
|
55
|
-
table.each do |dummy,c|
|
|
56
|
-
name_parts = c[:name].unaccent.downcase.split
|
|
57
|
-
name_parts.each {|part| part.chomp!('.')}
|
|
58
|
-
|
|
59
|
-
# construct one branch per word
|
|
60
|
-
root = r
|
|
61
|
-
while name_part = name_parts.shift
|
|
62
|
-
root = (root[name_part] ||= {})
|
|
63
|
-
end
|
|
64
|
-
|
|
65
|
-
# the leaf is a currency
|
|
66
|
-
(root[:value] ||= []) << c
|
|
67
|
-
end
|
|
68
|
-
end
|
|
69
|
-
end
|
|
70
|
-
|
|
71
|
-
class Analyzer
|
|
72
|
-
attr_reader :search_tree, :words
|
|
73
|
-
attr_accessor :str, :currencies
|
|
74
|
-
|
|
75
|
-
def initialize str, search_tree
|
|
76
|
-
@str = (str||'').dup
|
|
77
|
-
@search_tree = search_tree
|
|
78
|
-
@currencies = []
|
|
79
|
-
end
|
|
80
|
-
|
|
81
|
-
def process
|
|
82
|
-
format
|
|
83
|
-
return [] if str.empty?
|
|
84
|
-
|
|
85
|
-
search_by_symbol
|
|
86
|
-
search_by_iso_code
|
|
87
|
-
search_by_name
|
|
88
|
-
|
|
89
|
-
prepare_reply
|
|
90
|
-
end
|
|
91
|
-
|
|
92
|
-
def format
|
|
93
|
-
str.gsub!(/[\r\n\t]/,'')
|
|
94
|
-
str.gsub!(/[0-9][\.,:0-9]*[0-9]/,'')
|
|
95
|
-
str.gsub!(/[0-9]/, '')
|
|
96
|
-
str.downcase!
|
|
97
|
-
@words = str.unaccent.split
|
|
98
|
-
@words.each {|word| word.chomp!('.'); word.chomp!(',') }
|
|
99
|
-
end
|
|
100
|
-
|
|
101
|
-
def search_by_symbol
|
|
102
|
-
words.each do |word|
|
|
103
|
-
if found = search_tree[:by_symbol][word]
|
|
104
|
-
currencies.concat(found)
|
|
105
|
-
end
|
|
106
|
-
end
|
|
107
|
-
end
|
|
108
|
-
|
|
109
|
-
def search_by_iso_code
|
|
110
|
-
words.each do |word|
|
|
111
|
-
if found = search_tree[:by_iso_code][word]
|
|
112
|
-
currencies.concat(found)
|
|
113
|
-
end
|
|
114
|
-
end
|
|
115
|
-
end
|
|
116
|
-
|
|
117
|
-
def search_by_name
|
|
118
|
-
# remember, the search tree by name is a construct of branches and leaf!
|
|
119
|
-
# We need to try every combination of words within the sentence, so we
|
|
120
|
-
# end up with a x^2 equation, which should be fine as most names are either
|
|
121
|
-
# one or two words, and this is multiplied with the words of given sentence
|
|
122
|
-
|
|
123
|
-
search_words = words.dup
|
|
124
|
-
|
|
125
|
-
while search_words.length > 0
|
|
126
|
-
root = search_tree[:by_name]
|
|
127
|
-
|
|
128
|
-
search_words.each do |word|
|
|
129
|
-
if root = root[word]
|
|
130
|
-
if root[:value]
|
|
131
|
-
currencies.concat(root[:value])
|
|
132
|
-
end
|
|
133
|
-
else
|
|
134
|
-
break
|
|
135
|
-
end
|
|
136
|
-
end
|
|
137
|
-
|
|
138
|
-
search_words.delete_at(0)
|
|
139
|
-
end
|
|
140
|
-
end
|
|
141
|
-
|
|
142
|
-
def prepare_reply
|
|
143
|
-
codes = currencies.map do |currency|
|
|
144
|
-
currency[:iso_code]
|
|
145
|
-
end
|
|
146
|
-
codes.uniq!
|
|
147
|
-
codes.sort!
|
|
148
|
-
codes
|
|
149
|
-
end
|
|
7
|
+
raise StandardError, 'Heuristics deprecated, add `gem "money-heuristics"` to Gemfile'
|
|
150
8
|
end
|
|
151
9
|
end
|
|
152
10
|
end
|
|
153
11
|
end
|
|
154
|
-
|
data/lib/money/version.rb
CHANGED
data/money.gemspec
CHANGED
|
@@ -4,159 +4,8 @@ describe Money::Currency::Heuristics do
|
|
|
4
4
|
describe "#analyze_string" do
|
|
5
5
|
let(:it) { Money::Currency }
|
|
6
6
|
|
|
7
|
-
it "
|
|
8
|
-
expect
|
|
9
|
-
expect(it.analyze('\n123 \t')).to eq []
|
|
10
|
-
end
|
|
11
|
-
|
|
12
|
-
it "returns nothing when given nothing" do
|
|
13
|
-
expect(it.analyze('')).to eq []
|
|
14
|
-
expect(it.analyze(nil)).to eq []
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
it "finds a currency by use of its symbol" do
|
|
18
|
-
expect(it.analyze('zł')).to eq ['PLN']
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
it "is not affected by trailing dot" do
|
|
22
|
-
expect(it.analyze('zł.')).to eq ['PLN']
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
it "finds match even if has numbers after" do
|
|
26
|
-
expect(it.analyze('zł 123')).to eq ['PLN']
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
it "finds match even if has numbers before" do
|
|
30
|
-
expect(it.analyze('123 zł')).to eq ['PLN']
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
it "find match even if symbol is next to number" do
|
|
34
|
-
expect(it.analyze('300zł')).to eq ['PLN']
|
|
35
|
-
end
|
|
36
|
-
|
|
37
|
-
it "finds match even if has numbers with delimiters" do
|
|
38
|
-
expect(it.analyze('zł 123,000.50')).to eq ['PLN']
|
|
39
|
-
expect(it.analyze('zł123,000.50')).to eq ['PLN']
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
it "finds currencies with dots in symbols" do
|
|
43
|
-
expect(it.analyze('L.E.')).to eq ['EGP']
|
|
44
|
-
end
|
|
45
|
-
|
|
46
|
-
it "finds by name" do
|
|
47
|
-
expect(it.analyze('1900 bulgarian lev')).to eq ['BGN']
|
|
48
|
-
expect(it.analyze('Swedish Krona')).to eq ['SEK']
|
|
49
|
-
end
|
|
50
|
-
|
|
51
|
-
it "Finds several currencies when several match" do
|
|
52
|
-
r = it.analyze('$400')
|
|
53
|
-
expect(r).to include("ARS")
|
|
54
|
-
expect(r).to include("USD")
|
|
55
|
-
expect(r).to include("NZD")
|
|
56
|
-
|
|
57
|
-
r = it.analyze('9000 £')
|
|
58
|
-
expect(r).to include("GBP")
|
|
59
|
-
expect(r).to include("SHP")
|
|
60
|
-
expect(r).to include("SYP")
|
|
61
|
-
end
|
|
62
|
-
|
|
63
|
-
it "should use alternate symbols" do
|
|
64
|
-
expect(it.analyze('US$')).to eq ['USD']
|
|
65
|
-
end
|
|
66
|
-
|
|
67
|
-
it "finds a currency by use of its iso code" do
|
|
68
|
-
expect(it.analyze('USD 200')).to eq ['USD']
|
|
69
|
-
end
|
|
70
|
-
|
|
71
|
-
it "finds currencies in the middle of a sentence!" do
|
|
72
|
-
expect(it.analyze('It would be nice to have 10000 Albanian lek by tomorrow!')).to eq ['ALL']
|
|
73
|
-
end
|
|
74
|
-
|
|
75
|
-
it "finds several currencies in the same text!" do
|
|
76
|
-
expect(it.analyze("10EUR is less than 100:- but really, I want US$1")).to eq ['EUR', 'SEK', 'USD']
|
|
77
|
-
end
|
|
78
|
-
|
|
79
|
-
it "find currencies with normal characters in name using unaccent" do
|
|
80
|
-
expect(it.analyze("10 Nicaraguan Cordoba")).to eq ["NIO"]
|
|
81
|
-
end
|
|
82
|
-
|
|
83
|
-
it "find currencies with special characters in name using unaccent" do
|
|
84
|
-
expect(it.analyze("10 Nicaraguan Córdoba")).to eq ["NIO"]
|
|
85
|
-
end
|
|
86
|
-
|
|
87
|
-
it "find currencies with special symbols using unaccent" do
|
|
88
|
-
expect(it.analyze("ل.س")).not_to eq []
|
|
89
|
-
expect(it.analyze("R₣")).not_to eq []
|
|
90
|
-
expect(it.analyze("ரூ")).not_to eq []
|
|
91
|
-
expect(it.analyze("රු")).not_to eq []
|
|
92
|
-
expect(it.analyze("сом")).not_to eq []
|
|
93
|
-
expect(it.analyze("圓")).not_to eq []
|
|
94
|
-
expect(it.analyze("円")).not_to eq []
|
|
95
|
-
expect(it.analyze("৳")).not_to eq []
|
|
96
|
-
expect(it.analyze("૱")).not_to eq []
|
|
97
|
-
expect(it.analyze("௹")).not_to eq []
|
|
98
|
-
expect(it.analyze("रु")).not_to eq []
|
|
99
|
-
expect(it.analyze("ש״ח")).not_to eq []
|
|
100
|
-
expect(it.analyze("元")).not_to eq []
|
|
101
|
-
expect(it.analyze("¢")).not_to eq []
|
|
102
|
-
expect(it.analyze("£")).not_to eq []
|
|
103
|
-
expect(it.analyze("€")).not_to eq []
|
|
104
|
-
expect(it.analyze("¥")).not_to eq []
|
|
105
|
-
expect(it.analyze("د.إ")).not_to eq []
|
|
106
|
-
expect(it.analyze("؋")).not_to eq []
|
|
107
|
-
expect(it.analyze("դր.")).not_to eq []
|
|
108
|
-
expect(it.analyze("ƒ")).not_to eq []
|
|
109
|
-
expect(it.analyze("₼")).not_to eq []
|
|
110
|
-
expect(it.analyze("৳")).not_to eq []
|
|
111
|
-
expect(it.analyze("лв")).not_to eq []
|
|
112
|
-
expect(it.analyze("лев")).not_to eq []
|
|
113
|
-
expect(it.analyze("дин")).not_to eq []
|
|
114
|
-
expect(it.analyze("ب.د")).not_to eq []
|
|
115
|
-
expect(it.analyze("₡")).not_to eq []
|
|
116
|
-
expect(it.analyze("Kč")).not_to eq []
|
|
117
|
-
expect(it.analyze("د.ج")).not_to eq []
|
|
118
|
-
expect(it.analyze("ج.م")).not_to eq []
|
|
119
|
-
expect(it.analyze("ლ")).not_to eq []
|
|
120
|
-
expect(it.analyze("₵")).not_to eq []
|
|
121
|
-
expect(it.analyze("₪")).not_to eq []
|
|
122
|
-
expect(it.analyze("₹")).not_to eq []
|
|
123
|
-
expect(it.analyze("ع.د")).not_to eq []
|
|
124
|
-
expect(it.analyze("﷼")).not_to eq []
|
|
125
|
-
expect(it.analyze("د.ا")).not_to eq []
|
|
126
|
-
expect(it.analyze("៛")).not_to eq []
|
|
127
|
-
expect(it.analyze("₩")).not_to eq []
|
|
128
|
-
expect(it.analyze("د.ك")).not_to eq []
|
|
129
|
-
expect(it.analyze("〒")).not_to eq []
|
|
130
|
-
expect(it.analyze("₭")).not_to eq []
|
|
131
|
-
expect(it.analyze("ل.ل")).not_to eq []
|
|
132
|
-
expect(it.analyze("₨")).not_to eq []
|
|
133
|
-
expect(it.analyze("ل.د")).not_to eq []
|
|
134
|
-
expect(it.analyze("د.م.")).not_to eq []
|
|
135
|
-
expect(it.analyze("ден")).not_to eq []
|
|
136
|
-
expect(it.analyze("₮")).not_to eq []
|
|
137
|
-
expect(it.analyze("₦")).not_to eq []
|
|
138
|
-
expect(it.analyze("C$")).not_to eq []
|
|
139
|
-
expect(it.analyze("ر.ع.")).not_to eq []
|
|
140
|
-
expect(it.analyze("₱")).not_to eq []
|
|
141
|
-
expect(it.analyze("zł")).not_to eq []
|
|
142
|
-
expect(it.analyze("₲")).not_to eq []
|
|
143
|
-
expect(it.analyze("ر.ق")).not_to eq []
|
|
144
|
-
expect(it.analyze("РСД")).not_to eq []
|
|
145
|
-
expect(it.analyze("₽")).not_to eq []
|
|
146
|
-
expect(it.analyze("ر.س")).not_to eq []
|
|
147
|
-
expect(it.analyze("฿")).not_to eq []
|
|
148
|
-
expect(it.analyze("د.ت")).not_to eq []
|
|
149
|
-
expect(it.analyze("T$")).not_to eq []
|
|
150
|
-
expect(it.analyze("₺")).not_to eq []
|
|
151
|
-
expect(it.analyze("₴")).not_to eq []
|
|
152
|
-
expect(it.analyze("₫")).not_to eq []
|
|
153
|
-
expect(it.analyze("B⃦")).not_to eq []
|
|
154
|
-
expect(it.analyze("₤")).not_to eq []
|
|
155
|
-
expect(it.analyze("ރ")).not_to eq []
|
|
156
|
-
end
|
|
157
|
-
|
|
158
|
-
it "should function with unicode characters" do
|
|
159
|
-
expect(it.analyze("10 դր.")).to eq ["AMD"]
|
|
7
|
+
it "it raises deprecation error" do
|
|
8
|
+
expect{ it.analyze('123') }.to raise_error(StandardError, 'Heuristics deprecated, add `gem "money-heuristics"` to Gemfile')
|
|
160
9
|
end
|
|
161
10
|
end
|
|
162
11
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: money
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 6.
|
|
4
|
+
version: 6.9.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Shane Emmons
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2017-04-
|
|
11
|
+
date: 2017-04-20 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: i18n
|
|
@@ -30,26 +30,6 @@ dependencies:
|
|
|
30
30
|
- - "<"
|
|
31
31
|
- !ruby/object:Gem::Version
|
|
32
32
|
version: '0.9'
|
|
33
|
-
- !ruby/object:Gem::Dependency
|
|
34
|
-
name: sixarm_ruby_unaccent
|
|
35
|
-
requirement: !ruby/object:Gem::Requirement
|
|
36
|
-
requirements:
|
|
37
|
-
- - ">="
|
|
38
|
-
- !ruby/object:Gem::Version
|
|
39
|
-
version: 1.1.1
|
|
40
|
-
- - "<"
|
|
41
|
-
- !ruby/object:Gem::Version
|
|
42
|
-
version: '2'
|
|
43
|
-
type: :runtime
|
|
44
|
-
prerelease: false
|
|
45
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
46
|
-
requirements:
|
|
47
|
-
- - ">="
|
|
48
|
-
- !ruby/object:Gem::Version
|
|
49
|
-
version: 1.1.1
|
|
50
|
-
- - "<"
|
|
51
|
-
- !ruby/object:Gem::Version
|
|
52
|
-
version: '2'
|
|
53
33
|
- !ruby/object:Gem::Dependency
|
|
54
34
|
name: bundler
|
|
55
35
|
requirement: !ruby/object:Gem::Requirement
|