dropmire 0.0.1 → 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +4 -1
- data/README.md +48 -1
- data/config/first_initial.yml +26 -0
- data/config/first_name.yml +53 -0
- data/config/middle_initial.yml +26 -0
- data/dropmire.gemspec +1 -1
- data/lib/dropmire/ext/string.rb +5 -0
- data/lib/dropmire/identity.rb +101 -0
- data/lib/dropmire/name_encoder.rb +104 -0
- data/lib/dropmire/parser.rb +105 -8
- data/lib/dropmire/soundex.rb +66 -0
- data/lib/dropmire/version.rb +1 -1
- data/lib/dropmire.rb +2 -1
- data/spec/demo.txt +3 -1
- data/spec/identity_spec.rb +80 -0
- data/spec/name_encoder_spec.rb +168 -0
- data/spec/parser_spec.rb +97 -4
- data/spec/soundex_spec.rb +188 -0
- metadata +16 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 00aff84a94e0b3f608c8c246865fb43c2f1a6ace
|
4
|
+
data.tar.gz: 2b7661d1934070955617c298abc748296e9025c7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 29a80db72e40d488c6f3e0609b70af54251cf0a242f9754e4d617c79bc909c3c9985dd15c097836e8e1d78bd50a882cbb576cb9d3da009e5ec7780d366c8d53e
|
7
|
+
data.tar.gz: dc30a3663d0f6ca55e97b8290ce73f3a202686f5ef4228f94ee2dd95f0eac09f72cf9a9ab90788bf1d9951499740eaf72f5af98dec3efddc31821562a82d5d46
|
data/.gitignore
CHANGED
data/README.md
CHANGED
@@ -18,7 +18,54 @@ Or install it yourself as:
|
|
18
18
|
|
19
19
|
## Usage
|
20
20
|
|
21
|
-
|
21
|
+
Install the gem:
|
22
|
+
|
23
|
+
```bash
|
24
|
+
gem install dropmire
|
25
|
+
```
|
26
|
+
|
27
|
+
Or add to Gemfile:
|
28
|
+
|
29
|
+
```bash
|
30
|
+
gem 'dropmire'
|
31
|
+
```
|
32
|
+
|
33
|
+
Do cool stuff
|
34
|
+
|
35
|
+
```ruby
|
36
|
+
person = Dropmire::Identity.new("""Your scanned input here!""")
|
37
|
+
|
38
|
+
# use your super cool new object
|
39
|
+
person.first_name
|
40
|
+
# => 'John'
|
41
|
+
|
42
|
+
person.middle_name
|
43
|
+
# => 'Pearce'
|
44
|
+
|
45
|
+
person.last_name
|
46
|
+
# => 'Doe'
|
47
|
+
|
48
|
+
person.date_of_birth
|
49
|
+
# => '1993-06-07'
|
50
|
+
|
51
|
+
person.drivers_license_number
|
52
|
+
# => 'D21242193207'
|
53
|
+
|
54
|
+
person.drivers_license_expiration_date
|
55
|
+
# => '2015-06'
|
56
|
+
|
57
|
+
person.street
|
58
|
+
# => '1234 Main St'
|
59
|
+
|
60
|
+
person.city
|
61
|
+
# => 'Tallahassee'
|
62
|
+
|
63
|
+
person.state
|
64
|
+
# => 'State'
|
65
|
+
|
66
|
+
person.zipcode
|
67
|
+
# => '12345'
|
68
|
+
```
|
22
69
|
|
23
70
|
## Contributing
|
24
71
|
|
@@ -0,0 +1,26 @@
|
|
1
|
+
A: 0
|
2
|
+
B: 60
|
3
|
+
C: 100
|
4
|
+
D: 160
|
5
|
+
E: 200
|
6
|
+
F: 240
|
7
|
+
G: 280
|
8
|
+
H: 320
|
9
|
+
I: 400
|
10
|
+
J: 420
|
11
|
+
K: 500
|
12
|
+
L: 520
|
13
|
+
M: 540
|
14
|
+
N: 620
|
15
|
+
O: 640
|
16
|
+
P: 660
|
17
|
+
Q: 700
|
18
|
+
R: 720
|
19
|
+
S: 780
|
20
|
+
T: 800
|
21
|
+
U: 840
|
22
|
+
V: 860
|
23
|
+
W: 880
|
24
|
+
X: 940
|
25
|
+
Y: 960
|
26
|
+
Z: 980
|
@@ -0,0 +1,53 @@
|
|
1
|
+
albert: 20
|
2
|
+
alice: 20
|
3
|
+
ann: 40
|
4
|
+
anna: 40
|
5
|
+
annie: 40
|
6
|
+
arthur: 40
|
7
|
+
bernard: 80
|
8
|
+
bette: 80
|
9
|
+
bettie: 80
|
10
|
+
betty: 80
|
11
|
+
carl: 120
|
12
|
+
catherine: 120
|
13
|
+
charles: 140
|
14
|
+
dorthy: 180
|
15
|
+
edward: 220
|
16
|
+
elizabeth: 220
|
17
|
+
florence: 260
|
18
|
+
donald: 180
|
19
|
+
clara: 140
|
20
|
+
frank: 260
|
21
|
+
george: 300
|
22
|
+
grace: 300
|
23
|
+
harold: 340
|
24
|
+
harriet: 340
|
25
|
+
harry: 360
|
26
|
+
hazel: 360
|
27
|
+
helen: 380
|
28
|
+
henry: 380
|
29
|
+
james: 440
|
30
|
+
jane: 440
|
31
|
+
jayne: 440
|
32
|
+
jean: 460
|
33
|
+
joan: 480
|
34
|
+
john: 460
|
35
|
+
joseph: 480
|
36
|
+
margaret: 560
|
37
|
+
martin: 560
|
38
|
+
marvin: 580
|
39
|
+
mary: 580
|
40
|
+
melvin: 600
|
41
|
+
mildred: 600
|
42
|
+
patricia: 680
|
43
|
+
paul: 680
|
44
|
+
richard: 740
|
45
|
+
robert: 760
|
46
|
+
ruby: 740
|
47
|
+
ruth: 760
|
48
|
+
thelma: 820
|
49
|
+
thomas: 820
|
50
|
+
walter: 900
|
51
|
+
wanda: 900
|
52
|
+
william: 920
|
53
|
+
wilma: 920
|
data/dropmire.gemspec
CHANGED
@@ -10,7 +10,7 @@ Gem::Specification.new do |spec|
|
|
10
10
|
spec.email = ["jacobsen.connor@gmail.com"]
|
11
11
|
spec.summary = %q{A simple way to collect data from US driver's licenses.}
|
12
12
|
spec.description = %q{A simple way to collect data from US driver's licenses with a card reader.}
|
13
|
-
spec.homepage = ""
|
13
|
+
spec.homepage = "https://github.com/connorjacobsen/dropmire"
|
14
14
|
spec.license = "Apache-2.0"
|
15
15
|
|
16
16
|
spec.files = `git ls-files -z`.split("\x0")
|
@@ -0,0 +1,101 @@
|
|
1
|
+
require 'dropmire/parser'
|
2
|
+
|
3
|
+
module Dropmire
|
4
|
+
class Identity
|
5
|
+
def initialize(text)
|
6
|
+
p = Parser.new(text)
|
7
|
+
p.parse
|
8
|
+
|
9
|
+
@attrs = p.attrs
|
10
|
+
end
|
11
|
+
|
12
|
+
# naive method approach
|
13
|
+
def address
|
14
|
+
{ street: street, city: city, state: state, zipcode: zipcode }
|
15
|
+
end
|
16
|
+
|
17
|
+
def street
|
18
|
+
attrs[:address][:street]
|
19
|
+
end
|
20
|
+
|
21
|
+
def city
|
22
|
+
attrs[:address][:city]
|
23
|
+
end
|
24
|
+
|
25
|
+
def state
|
26
|
+
attrs[:address][:state]
|
27
|
+
end
|
28
|
+
|
29
|
+
def zipcode
|
30
|
+
attrs[:address][:zipcode]
|
31
|
+
end
|
32
|
+
|
33
|
+
def names
|
34
|
+
{ first: first_name, middle: middle_name, last: last_name }
|
35
|
+
end
|
36
|
+
|
37
|
+
def first_name
|
38
|
+
attrs[:name][:first]
|
39
|
+
end
|
40
|
+
|
41
|
+
def middle_name
|
42
|
+
attrs[:name][:middle]
|
43
|
+
end
|
44
|
+
|
45
|
+
def last_name
|
46
|
+
attrs[:name][:last]
|
47
|
+
end
|
48
|
+
|
49
|
+
def drivers_license_number
|
50
|
+
attrs[:license_num]
|
51
|
+
end
|
52
|
+
|
53
|
+
def drivers_license_iin
|
54
|
+
attrs[:iin]
|
55
|
+
end
|
56
|
+
|
57
|
+
def drivers_license_class
|
58
|
+
attrs[:license_class]
|
59
|
+
end
|
60
|
+
|
61
|
+
def drivers_license_expiration_date
|
62
|
+
attrs[:expiration_date]
|
63
|
+
end
|
64
|
+
|
65
|
+
def date_of_birth
|
66
|
+
attrs[:date_of_birth]
|
67
|
+
end
|
68
|
+
|
69
|
+
# For meta attr methods later...
|
70
|
+
#
|
71
|
+
# def method_missing(method, *args, &block)
|
72
|
+
# if addr_lookup method.to_s
|
73
|
+
|
74
|
+
# else
|
75
|
+
# super
|
76
|
+
# end
|
77
|
+
# end
|
78
|
+
|
79
|
+
private
|
80
|
+
|
81
|
+
def attrs
|
82
|
+
@attrs
|
83
|
+
end
|
84
|
+
|
85
|
+
# def attr_lookup(attr)
|
86
|
+
# if attrs.has_key? attr
|
87
|
+
# elsif address_vars
|
88
|
+
# elsif name_vars
|
89
|
+
# else
|
90
|
+
# end
|
91
|
+
# end
|
92
|
+
|
93
|
+
# def address_vars
|
94
|
+
# %w(street city state zipcode)
|
95
|
+
# end
|
96
|
+
|
97
|
+
# def name_vars
|
98
|
+
# %w(first middle last first_name middle_name last_name)
|
99
|
+
# end
|
100
|
+
end
|
101
|
+
end
|
@@ -0,0 +1,104 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
|
3
|
+
module Dropmire
|
4
|
+
module NameEncoder
|
5
|
+
|
6
|
+
class << self
|
7
|
+
# :first and :middle are the first and middle names to encode.
|
8
|
+
def encode(first, middle)
|
9
|
+
raise "Cannot encode nil name" if first.nil? || middle.nil?
|
10
|
+
|
11
|
+
fcode = generate_fcode(first.downcase)
|
12
|
+
mcode = find(:middle_initials, initial(middle).upcase)
|
13
|
+
|
14
|
+
"%3d" % (fcode + mcode)
|
15
|
+
end
|
16
|
+
|
17
|
+
def generate_fcode(name)
|
18
|
+
val = find(:first_names, name.downcase)
|
19
|
+
|
20
|
+
if val.nil?
|
21
|
+
val = find(:first_initials, initial(name).upcase)
|
22
|
+
end
|
23
|
+
|
24
|
+
val
|
25
|
+
end
|
26
|
+
|
27
|
+
# get the corresponding initial for a given :name.
|
28
|
+
def initial(name)
|
29
|
+
return nil if name.nil?
|
30
|
+
name[0].downcase
|
31
|
+
end
|
32
|
+
|
33
|
+
def load(filename)
|
34
|
+
load_yaml_from(filename)
|
35
|
+
end
|
36
|
+
|
37
|
+
def first_names
|
38
|
+
@first_names ||= load_first_names
|
39
|
+
end
|
40
|
+
|
41
|
+
def first_initials
|
42
|
+
@first_initials ||= load_first_initials
|
43
|
+
end
|
44
|
+
|
45
|
+
def middle_initials
|
46
|
+
@middle_initials ||= load_middle_initials
|
47
|
+
end
|
48
|
+
|
49
|
+
# searches the desired Hash (chosen by :method) for the :key
|
50
|
+
def find(method, key)
|
51
|
+
if allowed_find_methods.include? method
|
52
|
+
self.send(method).fetch(key, nil)
|
53
|
+
else
|
54
|
+
raise "Illegal find method!"
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
private
|
59
|
+
|
60
|
+
def allowed_find_methods
|
61
|
+
[ :first_names, :first_initials, :middle_initials ]
|
62
|
+
end
|
63
|
+
|
64
|
+
def load_first_names
|
65
|
+
@first_names = load(first_name_yaml)
|
66
|
+
end
|
67
|
+
|
68
|
+
def load_first_initials
|
69
|
+
@first_initials = load(first_initial_yaml)
|
70
|
+
end
|
71
|
+
|
72
|
+
def load_middle_initials
|
73
|
+
@middle_initials = load(middle_initial_yaml)
|
74
|
+
end
|
75
|
+
|
76
|
+
def load_yaml_from(filename)
|
77
|
+
parsed = begin
|
78
|
+
YAML.load(File.open(filename))
|
79
|
+
rescue ArgumentError => e
|
80
|
+
puts "Could not parse YAML: #{e.message}"
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
# YAML file name helpers #
|
85
|
+
|
86
|
+
def yaml_dir
|
87
|
+
'config/'
|
88
|
+
end
|
89
|
+
|
90
|
+
def first_name_yaml
|
91
|
+
yaml_dir + 'first_name.yml'
|
92
|
+
end
|
93
|
+
|
94
|
+
def first_initial_yaml
|
95
|
+
yaml_dir + 'first_initial.yml'
|
96
|
+
end
|
97
|
+
|
98
|
+
def middle_initial_yaml
|
99
|
+
yaml_dir + 'middle_initial.yml'
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
end
|
104
|
+
end
|
data/lib/dropmire/parser.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'dropmire/ext/string'
|
2
|
+
|
1
3
|
module Dropmire
|
2
4
|
class Parser
|
3
5
|
# Public: Creates a new Dropmire::Parser.
|
@@ -13,15 +15,26 @@ module Dropmire
|
|
13
15
|
# Returns the Hash of results from the string.
|
14
16
|
def initialize(text, options = {})
|
15
17
|
@text = text
|
16
|
-
@attrs = {} # empty hash for the parsed values
|
18
|
+
@attrs = {:address=>{}} # empty hash for the parsed values
|
17
19
|
end
|
18
20
|
|
19
21
|
def attrs
|
20
22
|
@attrs
|
21
23
|
end
|
22
24
|
|
23
|
-
def
|
24
|
-
|
25
|
+
def parse
|
26
|
+
parse_methods.each do |method|
|
27
|
+
self.send method
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def parse_methods
|
32
|
+
[ :parse_address, :parse_carrot_string, :date_of_birth, :zipcode,
|
33
|
+
:license_class, :expiration_date, :parse_license_num ]
|
34
|
+
end
|
35
|
+
|
36
|
+
def address
|
37
|
+
/\A[%][a-zA-Z]*/.match(@text).to_s
|
25
38
|
end
|
26
39
|
|
27
40
|
def state(addr)
|
@@ -33,11 +46,95 @@ module Dropmire
|
|
33
46
|
addr[3..l].capitalize
|
34
47
|
end
|
35
48
|
|
49
|
+
def carrot_string
|
50
|
+
str = /\^(.*)\^/.match(@text).to_s
|
51
|
+
len = str.length-2
|
52
|
+
str[1..len].split('^')
|
53
|
+
end
|
54
|
+
|
55
|
+
def parse_carrot_string
|
56
|
+
name_string, street_string = carrot_string
|
57
|
+
names split_name(name_string)
|
58
|
+
street street_string
|
59
|
+
end
|
60
|
+
|
36
61
|
def parse_address
|
37
|
-
addr = address
|
38
|
-
@attrs[:state] = state(addr)
|
39
|
-
@attrs[:city]
|
40
|
-
|
62
|
+
addr = address
|
63
|
+
@attrs[:address][:state] = state(addr)
|
64
|
+
@attrs[:address][:city] = city(addr)
|
65
|
+
|
66
|
+
[@attrs[:address][:city], @attrs[:address][:state]]
|
67
|
+
end
|
68
|
+
|
69
|
+
def split_name(name)
|
70
|
+
name.split('$')
|
71
|
+
end
|
72
|
+
|
73
|
+
def names(names)
|
74
|
+
@attrs[:name] = {
|
75
|
+
first: names[1].capitalize,
|
76
|
+
last: names[0].capitalize,
|
77
|
+
middle: names[2].capitalize
|
78
|
+
}
|
79
|
+
end
|
80
|
+
|
81
|
+
def street(street)
|
82
|
+
ary = street.split(' ')
|
83
|
+
str = []
|
84
|
+
ary.each do |s|
|
85
|
+
str << s.capitalize
|
86
|
+
end
|
87
|
+
@attrs[:address][:street] = str.join(' ')
|
88
|
+
end
|
89
|
+
|
90
|
+
def zipcode
|
91
|
+
str = /![\s]*[0-9]*/.match(@text).to_s
|
92
|
+
zip = str[1..(str.length)].strip
|
93
|
+
@attrs[:address][:zipcode] = zip[0,5]
|
94
|
+
end
|
95
|
+
|
96
|
+
def license_class
|
97
|
+
str = /![\s]*[0-9]*[\s]*[A-Z]/.match(@text).to_s
|
98
|
+
@attrs[:license_class] = str[-1]
|
99
|
+
end
|
100
|
+
|
101
|
+
def id_string
|
102
|
+
/;[0-9]*=/.match(@text).to_s.gsub(/[;=]/, '')
|
103
|
+
end
|
104
|
+
|
105
|
+
def iin(str)
|
106
|
+
@attrs[:iin] = str[0,6]
|
107
|
+
end
|
108
|
+
|
109
|
+
def license_num(str)
|
110
|
+
num_len = str.length - 8
|
111
|
+
@attrs[:license_num] = str[6,2].to_char.upcase + str[8, num_len]
|
112
|
+
end
|
113
|
+
|
114
|
+
def parse_license_num
|
115
|
+
id_str = id_string
|
116
|
+
iin(id_str)
|
117
|
+
license_num(id_str)
|
118
|
+
end
|
119
|
+
|
120
|
+
def expiration_date
|
121
|
+
str = /=[0-9]{4}/.match(@text).to_s
|
122
|
+
@attrs[:expiration_date] = transform_date str[1,4]
|
123
|
+
end
|
124
|
+
|
125
|
+
def date_of_birth
|
126
|
+
str = /=[0-9]*/.match(@text).to_s
|
127
|
+
dob = str[5,8]
|
128
|
+
year = dob[0,4]
|
129
|
+
month = dob[4,2]
|
130
|
+
day = dob[6,2]
|
131
|
+
@attrs[:date_of_birth] = "#{year}-#{month}-#{day}"
|
132
|
+
end
|
133
|
+
|
134
|
+
def transform_date(date)
|
135
|
+
y = date[0,2]
|
136
|
+
m = date[2,2]
|
137
|
+
"20#{y}-#{m}"
|
41
138
|
end
|
42
139
|
end
|
43
|
-
end
|
140
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
# Implementation of the Soundex phonetic algorithm for indexing names
|
2
|
+
# by sound, as pronounced in English.
|
3
|
+
module Dropmire
|
4
|
+
module Soundex
|
5
|
+
|
6
|
+
class << self
|
7
|
+
|
8
|
+
def soundex(str_or_arr)
|
9
|
+
case str_or_arr
|
10
|
+
when String
|
11
|
+
build_code_for(str_or_arr)
|
12
|
+
when Array
|
13
|
+
str_or_arr.collect { |str| build_code_for(str) }
|
14
|
+
else
|
15
|
+
nil
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def build_code_for(str)
|
20
|
+
str = str.upcase.gsub(/[^A-Z]/, '')
|
21
|
+
return nil if str.empty?
|
22
|
+
|
23
|
+
soundex_code = str[0]
|
24
|
+
last_code = get_code str[0]
|
25
|
+
|
26
|
+
len = str.length
|
27
|
+
str[0..len].chars.each_index do |index|
|
28
|
+
return soundex_code if soundex_code.length == 4
|
29
|
+
|
30
|
+
code = get_code str[index]
|
31
|
+
if code == '0'
|
32
|
+
unless %w(W H).include? str[index]
|
33
|
+
last_code = nil
|
34
|
+
end
|
35
|
+
elsif code != last_code
|
36
|
+
soundex_code += code
|
37
|
+
last_code = code
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
return soundex_code.ljust(4, '0')
|
42
|
+
end
|
43
|
+
|
44
|
+
def get_code(char)
|
45
|
+
case char
|
46
|
+
when 'B', 'F', 'P', 'V'
|
47
|
+
'1'
|
48
|
+
when 'C', 'G', 'J', 'K', 'Q', 'S', 'X', 'Z'
|
49
|
+
'2'
|
50
|
+
when 'D', 'T'
|
51
|
+
'3'
|
52
|
+
when 'L'
|
53
|
+
'4'
|
54
|
+
when 'M', 'N'
|
55
|
+
'5'
|
56
|
+
when 'R'
|
57
|
+
'6'
|
58
|
+
else
|
59
|
+
'0'
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
66
|
+
end
|
data/lib/dropmire/version.rb
CHANGED
data/lib/dropmire.rb
CHANGED
data/spec/demo.txt
CHANGED
@@ -1 +1,3 @@
|
|
1
|
-
%FLTALLAHASSEE^JACOBSEN$CONNOR$ALAN^6357 SINKOLA DR^ ?;6360101021210193207=
|
1
|
+
%FLTALLAHASSEE^JACOBSEN$CONNOR$ALAN^6357 SINKOLA DR^ ?;6360101021210193207=1506199306070=?+! 323124522 E 1602 ECCECC00000?
|
2
|
+
|
3
|
+
%CAENCINITAS^MEIER$ALAIN$PIERRE^2814 CRYSTAL RIDGE RD^?;636014064752956=190819930823?+!!92024 M602162BRNBRN I67620131125 [,/,_29’;2!?
|
@@ -0,0 +1,80 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Dropmire::Identity do
|
4
|
+
@demo_text = """%FLTALLAHASSEE^JACOBSEN$CONNOR$ALAN^1234 MAIN ST^ ?;6360101021210193207=1506199306070=?+! 123454522 E 1602 ECCECC00000?"""
|
5
|
+
identity = Dropmire::Identity.new(@demo_text)
|
6
|
+
subject { identity }
|
7
|
+
|
8
|
+
describe "#first_name" do
|
9
|
+
it "returns correct value" do
|
10
|
+
expect(subject.first_name).to eql "Connor"
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
describe "#middle_name" do
|
15
|
+
it "returns correct value" do
|
16
|
+
expect(subject.middle_name).to eql "Alan"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
describe "#last_name" do
|
21
|
+
it "returns correct value" do
|
22
|
+
expect(subject.last_name).to eql "Jacobsen"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
describe "#names" do
|
27
|
+
names = {first: "Connor", middle: "Alan", last: ""}
|
28
|
+
end
|
29
|
+
|
30
|
+
describe "#address" do
|
31
|
+
end
|
32
|
+
|
33
|
+
describe "#city" do
|
34
|
+
it "returns correct value" do
|
35
|
+
expect(subject.city).to eql "Tallahassee"
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
describe "#state" do
|
40
|
+
it "returns correct value" do
|
41
|
+
expect(subject.state).to eql "FL"
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
describe "#street" do
|
46
|
+
it "returns correct value" do
|
47
|
+
expect(subject.street).to eql "1234 Main St"
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
describe "#zipcode" do
|
52
|
+
it "returns correct value" do
|
53
|
+
expect(subject.zipcode).to eql "12345"
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
describe "#drivers_license_number" do
|
58
|
+
it "returns correct value" do
|
59
|
+
expect(subject.drivers_license_number).to eql "J21210193207"
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
describe "#drivers_license_iin" do
|
64
|
+
it "returns correct value" do
|
65
|
+
expect(subject.drivers_license_iin).to eql "636010"
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
describe "#drivers_license_expiration_date" do
|
70
|
+
it "returns correct value" do
|
71
|
+
expect(subject.drivers_license_expiration_date).to eql "2015-06"
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
describe "#date_of_birth" do
|
76
|
+
it "returns correct value" do
|
77
|
+
expect(subject.date_of_birth).to eql "1993-06-07"
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
@@ -0,0 +1,168 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Dropmire::NameEncoder do
|
4
|
+
|
5
|
+
subject { Dropmire::NameEncoder }
|
6
|
+
|
7
|
+
describe "#encode" do
|
8
|
+
context "William Andrew Fakename" do
|
9
|
+
it "returns correct value" do
|
10
|
+
expect(subject.encode("William", "Andrew")).to eql "921"
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
context "Connor Alan Jacobsen" do
|
15
|
+
it "returns correct value" do
|
16
|
+
expect(subject.encode("Connor", "Alan")).to eql "101"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
describe "#generate_fcode" do
|
22
|
+
context "first name NotFound" do
|
23
|
+
it "uses first initial" do
|
24
|
+
expect(subject.generate_fcode("Connor")).to eql 100
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
context "first name found" do
|
29
|
+
it "returns correct value" do
|
30
|
+
expect(subject.generate_fcode("Alice")).to eql 20
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
describe "#initial" do
|
36
|
+
context "when not nil" do
|
37
|
+
it "returns a single char" do
|
38
|
+
expect(subject.initial('Connor').size).to eql 1
|
39
|
+
end
|
40
|
+
|
41
|
+
it "returns the correct char" do
|
42
|
+
expect(subject.initial('Connor')).to eql 'c'
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
context "when nil" do
|
47
|
+
it "returns nil" do
|
48
|
+
expect(subject.initial(nil)).to eql nil
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
describe "#first_names" do
|
54
|
+
it "has class Hash" do
|
55
|
+
expect(subject.first_names.class).to eql Hash
|
56
|
+
end
|
57
|
+
|
58
|
+
it "is not empty" do
|
59
|
+
expect(subject.first_names.empty?).to eql false
|
60
|
+
end
|
61
|
+
|
62
|
+
describe "sanity check" do
|
63
|
+
context "alice" do
|
64
|
+
it "returns 20" do
|
65
|
+
expect(subject.first_names["alice"]).to eql 20
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
context "donald" do
|
70
|
+
it "returns 180" do
|
71
|
+
expect(subject.first_names["donald"]).to eql 180
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
describe "#first_initials" do
|
78
|
+
it "has class Hash" do
|
79
|
+
expect(subject.first_initials.class).to eql Hash
|
80
|
+
end
|
81
|
+
|
82
|
+
it "is not empty" do
|
83
|
+
expect(subject.first_initials.empty?).to eql false
|
84
|
+
end
|
85
|
+
|
86
|
+
describe "sanity check" do
|
87
|
+
context "C" do
|
88
|
+
it "returns 100" do
|
89
|
+
expect(subject.first_initials["C"]).to eql 100
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
context "J" do
|
94
|
+
it "returns 420" do
|
95
|
+
expect(subject.first_initials["J"]).to eql 420
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
describe "#middle_initials" do
|
102
|
+
it "has class Hash" do
|
103
|
+
expect(subject.middle_initials.class).to eql Hash
|
104
|
+
end
|
105
|
+
|
106
|
+
it "is not empty" do
|
107
|
+
expect(subject.middle_initials.empty?).to eql false
|
108
|
+
end
|
109
|
+
|
110
|
+
describe "sanity check" do
|
111
|
+
context "C" do
|
112
|
+
it "returns 3" do
|
113
|
+
expect(subject.middle_initials["C"]).to eql 3
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
context "J" do
|
118
|
+
it "returns 10" do
|
119
|
+
expect(subject.middle_initials["J"]).to eql 10
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
describe "#find" do
|
126
|
+
context "first_names" do
|
127
|
+
context "when in YAML" do
|
128
|
+
it "returns correct value" do
|
129
|
+
expect(subject.find(:first_names, "donald")).to eql 180
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
context "when not in YAML" do
|
134
|
+
it "returns nil" do
|
135
|
+
expect(subject.find(:first_names, "connor")).to eql nil
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
context "first_initials" do
|
141
|
+
context "when in YAML" do
|
142
|
+
it "returns correct value" do
|
143
|
+
expect(subject.find(:first_initials, "A")).to eql 0
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
context "when not in YAML" do
|
148
|
+
it "returns nil" do
|
149
|
+
expect(subject.find(:first_initials, "AB")).to eql nil
|
150
|
+
end
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
context "middle_initials" do
|
155
|
+
context "when in YAML" do
|
156
|
+
it "returns correct value" do
|
157
|
+
expect(subject.find(:middle_initials, "A")).to eql 1
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
context "when not in YAML" do
|
162
|
+
it "returns nil" do
|
163
|
+
expect(subject.find(:middle_initials, "AB")).to eql nil
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
167
|
+
end
|
168
|
+
end
|
data/spec/parser_spec.rb
CHANGED
@@ -1,8 +1,7 @@
|
|
1
|
-
require '
|
2
|
-
# require 'spec_helper'
|
1
|
+
require 'spec_helper'
|
3
2
|
|
4
3
|
describe Dropmire::Parser do
|
5
|
-
@demo_text =
|
4
|
+
@demo_text = """%FLTALLAHASSEE^JACOBSEN$CONNOR$ALAN^6357 SINKOLA DR^ ?;6360101021210193207=1506199306070=?+! 323124522 E 1602 ECCECC00000?"""
|
6
5
|
parser = Dropmire::Parser.new(@demo_text)
|
7
6
|
subject { parser }
|
8
7
|
|
@@ -10,7 +9,26 @@ describe Dropmire::Parser do
|
|
10
9
|
expect(subject.class).to eql Dropmire::Parser
|
11
10
|
end
|
12
11
|
|
13
|
-
describe "#
|
12
|
+
describe "#address" do
|
13
|
+
it "returns the address section" do
|
14
|
+
expect(subject.address).to eql "%FLTALLAHASSEE"
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
describe "#state" do
|
19
|
+
it "returns the correct state" do
|
20
|
+
addr = subject.address
|
21
|
+
|
22
|
+
expect(subject.state(addr)).to eql "FL"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
describe "#city" do
|
27
|
+
it "returns the correct city" do
|
28
|
+
addr = subject.address
|
29
|
+
|
30
|
+
expect(subject.city(addr)).to eql "Tallahassee"
|
31
|
+
end
|
14
32
|
end
|
15
33
|
|
16
34
|
describe "#parse_address" do
|
@@ -18,4 +36,79 @@ describe Dropmire::Parser do
|
|
18
36
|
expect(subject.parse_address).to eql ["Tallahassee", "FL"]
|
19
37
|
end
|
20
38
|
end
|
39
|
+
|
40
|
+
describe "#carrot_string" do
|
41
|
+
it "returns the correct array" do
|
42
|
+
carrot_arr = ["JACOBSEN$CONNOR$ALAN", "6357 SINKOLA DR"]
|
43
|
+
expect(subject.carrot_string).to eql carrot_arr
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
describe "#names" do
|
48
|
+
it "returns the correct array of strings" do
|
49
|
+
name_hash = {first: "Connor", middle: "Alan", last: "Jacobsen"}
|
50
|
+
expect(subject.names(%w(JACOBSEN CONNOR ALAN))).to eql name_hash
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
describe "street" do
|
55
|
+
it "returns the correct string" do
|
56
|
+
the_street = "6357 SINKOLA DR"
|
57
|
+
expect(subject.street(the_street)).to eql "6357 Sinkola Dr"
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
describe "#zipcode" do
|
62
|
+
it "returns correct zipcode" do
|
63
|
+
expect(subject.zipcode).to eql "32312"
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
describe "#id_string" do
|
68
|
+
it "returns the correct string" do
|
69
|
+
expect(subject.id_string).to eql "6360101021210193207"
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
describe "#iin" do
|
74
|
+
it "returns correct iin" do
|
75
|
+
id_str = subject.id_string
|
76
|
+
expect(subject.iin(id_str)).to eql "636010"
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
describe "#license_num" do
|
81
|
+
context "Florida" do
|
82
|
+
it "returns the correct string" do
|
83
|
+
id_str = subject.id_string
|
84
|
+
expect(subject.license_num(id_str)).to eql "J21210193207"
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
describe "#license_class" do
|
90
|
+
it "returns correct license_class" do
|
91
|
+
expect(subject.license_class).to eql "E"
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
describe "#expiration_date" do
|
96
|
+
it "returns the correct date" do
|
97
|
+
expect(subject.expiration_date).to eql "2015-06"
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
describe "#transform_date" do
|
102
|
+
it "returns Unix format" do
|
103
|
+
expect(subject.transform_date("1707")).to eql "2017-07"
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
describe "#date_of_birth" do
|
108
|
+
context "Florida" do
|
109
|
+
it "returns correct date_of_birth" do
|
110
|
+
expect(subject.date_of_birth).to eql "1993-06-07"
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
21
114
|
end
|
@@ -0,0 +1,188 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Dropmire::Soundex do
|
4
|
+
describe "#soundex" do
|
5
|
+
context "String" do
|
6
|
+
context "Robert" do
|
7
|
+
it "returns R163" do
|
8
|
+
expect(Dropmire::Soundex.soundex("Robert")).to eql 'R163'
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
context "Rupert" do
|
13
|
+
it "returns R163" do
|
14
|
+
expect(Dropmire::Soundex.soundex("Rupert")).to eql 'R163'
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
context "Rubin" do
|
19
|
+
it "returns R150" do
|
20
|
+
expect(Dropmire::Soundex.soundex("Rubin")).to eql 'R150'
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
context "Ashcraft" do
|
25
|
+
it "returns A261" do
|
26
|
+
expect(Dropmire::Soundex.soundex("Ashcraft")).to eql 'A261'
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
context "Ashcroft" do
|
31
|
+
it "returns A261" do
|
32
|
+
expect(Dropmire::Soundex.soundex("Ashcroft")).to eql 'A261'
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
context "Tymczak" do
|
37
|
+
it "returns T522" do
|
38
|
+
expect(Dropmire::Soundex.soundex("Tymczak")).to eql 'T522'
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
context "Pfister" do
|
43
|
+
it "returns P236" do
|
44
|
+
expect(Dropmire::Soundex.soundex("Pfister")).to eql 'P236'
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
context "Array" do
|
50
|
+
it "returns an Array of Soundexs" do
|
51
|
+
name_ary = %w(Robert Rupin Ashcroft Pfister)
|
52
|
+
answers = %w(R163 R150 A261 P236)
|
53
|
+
|
54
|
+
expect(Dropmire::Soundex.soundex(name_ary)).to eql answers
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
describe "#build_code_for" do
|
60
|
+
context "Robert" do
|
61
|
+
it "returns R163" do
|
62
|
+
expect(Dropmire::Soundex.build_code_for("Robert")).to eql 'R163'
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
context "Rupert" do
|
67
|
+
it "returns R163" do
|
68
|
+
expect(Dropmire::Soundex.build_code_for("Rupert")).to eql 'R163'
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
context "Rubin" do
|
73
|
+
it "returns R150" do
|
74
|
+
expect(Dropmire::Soundex.build_code_for("Rubin")).to eql 'R150'
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
context "Ashcraft" do
|
79
|
+
it "returns A261" do
|
80
|
+
expect(Dropmire::Soundex.build_code_for("Ashcraft")).to eql 'A261'
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
context "Ashcroft" do
|
85
|
+
it "returns A261" do
|
86
|
+
expect(Dropmire::Soundex.build_code_for("Ashcroft")).to eql 'A261'
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
context "Tymczak" do
|
91
|
+
it "returns T522" do
|
92
|
+
expect(Dropmire::Soundex.build_code_for("Tymczak")).to eql 'T522'
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
context "Pfister" do
|
97
|
+
it "returns P236" do
|
98
|
+
expect(Dropmire::Soundex.build_code_for("Pfister")).to eql 'P236'
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
describe "#get code" do
|
104
|
+
context "when code is 1" do
|
105
|
+
it "B" do
|
106
|
+
expect(Dropmire::Soundex.get_code('B')).to eql '1'
|
107
|
+
end
|
108
|
+
|
109
|
+
it "F" do
|
110
|
+
expect(Dropmire::Soundex.get_code('F')).to eql '1'
|
111
|
+
end
|
112
|
+
|
113
|
+
it "P" do
|
114
|
+
expect(Dropmire::Soundex.get_code('P')).to eql '1'
|
115
|
+
end
|
116
|
+
|
117
|
+
it "V" do
|
118
|
+
expect(Dropmire::Soundex.get_code('V')).to eql '1'
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
context "when code is 2" do
|
123
|
+
it "C" do
|
124
|
+
expect(Dropmire::Soundex.get_code('C')).to eql '2'
|
125
|
+
end
|
126
|
+
|
127
|
+
it "G" do
|
128
|
+
expect(Dropmire::Soundex.get_code('G')).to eql '2'
|
129
|
+
end
|
130
|
+
|
131
|
+
it "J" do
|
132
|
+
expect(Dropmire::Soundex.get_code('J')).to eql '2'
|
133
|
+
end
|
134
|
+
|
135
|
+
it "K" do
|
136
|
+
expect(Dropmire::Soundex.get_code('K')).to eql '2'
|
137
|
+
end
|
138
|
+
|
139
|
+
it "Q" do
|
140
|
+
expect(Dropmire::Soundex.get_code('Q')).to eql '2'
|
141
|
+
end
|
142
|
+
|
143
|
+
it "S" do
|
144
|
+
expect(Dropmire::Soundex.get_code('S')).to eql '2'
|
145
|
+
end
|
146
|
+
|
147
|
+
it "X" do
|
148
|
+
expect(Dropmire::Soundex.get_code('X')).to eql '2'
|
149
|
+
end
|
150
|
+
|
151
|
+
it "Z" do
|
152
|
+
expect(Dropmire::Soundex.get_code('Z')).to eql '2'
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
context "when code is 3" do
|
157
|
+
it "D" do
|
158
|
+
expect(Dropmire::Soundex.get_code('D')).to eql '3'
|
159
|
+
end
|
160
|
+
|
161
|
+
it "T" do
|
162
|
+
expect(Dropmire::Soundex.get_code('T')).to eql '3'
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
context "when code is 4" do
|
167
|
+
it "L" do
|
168
|
+
expect(Dropmire::Soundex.get_code('L')).to eql '4'
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
context "when code is 5" do
|
173
|
+
it "M" do
|
174
|
+
expect(Dropmire::Soundex.get_code('M')).to eql '5'
|
175
|
+
end
|
176
|
+
|
177
|
+
it "N" do
|
178
|
+
expect(Dropmire::Soundex.get_code('N')).to eql '5'
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
182
|
+
context "when code is 6" do
|
183
|
+
it "R" do
|
184
|
+
expect(Dropmire::Soundex.get_code('R')).to eql '6'
|
185
|
+
end
|
186
|
+
end
|
187
|
+
end
|
188
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dropmire
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Connor Jacobsen
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-10-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -64,14 +64,24 @@ files:
|
|
64
64
|
- LICENSE.txt
|
65
65
|
- README.md
|
66
66
|
- Rakefile
|
67
|
+
- config/first_initial.yml
|
68
|
+
- config/first_name.yml
|
69
|
+
- config/middle_initial.yml
|
67
70
|
- dropmire.gemspec
|
68
71
|
- lib/dropmire.rb
|
72
|
+
- lib/dropmire/ext/string.rb
|
73
|
+
- lib/dropmire/identity.rb
|
74
|
+
- lib/dropmire/name_encoder.rb
|
69
75
|
- lib/dropmire/parser.rb
|
76
|
+
- lib/dropmire/soundex.rb
|
70
77
|
- lib/dropmire/version.rb
|
71
78
|
- spec/demo.txt
|
79
|
+
- spec/identity_spec.rb
|
80
|
+
- spec/name_encoder_spec.rb
|
72
81
|
- spec/parser_spec.rb
|
82
|
+
- spec/soundex_spec.rb
|
73
83
|
- spec/spec_helper.rb
|
74
|
-
homepage:
|
84
|
+
homepage: https://github.com/connorjacobsen/dropmire
|
75
85
|
licenses:
|
76
86
|
- Apache-2.0
|
77
87
|
metadata: {}
|
@@ -97,5 +107,8 @@ specification_version: 4
|
|
97
107
|
summary: A simple way to collect data from US driver's licenses.
|
98
108
|
test_files:
|
99
109
|
- spec/demo.txt
|
110
|
+
- spec/identity_spec.rb
|
111
|
+
- spec/name_encoder_spec.rb
|
100
112
|
- spec/parser_spec.rb
|
113
|
+
- spec/soundex_spec.rb
|
101
114
|
- spec/spec_helper.rb
|