address-matcher 0.0.1 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/VERSION +1 -0
- data/address_matcher.gemspec +1 -1
- data/spec/address_group_spec.rb +11 -28
- data/spec/address_library_spec.rb +58 -54
- data/spec/data/geocoder_data.yaml +89 -0
- data/spec/spec_helper.rb +6 -6
- data/spec/support/geocoder.rb +23 -73
- metadata +3 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3d2d27af283ba186e00ff6ddbb3055b509b8e0b4
|
4
|
+
data.tar.gz: 5ceafeb2391eb02c0b3b037f5142f4b8e6082024
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 106dc2f97921d4cf2c5a0d19a815574477ca537106bad49e2cd67eb03ae7e75411a96ad91f21e4f77e1e6e2d6f637e8e9724c94983d8271c7200466e1b5b25a2
|
7
|
+
data.tar.gz: a0b5921cb6120bfae41c0e630c813fee91f28d968b4f3049f1f2280a2a401306be8faa1b0308b5f2bcf797e6a9195c04f470925e7495730214a9ce2b642f0d22
|
data/VERSION
CHANGED
@@ -0,0 +1 @@
|
|
1
|
+
0.1.0
|
data/address_matcher.gemspec
CHANGED
data/spec/address_group_spec.rb
CHANGED
@@ -1,49 +1,32 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe AddressGroup do
|
4
|
-
|
5
|
-
{ lat_long: [42.3426, -71.0858],
|
6
|
-
address: '301 Massachusetts Ave, Boston, MA 02115'
|
7
|
-
}
|
8
|
-
end
|
9
|
-
|
10
|
-
let(:nec) do
|
11
|
-
{ lat_long: [42.3406, -71.0869],
|
12
|
-
address: '290 Huntington Ave, Boston, MA 02115'
|
13
|
-
}
|
14
|
-
end
|
15
|
-
|
16
|
-
let(:boco) do
|
17
|
-
{ lat_long: [42.3462, -71.0901],
|
18
|
-
address: '8 Fenway, Boston, MA 02215'
|
19
|
-
}
|
20
|
-
end
|
21
|
-
|
4
|
+
include Locations
|
22
5
|
|
23
6
|
it 'stores addresses keyed by lat/long' do
|
24
7
|
address_group = AddressGroup.new
|
25
|
-
address_group[symphony_hall
|
8
|
+
address_group[symphony_hall.coords] = symphony_hall.address
|
26
9
|
|
27
|
-
expect(address_group[symphony_hall
|
10
|
+
expect(address_group[symphony_hall.coords]).to eq symphony_hall.address
|
28
11
|
end
|
29
12
|
|
30
13
|
it 'returns the address of an exact lat/long match' do
|
31
14
|
address_group = AddressGroup.new
|
32
|
-
address_group[symphony_hall
|
33
|
-
address_group[nec
|
15
|
+
address_group[symphony_hall.coords] = symphony_hall.address
|
16
|
+
address_group[nec.coords] = nec.address
|
34
17
|
|
35
|
-
match = address_group.match(symphony_hall
|
18
|
+
match = address_group.match(symphony_hall.coords)
|
36
19
|
|
37
|
-
expect(match).to eq symphony_hall
|
20
|
+
expect(match).to eq symphony_hall.address
|
38
21
|
end
|
39
22
|
|
40
23
|
it 'returns the address of the closest lat/long if there is not an exact match' do
|
41
24
|
address_group = AddressGroup.new
|
42
|
-
address_group[boco
|
43
|
-
address_group[nec
|
25
|
+
address_group[boco.coords] = boco.address
|
26
|
+
address_group[nec.coords] = nec.address
|
44
27
|
|
45
|
-
match = address_group.match(symphony_hall
|
28
|
+
match = address_group.match(symphony_hall.coords)
|
46
29
|
|
47
|
-
expect(match).to eq nec
|
30
|
+
expect(match).to eq nec.address
|
48
31
|
end
|
49
32
|
end
|
@@ -1,120 +1,124 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe AddressLibrary do
|
4
|
+
include Locations
|
5
|
+
|
4
6
|
it 'geocodes an address' do
|
5
7
|
allow(Geocoder).to receive(:search).and_call_original
|
6
8
|
|
7
|
-
AddressLibrary.new.add_address(
|
9
|
+
AddressLibrary.new.add_address(met_opera_short.address)
|
8
10
|
|
9
11
|
expect(Geocoder).to(
|
10
|
-
have_received(:search).with(
|
12
|
+
have_received(:search).with(met_opera_short.address)
|
11
13
|
)
|
12
14
|
end
|
13
15
|
|
14
16
|
it 'adds address to an AddressGroup indexed by lat-long to 3 digit precision' do
|
15
|
-
lib = AddressLibrary.new.add_address(
|
17
|
+
lib = AddressLibrary.new.add_address(met_opera_short.address)
|
16
18
|
|
17
|
-
group = lib.near(
|
19
|
+
group = lib.near(met_opera_short.coords)
|
18
20
|
|
19
21
|
expect(group).to be_an_instance_of AddressGroup
|
20
|
-
expect(group[
|
21
|
-
eq
|
22
|
+
expect(group[met_opera_short.coords]).to(
|
23
|
+
eq met_opera_short.address
|
22
24
|
)
|
23
25
|
end
|
24
26
|
|
25
27
|
it 'adds multiple nearby addresses to the same AddressGroup' do
|
26
28
|
lib = AddressLibrary.new
|
27
|
-
.add_address(
|
28
|
-
.add_address(
|
29
|
+
.add_address(met_art_avenue.address)
|
30
|
+
.add_address(met_next_door.address)
|
29
31
|
|
30
|
-
group = lib.near(
|
32
|
+
group = lib.near(met_art_avenue.coords)
|
31
33
|
|
32
|
-
expect(group[
|
33
|
-
eq
|
34
|
+
expect(group[met_art_avenue.coords]).to(
|
35
|
+
eq met_art_avenue.address
|
34
36
|
)
|
35
|
-
expect(group[
|
36
|
-
eq
|
37
|
+
expect(group[met_next_door.coords]).to(
|
38
|
+
eq met_next_door.address
|
37
39
|
)
|
38
40
|
end
|
39
41
|
|
40
42
|
it 'adds multiple far-apart addresses to different AddressGroups' do
|
41
43
|
lib = AddressLibrary.new
|
42
|
-
.add_address(
|
43
|
-
.add_address(
|
44
|
+
.add_address(met_art_avenue.address)
|
45
|
+
.add_address(met_opera_short.address)
|
44
46
|
|
45
|
-
group_1 = lib.near(
|
46
|
-
group_2 = lib.near(
|
47
|
+
group_1 = lib.near(met_art_avenue.coords)
|
48
|
+
group_2 = lib.near(met_opera_short.coords)
|
47
49
|
|
48
|
-
expect(group_1[
|
49
|
-
eq
|
50
|
+
expect(group_1[met_art_avenue.coords]).to(
|
51
|
+
eq met_art_avenue.address
|
50
52
|
)
|
51
|
-
expect(group_2[
|
52
|
-
expect(group_1[
|
53
|
-
expect(group_2[
|
54
|
-
eq
|
53
|
+
expect(group_2[met_art_avenue.coords]).to be_nil
|
54
|
+
expect(group_1[met_opera_short.coords]).to be_nil
|
55
|
+
expect(group_2[met_opera_short.coords]).to(
|
56
|
+
eq met_opera_short.address
|
55
57
|
)
|
56
58
|
end
|
57
59
|
|
58
60
|
it 'adds an array of addresses' do
|
59
|
-
addresses = [
|
60
|
-
|
61
|
-
|
62
|
-
|
61
|
+
addresses = [met_opera_short.address,
|
62
|
+
met_art_ave.address,
|
63
|
+
apartments_1001.address,
|
64
|
+
met_next_door.address
|
63
65
|
]
|
64
66
|
|
65
67
|
lib = AddressLibrary.build(addresses)
|
66
68
|
|
67
|
-
group_1 = lib.near(
|
68
|
-
group_2 = lib.near(
|
69
|
-
group_3 = lib.near(
|
69
|
+
group_1 = lib.near(met_art_ave.coords)
|
70
|
+
group_2 = lib.near(met_opera_short.coords)
|
71
|
+
group_3 = lib.near(apartments_1001.coords)
|
70
72
|
|
71
|
-
expect(group_1[
|
72
|
-
eq
|
73
|
+
expect(group_1[met_art_ave.coords]).to(
|
74
|
+
eq met_art_ave.address
|
73
75
|
)
|
74
|
-
expect(group_1[
|
75
|
-
eq
|
76
|
+
expect(group_1[met_next_door.coords]).to(
|
77
|
+
eq met_next_door.address
|
76
78
|
)
|
77
|
-
expect(group_2[
|
78
|
-
eq
|
79
|
+
expect(group_2[met_opera_short.coords]).to(
|
80
|
+
eq met_opera_short.address
|
79
81
|
)
|
80
|
-
expect(group_3[
|
81
|
-
eq
|
82
|
+
expect(group_3[apartments_1001.coords]).to(
|
83
|
+
eq apartments_1001.address
|
82
84
|
)
|
83
85
|
end
|
84
86
|
|
85
87
|
describe '#near' do
|
86
88
|
it 'returns the address group indexed at the 3-digit precision for a given set of coordinates' do
|
87
89
|
lib = AddressLibrary.new
|
88
|
-
.add_address(
|
89
|
-
.add_address(
|
90
|
+
.add_address(met_art_avenue.address)
|
91
|
+
.add_address(met_opera_long.address)
|
90
92
|
|
91
|
-
group_1 = lib.near(
|
92
|
-
group_2 = lib.near(
|
93
|
+
group_1 = lib.near(met_art_avenue.coords)
|
94
|
+
group_2 = lib.near(met_opera_long.coords)
|
93
95
|
|
94
|
-
expect(group_1[
|
95
|
-
eq
|
96
|
+
expect(group_1[met_art_avenue.coords]).to(
|
97
|
+
eq met_art_avenue.address
|
96
98
|
)
|
97
|
-
expect(
|
98
|
-
expect(
|
99
|
-
expect(group_2[
|
100
|
-
eq
|
99
|
+
expect(group_1[met_opera_long.coords]).to be_nil
|
100
|
+
expect(group_2[met_art_avenue.coords]).to be_nil
|
101
|
+
expect(group_2[met_opera_long.coords]).to(
|
102
|
+
eq met_opera_long.address
|
101
103
|
)
|
102
104
|
end
|
103
105
|
end
|
104
106
|
|
105
107
|
describe '#match' do
|
106
108
|
it 'returns the address which most nearly matches the given address' do
|
107
|
-
addresses = [
|
108
|
-
|
109
|
-
|
110
|
-
|
109
|
+
addresses = [met_opera_short.address,
|
110
|
+
met_art_ave.address,
|
111
|
+
apartments_1001.address,
|
112
|
+
met_next_door.address
|
111
113
|
]
|
112
114
|
|
113
115
|
lib = AddressLibrary.build(addresses)
|
114
116
|
|
115
|
-
|
117
|
+
match_1 = lib.match(met_art_avenue.address)
|
118
|
+
match_2 = lib.match(met_opera_long.address)
|
116
119
|
|
117
|
-
expect(
|
120
|
+
expect(match_1).to eq met_art_ave.address
|
121
|
+
expect(match_2).to eq met_opera_short.address
|
118
122
|
end
|
119
123
|
end
|
120
124
|
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
met_opera_long:
|
2
|
+
address: 'Lincoln Center for the Performing Arts, 30 Lincoln Center Plaza, New York, NY 10023'
|
3
|
+
latitude: 40.772748
|
4
|
+
longitude: -73.98384759999
|
5
|
+
canonical_address: '30 Lincoln Center Plaza, New York, NY 10023'
|
6
|
+
state: 'New York'
|
7
|
+
state_code: 'NY'
|
8
|
+
country: 'United States'
|
9
|
+
country_code: 'US'
|
10
|
+
|
11
|
+
met_opera_short:
|
12
|
+
address: '30 Lincoln Center Plaza, New York, NY 10023'
|
13
|
+
latitude: 40.772748
|
14
|
+
longitude: -73.98384759999
|
15
|
+
canonical_address: '30 Lincoln Center Plaza, New York, NY 10023'
|
16
|
+
state: 'New York'
|
17
|
+
state_code: 'NY'
|
18
|
+
country: 'United States'
|
19
|
+
country_code: 'US'
|
20
|
+
|
21
|
+
met_art_ave:
|
22
|
+
address: '1000 5th Ave, New York, NY 10028'
|
23
|
+
latitude: 40.77916555
|
24
|
+
longitude: -73.9629278
|
25
|
+
canonical_address: '1000 5th Ave, New York, NY 10028'
|
26
|
+
state: 'New York'
|
27
|
+
state_code: 'NY'
|
28
|
+
country: 'United States'
|
29
|
+
country_code: 'US'
|
30
|
+
|
31
|
+
met_art_avenue:
|
32
|
+
address: '1000 5th Avenue, New York, NY 10028'
|
33
|
+
latitude: 40.7791655
|
34
|
+
longitude: -73.9629278
|
35
|
+
canonical_address: '1000 5th Ave, New York, NY 10028'
|
36
|
+
state: 'New York'
|
37
|
+
state_code: 'NY'
|
38
|
+
country: 'United States'
|
39
|
+
country_code: 'US'
|
40
|
+
|
41
|
+
apartments_1001:
|
42
|
+
address: '1001 5th Avenue, New York, NY 10028'
|
43
|
+
latitude: 40.7785889
|
44
|
+
longitude: -73.9621559
|
45
|
+
canonical_address: '1000 5th Ave, New York, NY 10028'
|
46
|
+
state: 'New York'
|
47
|
+
state_code: 'NY'
|
48
|
+
country: 'United States'
|
49
|
+
country_code: 'US'
|
50
|
+
|
51
|
+
met_next_door:
|
52
|
+
address: '1002 5th Avenue, New York, NY 10028'
|
53
|
+
latitude: 40.7785016
|
54
|
+
longitude: -73.9625847
|
55
|
+
canonical_address: '1002 5th Ave, New York, NY 10028'
|
56
|
+
state: 'New York'
|
57
|
+
state_code: 'NY'
|
58
|
+
country: 'United States'
|
59
|
+
country_code: 'US'
|
60
|
+
|
61
|
+
symphony_hall:
|
62
|
+
address: '301 Massachusetts Ave, Boston, MA 02115'
|
63
|
+
latitude: 42.3426
|
64
|
+
longitude: -71.0858
|
65
|
+
canonical_address: '301 Massachusetts Ave, Boston, MA 02115'
|
66
|
+
state: 'Massachusetts'
|
67
|
+
state_code: 'MA'
|
68
|
+
country: 'United States'
|
69
|
+
country_code: 'US'
|
70
|
+
|
71
|
+
nec:
|
72
|
+
address: '290 Huntington Ave, Boston, MA 02115'
|
73
|
+
latitude: 42.3406
|
74
|
+
longitude: -71.0869
|
75
|
+
canonical_address: '290 Huntington Ave, Boston, MA 02115'
|
76
|
+
state: 'Massachusetts'
|
77
|
+
state_code: 'MA'
|
78
|
+
country: 'United States'
|
79
|
+
country_code: 'US'
|
80
|
+
|
81
|
+
boco:
|
82
|
+
address: '8 Fenway, Boston, MA 02215'
|
83
|
+
latitude: 42.3462
|
84
|
+
longitude: -71.0901
|
85
|
+
canonical_address: '8 Fenway, Boston, MA 02215'
|
86
|
+
state: 'Massachusetts'
|
87
|
+
state_code: 'MA'
|
88
|
+
country: 'United States'
|
89
|
+
country_code: 'US'
|
data/spec/spec_helper.rb
CHANGED
@@ -1,5 +1,10 @@
|
|
1
|
-
require '
|
1
|
+
require 'geocoder'
|
2
|
+
require 'ostruct'
|
2
3
|
require 'pry'
|
4
|
+
require 'rspec'
|
5
|
+
require 'simplecov'
|
6
|
+
require 'yaml'
|
7
|
+
require_relative 'support/geocoder'
|
3
8
|
|
4
9
|
SimpleCov.start do
|
5
10
|
add_filter 'spec/'
|
@@ -9,14 +14,9 @@ end
|
|
9
14
|
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
10
15
|
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
11
16
|
|
12
|
-
require 'geocoder'
|
13
|
-
require_relative 'support/geocoder'
|
14
|
-
|
15
17
|
Dir['./spec/shared/**/*.rb'].sort.each { |f| require f }
|
16
18
|
require_relative '../lib/address_matcher'
|
17
19
|
|
18
|
-
require 'rspec'
|
19
|
-
|
20
20
|
RSpec.configure do |config|
|
21
21
|
config.order = 'random'
|
22
22
|
end
|
data/spec/support/geocoder.rb
CHANGED
@@ -1,77 +1,27 @@
|
|
1
1
|
Geocoder.configure(lookup: :test)
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
'longitude' => -73.98384759999,
|
7
|
-
'address' => '30 Lincoln Center Plaza, New York, NY 10023',
|
8
|
-
'state' => 'New York',
|
9
|
-
'state_code' => 'NY',
|
10
|
-
'country' => 'United States',
|
11
|
-
'country_code' => 'US'
|
12
|
-
}
|
13
|
-
]
|
14
|
-
)
|
15
|
-
Geocoder::Lookup::Test.add_stub(
|
16
|
-
'30 Lincoln Center Plaza, New York, NY 10023', [
|
17
|
-
{ 'latitude' => 40.772748,
|
18
|
-
'longitude' => -73.98384759999,
|
19
|
-
'address' => '30 Lincoln Center Plaza, New York, NY 10023',
|
20
|
-
'state' => 'New York',
|
21
|
-
'state_code' => 'NY',
|
22
|
-
'country' => 'United States',
|
23
|
-
'country_code' => 'US'
|
24
|
-
}
|
25
|
-
]
|
26
|
-
)
|
3
|
+
module Locations
|
4
|
+
DATA_PATH = Pathname.new('spec/data')
|
5
|
+
TEST_DATA = YAML.load(File.read(DATA_PATH.join('geocoder_data.yaml')))
|
27
6
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
'state_code' => 'NY',
|
35
|
-
'country' => 'United States',
|
36
|
-
'country_code' => 'US'
|
37
|
-
}
|
38
|
-
]
|
39
|
-
)
|
40
|
-
Geocoder::Lookup::Test.add_stub(
|
41
|
-
'1000 5th Avenue, New York, NY 10028', [
|
42
|
-
{ 'latitude' => 40.7791655,
|
43
|
-
'longitude' => -73.9629278,
|
44
|
-
'address' => '1000 5th Ave, New York, NY 10028',
|
45
|
-
'state' => 'New York',
|
46
|
-
'state_code' => 'NY',
|
47
|
-
'country' => 'United States',
|
48
|
-
'country_code' => 'US'
|
49
|
-
}
|
50
|
-
]
|
51
|
-
)
|
7
|
+
TEST_DATA.each do |location, data|
|
8
|
+
define_method location do
|
9
|
+
OpenStruct.new(data.merge(coords: [data['latitude'], data['longitude']]))
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
52
13
|
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
'
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
'1002 5th Avenue, New York, NY 10028', [
|
68
|
-
{ 'latitude' => 40.7785016,
|
69
|
-
'longitude' => -73.9625847,
|
70
|
-
'address' => '1002 5th Ave, New York, NY 10028',
|
71
|
-
'state' => 'New York',
|
72
|
-
'state_code' => 'NY',
|
73
|
-
'country' => 'United States',
|
74
|
-
'country_code' => 'US'
|
75
|
-
}
|
76
|
-
]
|
77
|
-
)
|
14
|
+
Locations::TEST_DATA.values.each do |location|
|
15
|
+
Geocoder::Lookup::Test.add_stub(
|
16
|
+
location['address'], [
|
17
|
+
{ 'latitude' => location['latitude'],
|
18
|
+
'longitude' => location['longitude'],
|
19
|
+
'address' => location['canonical_address'],
|
20
|
+
'state' => location['state'],
|
21
|
+
'state_code' => location['state_code'],
|
22
|
+
'country' => location['country'],
|
23
|
+
'country_code' => location['country_code']
|
24
|
+
}
|
25
|
+
]
|
26
|
+
)
|
27
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: address-matcher
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Stuart Terrett
|
@@ -98,6 +98,7 @@ files:
|
|
98
98
|
- lib/address_matcher/address_library.rb
|
99
99
|
- spec/address_group_spec.rb
|
100
100
|
- spec/address_library_spec.rb
|
101
|
+
- spec/data/geocoder_data.yaml
|
101
102
|
- spec/spec_helper.rb
|
102
103
|
- spec/support/geocoder.rb
|
103
104
|
homepage: http://github.com/shterrett/address_matcher
|
@@ -127,5 +128,6 @@ summary: Matches addresses by geocoding
|
|
127
128
|
test_files:
|
128
129
|
- spec/address_group_spec.rb
|
129
130
|
- spec/address_library_spec.rb
|
131
|
+
- spec/data/geocoder_data.yaml
|
130
132
|
- spec/spec_helper.rb
|
131
133
|
- spec/support/geocoder.rb
|