nameable 1.0.0 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.codeclimate.yml +7 -0
- data/.gitignore +1 -0
- data/.travis.yml +10 -0
- data/Gemfile.lock +87 -16
- data/Guardfile +57 -0
- data/README.md +4 -1
- data/data/yob2014.txt +33044 -0
- data/lib/nameable.rb +1 -0
- data/lib/nameable/assets.rb +4 -0
- data/lib/nameable/latin.rb +2 -2
- data/lib/nameable/version.rb +1 -1
- data/nameable.gemspec +7 -3
- data/spec/nameable/latin_spec.rb +213 -211
- data/spec/nameable_spec.rb +10 -6
- data/spec/spec_helper.rb +4 -0
- metadata +81 -9
- data/data/yob2013.txt +0 -33072
data/lib/nameable.rb
CHANGED
data/lib/nameable/latin.rb
CHANGED
@@ -138,10 +138,10 @@ module Nameable
|
|
138
138
|
end
|
139
139
|
|
140
140
|
# http://www.ssa.gov/oact/babynames/limits.html
|
141
|
-
def load_huge_gender_table
|
141
|
+
def load_huge_gender_table(gender_table=Nameable::Assets::GENDER_TABLE)
|
142
142
|
ranked = {}
|
143
143
|
|
144
|
-
CSV.read(
|
144
|
+
CSV.read(gender_table).each do |first, gender, rank|
|
145
145
|
first.downcase!
|
146
146
|
gender.downcase!
|
147
147
|
ranked[first] = {} unless ranked[first]
|
data/lib/nameable/version.rb
CHANGED
data/nameable.gemspec
CHANGED
@@ -18,7 +18,11 @@ Gem::Specification.new do |spec|
|
|
18
18
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
19
|
spec.require_paths = ["lib"]
|
20
20
|
|
21
|
-
spec.add_development_dependency 'bundler', '>= 1.6.2'
|
22
|
-
spec.add_development_dependency '
|
23
|
-
spec.add_development_dependency '
|
21
|
+
spec.add_development_dependency 'bundler', '~> 1.6', '>= 1.6.2'
|
22
|
+
spec.add_development_dependency 'codeclimate-test-reporter', '~> 0.4'
|
23
|
+
spec.add_development_dependency 'guard', '~> 2.12', '>= 2.12.6'
|
24
|
+
spec.add_development_dependency 'guard-bundler', '~> 2.1'
|
25
|
+
spec.add_development_dependency 'guard-rspec', '~> 4.5'
|
26
|
+
spec.add_development_dependency 'rake', '~> 10.4'
|
27
|
+
spec.add_development_dependency 'rspec', '~> 3.2'
|
24
28
|
end
|
data/spec/nameable/latin_spec.rb
CHANGED
@@ -1,284 +1,286 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
describe
|
4
|
-
|
5
|
-
|
3
|
+
describe Nameable::Latin do
|
4
|
+
describe '.new' do
|
5
|
+
it "doesn't raise" do
|
6
|
+
expect { Nameable::Latin.new }.to_not raise_error
|
7
|
+
end
|
6
8
|
end
|
7
|
-
end
|
8
9
|
|
9
|
-
context('with a single word name') do
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
10
|
+
context('with a single word name') do
|
11
|
+
subject(:n) { Nameable::Latin.new.parse("Chris") }
|
12
|
+
it '.parse' do
|
13
|
+
expect(n.prefix).to be_nil
|
14
|
+
expect(n.first).to eq('Chris')
|
15
|
+
expect(n.middle).to be_nil
|
16
|
+
expect(n.last).to be_nil
|
17
|
+
expect(n.suffix).to be_nil
|
18
|
+
end
|
17
19
|
end
|
18
|
-
end
|
19
20
|
|
20
|
-
context('with a simple name') do
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
21
|
+
context('with a simple name') do
|
22
|
+
subject(:n) { Nameable::Latin.new.parse("Chris Horn") }
|
23
|
+
it '.prefix' do
|
24
|
+
expect(n.prefix).to be_nil
|
25
|
+
end
|
26
|
+
it '.first' do
|
27
|
+
expect(n.first).to eq('Chris')
|
28
|
+
end
|
29
|
+
it '.middle' do
|
30
|
+
expect(n.middle).to be_nil
|
31
|
+
end
|
32
|
+
it '.last' do
|
33
|
+
expect(n.last).to eq('Horn')
|
34
|
+
end
|
35
|
+
it '.suffix' do
|
36
|
+
expect(n.suffix).to be_nil
|
37
|
+
end
|
36
38
|
end
|
37
|
-
end
|
38
39
|
|
39
|
-
context('with an all uppercase name') do
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
40
|
+
context('with an all uppercase name') do
|
41
|
+
subject(:n) { Nameable::Latin.new.parse("CHRIS HORN") }
|
42
|
+
it '.first' do
|
43
|
+
expect(n.first).to eq('Chris')
|
44
|
+
end
|
45
|
+
it '.last' do
|
46
|
+
expect(n.last).to eq('Horn')
|
47
|
+
end
|
46
48
|
end
|
47
|
-
end
|
48
49
|
|
49
|
-
context('with an all lowercase name') do
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
50
|
+
context('with an all lowercase name') do
|
51
|
+
subject(:n) { Nameable::Latin.new.parse("chris horn") }
|
52
|
+
it '.first' do
|
53
|
+
expect(n.first).to eq('Chris')
|
54
|
+
end
|
55
|
+
it '.last' do
|
56
|
+
expect(n.last).to eq('Horn')
|
57
|
+
end
|
56
58
|
end
|
57
|
-
end
|
58
59
|
|
59
|
-
context('with a mixed case name') do
|
60
|
-
|
61
|
-
|
62
|
-
|
60
|
+
context('with a mixed case name') do
|
61
|
+
subject(:n) { Nameable::Latin.new.parse("DeChris HORN") }
|
62
|
+
it '.first' do
|
63
|
+
expect(n.first).to eq('DeChris')
|
64
|
+
end
|
63
65
|
end
|
64
|
-
end
|
65
66
|
|
66
|
-
context('with a simple middle name') do
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
67
|
+
context('with a simple middle name') do
|
68
|
+
subject(:n) { Nameable::Latin.new.parse("Chris Derp Horn") }
|
69
|
+
it '.prefix' do
|
70
|
+
expect(n.prefix).to be_nil
|
71
|
+
end
|
72
|
+
it '.first' do
|
73
|
+
expect(n.first).to eq('Chris')
|
74
|
+
end
|
75
|
+
it '.middle' do
|
76
|
+
expect(n.middle).to eq('Derp')
|
77
|
+
end
|
78
|
+
it '.last' do
|
79
|
+
expect(n.last).to eq('Horn')
|
80
|
+
end
|
81
|
+
it '.suffix' do
|
82
|
+
expect(n.suffix).to be_nil
|
83
|
+
end
|
82
84
|
end
|
83
|
-
end
|
84
85
|
|
85
|
-
context('with a simple prefix') do
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
86
|
+
context('with a simple prefix') do
|
87
|
+
subject(:n) { Nameable::Latin.new.parse("Sir Chris Horn") }
|
88
|
+
it '.prefix' do
|
89
|
+
expect(n.prefix).to eq('Sir')
|
90
|
+
end
|
91
|
+
it '.first' do
|
92
|
+
expect(n.first).to eq('Chris')
|
93
|
+
end
|
94
|
+
it '.middle' do
|
95
|
+
expect(n.middle).to be_nil
|
96
|
+
end
|
97
|
+
it '.last' do
|
98
|
+
expect(n.last).to eq('Horn')
|
99
|
+
end
|
100
|
+
it '.suffix' do
|
101
|
+
expect(n.suffix).to be_nil
|
102
|
+
end
|
101
103
|
end
|
102
|
-
end
|
103
104
|
|
104
|
-
context('with a simple suffix') do
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
105
|
+
context('with a simple suffix') do
|
106
|
+
subject(:n) { Nameable::Latin.new.parse("Chris Horn PhD") }
|
107
|
+
it '.prefix' do
|
108
|
+
expect(n.prefix).to be_nil
|
109
|
+
end
|
110
|
+
it '.first' do
|
111
|
+
expect(n.first).to eq('Chris')
|
112
|
+
end
|
113
|
+
it '.middle' do
|
114
|
+
expect(n.middle).to be_nil
|
115
|
+
end
|
116
|
+
it '.last' do
|
117
|
+
expect(n.last).to eq('Horn')
|
118
|
+
end
|
119
|
+
it '.suffix' do
|
120
|
+
expect(n.suffix).to eq('Ph.D.')
|
121
|
+
end
|
120
122
|
end
|
121
|
-
end
|
122
123
|
|
123
|
-
context('prefix patterns') do
|
124
|
-
|
125
|
-
|
126
|
-
|
124
|
+
context('prefix patterns') do
|
125
|
+
%w{Mr Mr. Mister}.each do |prefix|
|
126
|
+
it prefix do
|
127
|
+
expect(Nameable::Latin.new.parse("#{prefix} Chris Horn").prefix).to eq('Mr.')
|
128
|
+
end
|
127
129
|
end
|
128
|
-
end
|
129
130
|
|
130
|
-
|
131
|
-
|
132
|
-
|
131
|
+
%w{Mrs Mrs. Misses}.each do |prefix|
|
132
|
+
it prefix do
|
133
|
+
expect(Nameable::Latin.new.parse("#{prefix} Chris Horn").prefix).to eq('Mrs.')
|
134
|
+
end
|
133
135
|
end
|
134
|
-
end
|
135
136
|
|
136
|
-
|
137
|
-
|
138
|
-
|
137
|
+
%w{Ms Ms. Miss}.each do |prefix|
|
138
|
+
it prefix do
|
139
|
+
expect(Nameable::Latin.new.parse("#{prefix} Chris Horn").prefix).to eq('Ms.')
|
140
|
+
end
|
139
141
|
end
|
140
|
-
end
|
141
142
|
|
142
|
-
|
143
|
-
|
144
|
-
|
143
|
+
%w{Dr Dr. Doctor}.each do |prefix|
|
144
|
+
it prefix do
|
145
|
+
expect(Nameable::Latin.new.parse("#{prefix} Chris Horn").prefix).to eq('Dr.')
|
146
|
+
end
|
145
147
|
end
|
146
|
-
end
|
147
148
|
|
148
|
-
|
149
|
-
|
150
|
-
|
149
|
+
%w{Rev Rev. Reverand}.each do |prefix|
|
150
|
+
it prefix do
|
151
|
+
expect(Nameable::Latin.new.parse("#{prefix} Chris Horn").prefix).to eq('Rev.')
|
152
|
+
end
|
151
153
|
end
|
152
|
-
end
|
153
154
|
|
154
|
-
|
155
|
-
|
156
|
-
|
155
|
+
%w{Fr Fr. Friar}.each do |prefix|
|
156
|
+
it prefix do
|
157
|
+
expect(Nameable::Latin.new.parse("#{prefix} Chris Horn").prefix).to eq('Fr.')
|
158
|
+
end
|
157
159
|
end
|
158
|
-
end
|
159
160
|
|
160
|
-
|
161
|
-
|
162
|
-
|
161
|
+
%w{Master Sir}.each do |prefix|
|
162
|
+
it prefix do
|
163
|
+
expect(Nameable::Latin.new.parse("#{prefix} Chris Horn").prefix).to eq(prefix)
|
164
|
+
end
|
163
165
|
end
|
166
|
+
|
164
167
|
end
|
165
168
|
|
166
|
-
|
169
|
+
context('suffix patterns (formatted)') do
|
170
|
+
%w{Sr Sr. Senior}.each do |suffix|
|
171
|
+
it suffix do
|
172
|
+
expect(Nameable::Latin.new.parse("Chris Horn #{suffix}").suffix).to eq('Sr.')
|
173
|
+
end
|
174
|
+
end
|
167
175
|
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
176
|
+
%w{Jr Jr. Junior}.each do |suffix|
|
177
|
+
it suffix do
|
178
|
+
expect(Nameable::Latin.new.parse("Chris Horn #{suffix}").suffix).to eq('Jr.')
|
179
|
+
end
|
172
180
|
end
|
173
|
-
end
|
174
181
|
|
175
|
-
|
176
|
-
|
177
|
-
|
182
|
+
%w{Esq Esq. Esquire}.each do |suffix|
|
183
|
+
it suffix do
|
184
|
+
expect(Nameable::Latin.new.parse("Chris Horn #{suffix}").suffix).to eq('Esq.')
|
185
|
+
end
|
178
186
|
end
|
179
|
-
end
|
180
187
|
|
181
|
-
|
182
|
-
|
183
|
-
|
188
|
+
%w{PHD PhD Ph.D Ph.D. P.H.D.}.each do |suffix|
|
189
|
+
it suffix do
|
190
|
+
expect(Nameable::Latin.new.parse("Chris Horn #{suffix}").suffix).to eq('Ph.D.')
|
191
|
+
end
|
184
192
|
end
|
193
|
+
|
185
194
|
end
|
186
195
|
|
187
|
-
|
188
|
-
|
189
|
-
|
196
|
+
context('suffix patterns (generational)') do
|
197
|
+
%w{ii III iv V VI ix Xiii}.each do |suffix|
|
198
|
+
it suffix do
|
199
|
+
expect(Nameable::Latin.new.parse("Chris Horn #{suffix}").suffix).to eq(suffix.upcase)
|
200
|
+
end
|
190
201
|
end
|
191
202
|
end
|
192
203
|
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
expect(Nameable::Latin.new.parse("Chris Horn #{suffix}").suffix).to eq(suffix.upcase)
|
204
|
+
context('suffix patterns (common)') do
|
205
|
+
%w{APR RPh MD MA DMD DDS PharmD EngD DPhil JD DD DO BA BS BSc BE BFA MA MS MSc MFA MLA MBA PE CSA CPA CPL CME CEng OFM CSV}.each do |suffix|
|
206
|
+
it suffix do
|
207
|
+
expect(Nameable::Latin.new.parse("Chris Horn #{suffix}").suffix).to eq(suffix.upcase)
|
208
|
+
end
|
199
209
|
end
|
200
210
|
end
|
201
|
-
end
|
202
211
|
|
203
|
-
context('suffix patterns (
|
204
|
-
|
205
|
-
|
206
|
-
expect(Nameable::Latin.new.parse("Chris Horn #{suffix}").suffix).to eq(suffix.upcase)
|
212
|
+
context('suffix patterns (generic uppercase)') do
|
213
|
+
it 'generic DERP suffix' do
|
214
|
+
expect(Nameable::Latin.new.parse("Chris Horn DERP").suffix).to eq('DERP')
|
207
215
|
end
|
208
|
-
end
|
209
|
-
end
|
210
216
|
|
211
|
-
|
212
|
-
|
213
|
-
|
217
|
+
it 'no generic DERP suffix when all uppercase name' do
|
218
|
+
expect(Nameable::Latin.new.parse("CHRIS HORN DERP").suffix).to be_nil
|
219
|
+
end
|
214
220
|
end
|
215
221
|
|
216
|
-
|
217
|
-
|
222
|
+
context('multi word last names') do
|
223
|
+
%w{mc vere von van da de del della di da pietro vanden du st la ter ten}.each do |prefix|
|
224
|
+
it "#{prefix} Last" do
|
225
|
+
expect(Nameable::Latin.new.parse("Chris #{prefix} Last").last).to eq("#{prefix.downcase.capitalize} Last")
|
226
|
+
end
|
227
|
+
end
|
218
228
|
end
|
219
|
-
end
|
220
229
|
|
221
|
-
context('
|
222
|
-
|
223
|
-
|
224
|
-
expect(Nameable::Latin.new.parse("Chris #{prefix} Last").last).to eq("#{prefix.downcase.capitalize} Last")
|
230
|
+
context("o'last-name") do
|
231
|
+
it "O'Horn" do
|
232
|
+
expect(Nameable::Latin.new.parse("Chris O'Horn").last).to eq("O'Horn")
|
225
233
|
end
|
226
|
-
end
|
227
|
-
end
|
228
234
|
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
end
|
235
|
+
it "O`Horn" do
|
236
|
+
expect(Nameable::Latin.new.parse("Chris O`Horn").last).to eq("O'Horn")
|
237
|
+
end
|
233
238
|
|
234
|
-
|
235
|
-
|
239
|
+
it "O' Horn" do
|
240
|
+
expect(Nameable::Latin.new.parse("Chris O' Horn").last).to eq("O'Horn")
|
241
|
+
end
|
236
242
|
end
|
237
243
|
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
end
|
244
|
+
context("hyphenated last names") do
|
245
|
+
it "Horn - Derp" do
|
246
|
+
expect(Nameable::Latin.new.parse("Chris Horn - Derp").last).to eq("Horn-Derp")
|
247
|
+
end
|
242
248
|
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
end
|
249
|
+
it "Horn-Derp" do
|
250
|
+
expect(Nameable::Latin.new.parse("Chris Horn-Derp").last).to eq("Horn-Derp")
|
251
|
+
end
|
247
252
|
|
248
|
-
|
249
|
-
|
250
|
-
|
253
|
+
it "Horn--Derp" do
|
254
|
+
expect(Nameable::Latin.new.parse("Chris Horn--Derp").last).to eq("Horn-Derp")
|
255
|
+
end
|
251
256
|
|
252
|
-
|
253
|
-
|
257
|
+
it "Horn -- Derp" do
|
258
|
+
expect(Nameable::Latin.new.parse("Chris Horn--Derp").last).to eq("Horn-Derp")
|
259
|
+
end
|
254
260
|
end
|
255
261
|
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
end
|
262
|
+
context("gender") do
|
263
|
+
it "Chris is more likely to be male" do
|
264
|
+
expect(Nameable::Latin.new.parse("Chris Horn").male?).to be true
|
265
|
+
end
|
260
266
|
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
end
|
267
|
+
it "Janine is more likely to be female" do
|
268
|
+
expect(Nameable::Latin.new.parse("Janine Horn").female?).to be true
|
269
|
+
end
|
265
270
|
|
266
|
-
|
267
|
-
|
271
|
+
it "Derp has :unknown gender" do
|
272
|
+
expect(Nameable::Latin.new.parse("Derp Horn").gender).to eq(:unknown)
|
273
|
+
end
|
268
274
|
end
|
269
275
|
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
end
|
276
|
+
context("ethnicity") do
|
277
|
+
it "Horn has a hash of ethnicity results" do
|
278
|
+
expect(Nameable::Latin.new.parse("Chris Horn").ethnicity).to be_a Hash
|
279
|
+
end
|
274
280
|
|
275
|
-
|
276
|
-
|
277
|
-
|
281
|
+
it "Horn's census :percent_white > 80% " do
|
282
|
+
expect(Nameable::Latin.new.parse("Chris Horn").ethnicity[:percent_white]).to be >= 80
|
283
|
+
end
|
278
284
|
end
|
279
285
|
|
280
|
-
it "Horn's census :percent_white > 80% " do
|
281
|
-
expect(Nameable::Latin.new.parse("Chris Horn").ethnicity[:percent_white]).to be >= 80
|
282
|
-
end
|
283
286
|
end
|
284
|
-
|