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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f290bfa8454b55a279eb7c548620689ead38c172
4
- data.tar.gz: 79cdf5b28b304266e61331d3527a1579bc85833a
3
+ metadata.gz: f268faeee9a1901f8a4e482e8497370697eb436a
4
+ data.tar.gz: 54f37ca793f33929f7c1dd10de33d58c813495fe
5
5
  SHA512:
6
- metadata.gz: 337064ab1d3e44b4f047248683c73ef814f50b1b54d00e5d54c81c1472baa015701365c8bf516ef2d3e0e707a7196dec80b79b4a8134659ca9adfac7ef4d2dc6
7
- data.tar.gz: 7e625920a47b29b5f5d042bf7d90a9be710e943d9581175d46d015bef170c5f63412627f7d3994c15d4f6ba7106f336671fab7803a8d04231584fb1a864642fe
6
+ metadata.gz: b9d33bfe048a6ba6fe92391ac9223a92268f31bd6c1f0ef932f2d202fd3a45e7df013c5c96d5ac99b98aacde1ece7a905fda77949aa9e4ad7625698b16b5914f
7
+ data.tar.gz: b3b255302aec3569a1b7e1b4dc5a7e1a77b1b4129c09eb65f295461eadc48cc342f09de81236a229a6d4139a5038069108fdc53660d09255c9d3fa1130d22a02
@@ -1,5 +1,8 @@
1
1
  # Changelog
2
2
 
3
+ ## 6.9.0
4
+ - Extracted heuristics into money-heuristics gem
5
+
3
6
  ## 6.8.4
4
7
  - Resolving NIO ambiguity with CAD
5
8
  - Display the BBD $ symbol before digits
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
@@ -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
- return Analyzer.new(str, search_tree).process
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
-
@@ -1,3 +1,3 @@
1
1
  class Money
2
- VERSION = "6.8.4"
2
+ VERSION = "6.9.0"
3
3
  end
@@ -15,7 +15,6 @@ Gem::Specification.new do |s|
15
15
  s.license = "MIT"
16
16
 
17
17
  s.add_dependency 'i18n', ['>= 0.6.4', '< 0.9']
18
- s.add_dependency 'sixarm_ruby_unaccent', ['>= 1.1.1', '< 2']
19
18
 
20
19
  s.add_development_dependency "bundler", "~> 1.3"
21
20
  s.add_development_dependency "rake"
@@ -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 "is not affected by blank characters and numbers" do
8
- expect(it.analyze('123')).to eq []
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.8.4
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-19 00:00:00.000000000 Z
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