geocoder2 0.1.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.
- data/.gitignore +5 -0
- data/.travis.yml +27 -0
- data/CHANGELOG.md +329 -0
- data/LICENSE +20 -0
- data/README.md +796 -0
- data/Rakefile +25 -0
- data/bin/geocode2 +5 -0
- data/examples/autoexpire_cache_dalli.rb +62 -0
- data/examples/autoexpire_cache_redis.rb +28 -0
- data/examples/cache_bypass.rb +48 -0
- data/gemfiles/Gemfile.mongoid-2.4.x +15 -0
- data/json?address=26+leonard+street%2C+Belmont&key=AIzaSyDoltU6YL8XeIQrSLFGk6ZfpKaWkPukwYQ&language=en +68 -0
- data/lib/generators/geocoder2/config/config_generator.rb +14 -0
- data/lib/generators/geocoder2/config/templates/initializer.rb +21 -0
- data/lib/geocoder2/cache.rb +89 -0
- data/lib/geocoder2/calculations.rb +389 -0
- data/lib/geocoder2/cli.rb +121 -0
- data/lib/geocoder2/configuration.rb +130 -0
- data/lib/geocoder2/configuration_hash.rb +11 -0
- data/lib/geocoder2/exceptions.rb +21 -0
- data/lib/geocoder2/lookup.rb +86 -0
- data/lib/geocoder2/lookups/baidu.rb +54 -0
- data/lib/geocoder2/lookups/base.rb +266 -0
- data/lib/geocoder2/lookups/bing.rb +47 -0
- data/lib/geocoder2/lookups/dstk.rb +20 -0
- data/lib/geocoder2/lookups/esri.rb +48 -0
- data/lib/geocoder2/lookups/freegeoip.rb +43 -0
- data/lib/geocoder2/lookups/geocoder_ca.rb +54 -0
- data/lib/geocoder2/lookups/geocoder_us.rb +39 -0
- data/lib/geocoder2/lookups/google.rb +69 -0
- data/lib/geocoder2/lookups/google_premier.rb +47 -0
- data/lib/geocoder2/lookups/mapquest.rb +59 -0
- data/lib/geocoder2/lookups/maxmind.rb +88 -0
- data/lib/geocoder2/lookups/nominatim.rb +44 -0
- data/lib/geocoder2/lookups/ovi.rb +62 -0
- data/lib/geocoder2/lookups/test.rb +44 -0
- data/lib/geocoder2/lookups/yahoo.rb +86 -0
- data/lib/geocoder2/lookups/yandex.rb +54 -0
- data/lib/geocoder2/models/active_record.rb +46 -0
- data/lib/geocoder2/models/base.rb +42 -0
- data/lib/geocoder2/models/mongo_base.rb +60 -0
- data/lib/geocoder2/models/mongo_mapper.rb +26 -0
- data/lib/geocoder2/models/mongoid.rb +32 -0
- data/lib/geocoder2/query.rb +107 -0
- data/lib/geocoder2/railtie.rb +26 -0
- data/lib/geocoder2/request.rb +23 -0
- data/lib/geocoder2/results/baidu.rb +79 -0
- data/lib/geocoder2/results/base.rb +67 -0
- data/lib/geocoder2/results/bing.rb +48 -0
- data/lib/geocoder2/results/dstk.rb +6 -0
- data/lib/geocoder2/results/esri.rb +51 -0
- data/lib/geocoder2/results/freegeoip.rb +45 -0
- data/lib/geocoder2/results/geocoder_ca.rb +60 -0
- data/lib/geocoder2/results/geocoder_us.rb +39 -0
- data/lib/geocoder2/results/google.rb +124 -0
- data/lib/geocoder2/results/google_premier.rb +6 -0
- data/lib/geocoder2/results/mapquest.rb +51 -0
- data/lib/geocoder2/results/maxmind.rb +135 -0
- data/lib/geocoder2/results/nominatim.rb +94 -0
- data/lib/geocoder2/results/ovi.rb +62 -0
- data/lib/geocoder2/results/test.rb +16 -0
- data/lib/geocoder2/results/yahoo.rb +55 -0
- data/lib/geocoder2/results/yandex.rb +80 -0
- data/lib/geocoder2/sql.rb +106 -0
- data/lib/geocoder2/stores/active_record.rb +272 -0
- data/lib/geocoder2/stores/base.rb +120 -0
- data/lib/geocoder2/stores/mongo_base.rb +89 -0
- data/lib/geocoder2/stores/mongo_mapper.rb +13 -0
- data/lib/geocoder2/stores/mongoid.rb +13 -0
- data/lib/geocoder2/version.rb +3 -0
- data/lib/geocoder2.rb +55 -0
- data/lib/hash_recursive_merge.rb +74 -0
- data/lib/oauth_util.rb +112 -0
- data/lib/tasks/geocoder2.rake +27 -0
- data/test/active_record_test.rb +15 -0
- data/test/cache_test.rb +35 -0
- data/test/calculations_test.rb +211 -0
- data/test/configuration_test.rb +78 -0
- data/test/custom_block_test.rb +32 -0
- data/test/error_handling_test.rb +43 -0
- data/test/fixtures/baidu_invalid_key +1 -0
- data/test/fixtures/baidu_no_results +1 -0
- data/test/fixtures/baidu_reverse +1 -0
- data/test/fixtures/baidu_shanghai_pearl_tower +12 -0
- data/test/fixtures/bing_invalid_key +1 -0
- data/test/fixtures/bing_madison_square_garden +40 -0
- data/test/fixtures/bing_no_results +16 -0
- data/test/fixtures/bing_reverse +42 -0
- data/test/fixtures/esri_madison_square_garden +59 -0
- data/test/fixtures/esri_no_results +8 -0
- data/test/fixtures/esri_reverse +21 -0
- data/test/fixtures/freegeoip_74_200_247_59 +12 -0
- data/test/fixtures/freegeoip_no_results +1 -0
- data/test/fixtures/geocoder_ca_madison_square_garden +1 -0
- data/test/fixtures/geocoder_ca_no_results +1 -0
- data/test/fixtures/geocoder_ca_reverse +34 -0
- data/test/fixtures/geocoder_us_madison_square_garden +1 -0
- data/test/fixtures/geocoder_us_no_results +1 -0
- data/test/fixtures/google_garbage +456 -0
- data/test/fixtures/google_madison_square_garden +57 -0
- data/test/fixtures/google_no_city_data +44 -0
- data/test/fixtures/google_no_locality +51 -0
- data/test/fixtures/google_no_results +4 -0
- data/test/fixtures/google_over_limit +4 -0
- data/test/fixtures/mapquest_error +16 -0
- data/test/fixtures/mapquest_invalid_api_key +16 -0
- data/test/fixtures/mapquest_invalid_request +16 -0
- data/test/fixtures/mapquest_madison_square_garden +52 -0
- data/test/fixtures/mapquest_no_results +16 -0
- data/test/fixtures/maxmind_24_24_24_21 +1 -0
- data/test/fixtures/maxmind_24_24_24_22 +1 -0
- data/test/fixtures/maxmind_24_24_24_23 +1 -0
- data/test/fixtures/maxmind_24_24_24_24 +1 -0
- data/test/fixtures/maxmind_74_200_247_59 +1 -0
- data/test/fixtures/maxmind_invalid_key +1 -0
- data/test/fixtures/maxmind_no_results +1 -0
- data/test/fixtures/nominatim_madison_square_garden +150 -0
- data/test/fixtures/nominatim_no_results +1 -0
- data/test/fixtures/ovi_madison_square_garden +72 -0
- data/test/fixtures/ovi_no_results +8 -0
- data/test/fixtures/yahoo_error +1 -0
- data/test/fixtures/yahoo_invalid_key +2 -0
- data/test/fixtures/yahoo_madison_square_garden +52 -0
- data/test/fixtures/yahoo_no_results +10 -0
- data/test/fixtures/yahoo_over_limit +2 -0
- data/test/fixtures/yandex_invalid_key +1 -0
- data/test/fixtures/yandex_kremlin +48 -0
- data/test/fixtures/yandex_no_city_and_town +112 -0
- data/test/fixtures/yandex_no_results +16 -0
- data/test/geocoder_test.rb +59 -0
- data/test/https_test.rb +16 -0
- data/test/integration/smoke_test.rb +26 -0
- data/test/lookup_test.rb +117 -0
- data/test/method_aliases_test.rb +25 -0
- data/test/mongoid_test.rb +46 -0
- data/test/mongoid_test_helper.rb +43 -0
- data/test/near_test.rb +61 -0
- data/test/oauth_util_test.rb +30 -0
- data/test/proxy_test.rb +36 -0
- data/test/query_test.rb +52 -0
- data/test/request_test.rb +29 -0
- data/test/result_test.rb +42 -0
- data/test/services_test.rb +393 -0
- data/test/test_helper.rb +289 -0
- data/test/test_mode_test.rb +59 -0
- metadata +213 -0
|
@@ -0,0 +1,393 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
require 'test_helper'
|
|
3
|
+
|
|
4
|
+
class ServicesTest < Test::Unit::TestCase
|
|
5
|
+
|
|
6
|
+
# --- Google ---
|
|
7
|
+
|
|
8
|
+
def test_google_result_components
|
|
9
|
+
result = Geocoder2.search("Madison Square Garden, New York, NY").first
|
|
10
|
+
assert_equal "Manhattan",
|
|
11
|
+
result.address_components_of_type(:sublocality).first['long_name']
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def test_google_result_components_contains_route
|
|
15
|
+
result = Geocoder2.search("Madison Square Garden, New York, NY").first
|
|
16
|
+
assert_equal "Penn Plaza",
|
|
17
|
+
result.address_components_of_type(:route).first['long_name']
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def test_google_result_components_contains_street_number
|
|
21
|
+
result = Geocoder2.search("Madison Square Garden, New York, NY").first
|
|
22
|
+
assert_equal "4",
|
|
23
|
+
result.address_components_of_type(:street_number).first['long_name']
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def test_google_returns_city_when_no_locality_in_result
|
|
27
|
+
result = Geocoder2.search("no locality").first
|
|
28
|
+
assert_equal "Haram", result.city
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def test_google_city_results_returns_nil_if_no_matching_component_types
|
|
32
|
+
result = Geocoder2.search("no city data").first
|
|
33
|
+
assert_equal nil, result.city
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def test_google_street_address_returns_formatted_street_address
|
|
37
|
+
result = Geocoder2.search("Madison Square Garden, New York, NY").first
|
|
38
|
+
assert_equal "4 Penn Plaza", result.street_address
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def test_google_precision
|
|
42
|
+
result = Geocoder2.search("Madison Square Garden, New York, NY").first
|
|
43
|
+
assert_equal "ROOFTOP",
|
|
44
|
+
result.precision
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def test_google_query_url_contains_bounds
|
|
48
|
+
lookup = Geocoder2::Lookup::Google.new
|
|
49
|
+
url = lookup.query_url(Geocoder2::Query.new(
|
|
50
|
+
"Some Intersection",
|
|
51
|
+
:bounds => [[40.0, -120.0], [39.0, -121.0]]
|
|
52
|
+
))
|
|
53
|
+
assert_match /bounds=40.0+%2C-120.0+%7C39.0+%2C-121.0+/, url
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def test_google_query_url_contains_region
|
|
57
|
+
lookup = Geocoder2::Lookup::Google.new
|
|
58
|
+
url = lookup.query_url(Geocoder2::Query.new(
|
|
59
|
+
"Some Intersection",
|
|
60
|
+
:region => "gb"
|
|
61
|
+
))
|
|
62
|
+
assert_match /region=gb/, url
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def test_google_query_url_contains_components_when_given_as_string
|
|
66
|
+
lookup = Geocoder2::Lookup::Google.new
|
|
67
|
+
url = lookup.query_url(Geocoder2::Query.new(
|
|
68
|
+
"Some Intersection",
|
|
69
|
+
:components => "locality:ES"
|
|
70
|
+
))
|
|
71
|
+
formatted = "components=" + CGI.escape("locality:ES")
|
|
72
|
+
assert url.include?(formatted), "Expected #{formatted} to be included in #{url}"
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def test_google_query_url_contains_components_when_given_as_array
|
|
76
|
+
lookup = Geocoder2::Lookup::Google.new
|
|
77
|
+
url = lookup.query_url(Geocoder2::Query.new(
|
|
78
|
+
"Some Intersection",
|
|
79
|
+
:components => ["country:ES", "locality:ES"]
|
|
80
|
+
))
|
|
81
|
+
formatted = "components=" + CGI.escape("country:ES|locality:ES")
|
|
82
|
+
assert url.include?(formatted), "Expected #{formatted} to be included in #{url}"
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
# --- Google Premier ---
|
|
86
|
+
|
|
87
|
+
def test_google_premier_result_components
|
|
88
|
+
Geocoder2.configure(:lookup => :google_premier)
|
|
89
|
+
set_api_key!(:google_premier)
|
|
90
|
+
result = Geocoder2.search("Madison Square Garden, New York, NY").first
|
|
91
|
+
assert_equal "Manhattan",
|
|
92
|
+
result.address_components_of_type(:sublocality).first['long_name']
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def test_google_premier_query_url
|
|
96
|
+
Geocoder2.configure(:api_key => ["deadbeef", "gme-test", "test-dev"])
|
|
97
|
+
assert_equal "http://maps.googleapis.com/maps/api/geocode/json?address=Madison+Square+Garden%2C+New+York%2C+NY&channel=test-dev&client=gme-test&language=en&sensor=false&signature=doJvJqX7YJzgV9rJ0DnVkTGZqTg=",
|
|
98
|
+
Geocoder2::Lookup::GooglePremier.new.query_url(Geocoder2::Query.new("Madison Square Garden, New York, NY"))
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
# --- DSTK (Data Science Toolkit) ---
|
|
102
|
+
|
|
103
|
+
def test_dstk_result_components
|
|
104
|
+
Geocoder2.configure(:lookup => :dstk, :dstk => { :host => 'NOT_AN_ACTUAL_HOST' })
|
|
105
|
+
result = Geocoder2.search("Madison Square Garden, New York, NY").first
|
|
106
|
+
assert_equal "Manhattan",
|
|
107
|
+
result.address_components_of_type(:sublocality).first['long_name']
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
def test_dstk_query_url
|
|
111
|
+
Geocoder2.configure(:lookup => :dstk, :dstk => { :host => 'NOT_AN_ACTUAL_HOST' })
|
|
112
|
+
assert_equal "http://NOT_AN_ACTUAL_HOST/maps/api/geocode/json?address=Madison+Square+Garden%2C+New+York%2C+NY&language=en&sensor=false",
|
|
113
|
+
Geocoder2::Lookup::Dstk.new.query_url(Geocoder2::Query.new("Madison Square Garden, New York, NY"))
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
def test_dstk_default_query_url
|
|
117
|
+
Geocoder2.configure(:lookup => :dstk)
|
|
118
|
+
assert_equal "http://www.datasciencetoolkit.org/maps/api/geocode/json?address=Madison+Square+Garden%2C+New+York%2C+NY&language=en&sensor=false",
|
|
119
|
+
Geocoder2::Lookup::Dstk.new.query_url(Geocoder2::Query.new("Madison Square Garden, New York, NY"))
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
# --- Yahoo ---
|
|
123
|
+
|
|
124
|
+
def test_yahoo_no_results
|
|
125
|
+
Geocoder2.configure(:lookup => :yahoo)
|
|
126
|
+
set_api_key!(:yahoo)
|
|
127
|
+
assert_equal [], Geocoder2.search("no results")
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
def test_yahoo_error
|
|
131
|
+
Geocoder2.configure(:lookup => :yahoo)
|
|
132
|
+
set_api_key!(:yahoo)
|
|
133
|
+
# keep test output clean: suppress timeout warning
|
|
134
|
+
orig = $VERBOSE; $VERBOSE = nil
|
|
135
|
+
assert_equal [], Geocoder2.search("error")
|
|
136
|
+
ensure
|
|
137
|
+
$VERBOSE = orig
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
def test_yahoo_result_components
|
|
141
|
+
Geocoder2.configure(:lookup => :yahoo)
|
|
142
|
+
set_api_key!(:yahoo)
|
|
143
|
+
result = Geocoder2.search("madison square garden").first
|
|
144
|
+
assert_equal "10001", result.postal_code
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
def test_yahoo_address_formatting
|
|
148
|
+
Geocoder2.configure(:lookup => :yahoo)
|
|
149
|
+
set_api_key!(:yahoo)
|
|
150
|
+
result = Geocoder2.search("madison square garden").first
|
|
151
|
+
assert_equal "Madison Square Garden, New York, NY 10001, United States", result.address
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
def test_yahoo_raises_exception_when_over_query_limit
|
|
155
|
+
Geocoder2.configure(:always_raise => [Geocoder2::OverQueryLimitError])
|
|
156
|
+
l = Geocoder2::Lookup.get(:yahoo)
|
|
157
|
+
assert_raises Geocoder2::OverQueryLimitError do
|
|
158
|
+
l.send(:results, Geocoder2::Query.new("over limit"))
|
|
159
|
+
end
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
# --- Geocoder2.ca ---
|
|
163
|
+
|
|
164
|
+
def test_geocoder_ca_result_components
|
|
165
|
+
Geocoder2.configure(:lookup => :geocoder_ca)
|
|
166
|
+
set_api_key!(:geocoder_ca)
|
|
167
|
+
result = Geocoder2.search([45.423733, -75.676333]).first
|
|
168
|
+
assert_equal "CA", result.country_code
|
|
169
|
+
assert_equal "289 Somerset ST E, Ottawa, ON K1N6W1, Canada", result.address
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
# --- FreeGeoIp ---
|
|
174
|
+
|
|
175
|
+
def test_freegeoip_result_on_ip_address_search
|
|
176
|
+
result = Geocoder2.search("74.200.247.59").first
|
|
177
|
+
assert result.is_a?(Geocoder2::Result::Freegeoip)
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
def test_freegeoip_result_components
|
|
181
|
+
result = Geocoder2.search("74.200.247.59").first
|
|
182
|
+
assert_equal "Plano, TX 75093, United States", result.address
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
# --- MaxMind ---
|
|
186
|
+
|
|
187
|
+
def test_maxmind_result_on_ip_address_search
|
|
188
|
+
Geocoder2.configure(:ip_lookup => :maxmind, :maxmind => {:service => :city_isp_org})
|
|
189
|
+
result = Geocoder2.search("74.200.247.59").first
|
|
190
|
+
assert result.is_a?(Geocoder2::Result::Maxmind)
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
def test_maxmind_result_knows_country_service_name
|
|
194
|
+
Geocoder2.configure(:ip_lookup => :maxmind, :maxmind => {:service => :country})
|
|
195
|
+
assert_equal :country, Geocoder2.search("24.24.24.21").first.service_name
|
|
196
|
+
end
|
|
197
|
+
|
|
198
|
+
def test_maxmind_result_knows_city_service_name
|
|
199
|
+
Geocoder2.configure(:ip_lookup => :maxmind, :maxmind => {:service => :city})
|
|
200
|
+
assert_equal :city, Geocoder2.search("24.24.24.22").first.service_name
|
|
201
|
+
end
|
|
202
|
+
|
|
203
|
+
def test_maxmind_result_knows_city_isp_org_service_name
|
|
204
|
+
Geocoder2.configure(:ip_lookup => :maxmind, :maxmind => {:service => :city_isp_org})
|
|
205
|
+
assert_equal :city_isp_org, Geocoder2.search("24.24.24.23").first.service_name
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
def test_maxmind_result_knows_omni_service_name
|
|
209
|
+
Geocoder2.configure(:ip_lookup => :maxmind, :maxmind => {:service => :omni})
|
|
210
|
+
assert_equal :omni, Geocoder2.search("24.24.24.24").first.service_name
|
|
211
|
+
end
|
|
212
|
+
|
|
213
|
+
def test_maxmind_special_result_components
|
|
214
|
+
Geocoder2.configure(:ip_lookup => :maxmind, :maxmind => {:service => :omni})
|
|
215
|
+
result = Geocoder2.search("24.24.24.24").first
|
|
216
|
+
assert_equal "Road Runner", result.isp_name
|
|
217
|
+
assert_equal "Cable/DSL", result.netspeed
|
|
218
|
+
assert_equal "rr.com", result.domain
|
|
219
|
+
end
|
|
220
|
+
|
|
221
|
+
def test_maxmind_raises_exception_when_service_not_configured
|
|
222
|
+
Geocoder2.configure(:ip_lookup => :maxmind)
|
|
223
|
+
Geocoder2.configure(:maxmind => {:service => nil})
|
|
224
|
+
assert_raises Geocoder2::ConfigurationError do
|
|
225
|
+
Geocoder2::Query.new("24.24.24.24").url
|
|
226
|
+
end
|
|
227
|
+
end
|
|
228
|
+
|
|
229
|
+
def test_maxmind_works_when_loopback_address_on_omni
|
|
230
|
+
Geocoder2.configure(:ip_lookup => :maxmind, :maxmind => { :service => :omni })
|
|
231
|
+
result = Geocoder2.search("127.0.0.1").first
|
|
232
|
+
assert_equal "", result.country_code
|
|
233
|
+
end
|
|
234
|
+
|
|
235
|
+
def test_maxmind_works_when_loopback_address_on_country
|
|
236
|
+
Geocoder2.configure(:ip_lookup => :maxmind, :maxmind => { :service => :country })
|
|
237
|
+
result = Geocoder2.search("127.0.0.1").first
|
|
238
|
+
assert_equal "", result.country_code
|
|
239
|
+
end
|
|
240
|
+
|
|
241
|
+
|
|
242
|
+
# --- Bing ---
|
|
243
|
+
|
|
244
|
+
def test_bing_result_components
|
|
245
|
+
Geocoder2.configure(:lookup => :bing)
|
|
246
|
+
set_api_key!(:bing)
|
|
247
|
+
result = Geocoder2.search("Madison Square Garden, New York, NY").first
|
|
248
|
+
assert_equal "Madison Square Garden, NY", result.address
|
|
249
|
+
assert_equal "NY", result.state
|
|
250
|
+
assert_equal "New York", result.city
|
|
251
|
+
end
|
|
252
|
+
|
|
253
|
+
def test_bing_no_results
|
|
254
|
+
Geocoder2.configure(:lookup => :bing)
|
|
255
|
+
set_api_key!(:bing)
|
|
256
|
+
results = Geocoder2.search("no results")
|
|
257
|
+
assert_equal 0, results.length
|
|
258
|
+
end
|
|
259
|
+
|
|
260
|
+
# --- Nominatim ---
|
|
261
|
+
|
|
262
|
+
def test_nominatim_result_components
|
|
263
|
+
Geocoder2.configure(:lookup => :nominatim)
|
|
264
|
+
set_api_key!(:nominatim)
|
|
265
|
+
result = Geocoder2.search("Madison Square Garden, New York, NY").first
|
|
266
|
+
assert_equal "10001", result.postal_code
|
|
267
|
+
end
|
|
268
|
+
|
|
269
|
+
def test_nominatim_address_formatting
|
|
270
|
+
Geocoder2.configure(:lookup => :nominatim)
|
|
271
|
+
set_api_key!(:nominatim)
|
|
272
|
+
result = Geocoder2.search("Madison Square Garden, New York, NY").first
|
|
273
|
+
assert_equal "Madison Square Garden, West 31st Street, Long Island City, New York City, New York, 10001, United States of America",
|
|
274
|
+
result.address
|
|
275
|
+
end
|
|
276
|
+
|
|
277
|
+
def test_nominatim_host_config
|
|
278
|
+
Geocoder2.configure(:lookup => :nominatim, :nominatim => {:host => "local.com"})
|
|
279
|
+
lookup = Geocoder2::Lookup::Nominatim.new
|
|
280
|
+
query = Geocoder2::Query.new("Bluffton, SC")
|
|
281
|
+
assert_match %r(http://local\.com), lookup.query_url(query)
|
|
282
|
+
end
|
|
283
|
+
|
|
284
|
+
# --- MapQuest ---
|
|
285
|
+
|
|
286
|
+
def test_api_route
|
|
287
|
+
Geocoder2.configure(:lookup => :mapquest, :api_key => "abc123")
|
|
288
|
+
lookup = Geocoder2::Lookup::Mapquest.new
|
|
289
|
+
query = Geocoder2::Query.new("Bluffton, SC")
|
|
290
|
+
res = lookup.query_url(query)
|
|
291
|
+
assert_equal "http://open.mapquestapi.com/geocoding/v1/address?key=abc123&location=Bluffton%2C+SC",
|
|
292
|
+
res
|
|
293
|
+
end
|
|
294
|
+
|
|
295
|
+
def test_api_route_licensed
|
|
296
|
+
Geocoder2.configure(:lookup => :mapquest, :api_key => "abc123", :mapquest => {:licensed => true, :version => 2})
|
|
297
|
+
lookup = Geocoder2::Lookup::Mapquest.new
|
|
298
|
+
query = Geocoder2::Query.new("Bluffton, SC")
|
|
299
|
+
res = lookup.query_url(query)
|
|
300
|
+
assert_equal "http://www.mapquestapi.com/geocoding/v2/address?key=abc123&location=Bluffton%2C+SC",
|
|
301
|
+
res
|
|
302
|
+
end
|
|
303
|
+
|
|
304
|
+
def test_mapquest_result_components
|
|
305
|
+
Geocoder2.configure(:lookup => :mapquest)
|
|
306
|
+
set_api_key!(:mapquest)
|
|
307
|
+
result = Geocoder2.search("Madison Square Garden, New York, NY").first
|
|
308
|
+
assert_equal "10001", result.postal_code
|
|
309
|
+
end
|
|
310
|
+
|
|
311
|
+
def test_mapquest_address_formatting
|
|
312
|
+
Geocoder2.configure(:lookup => :mapquest)
|
|
313
|
+
set_api_key!(:mapquest)
|
|
314
|
+
result = Geocoder2.search("Madison Square Garden, New York, NY").first
|
|
315
|
+
assert_equal "46 West 31st Street, New York, NY, 10001, US",
|
|
316
|
+
result.address
|
|
317
|
+
end
|
|
318
|
+
|
|
319
|
+
def test_mapquest_no_results
|
|
320
|
+
Geocoder2.configure(:lookup => :mapquest)
|
|
321
|
+
set_api_key!(:mapquest)
|
|
322
|
+
assert_equal [], Geocoder2.search("no results")
|
|
323
|
+
end
|
|
324
|
+
|
|
325
|
+
def test_mapquest_raises_exception_when_invalid_request
|
|
326
|
+
Geocoder2.configure(:always_raise => [Geocoder2::InvalidRequest])
|
|
327
|
+
l = Geocoder2::Lookup.get(:mapquest)
|
|
328
|
+
assert_raises Geocoder2::InvalidRequest do
|
|
329
|
+
l.send(:results, Geocoder2::Query.new("invalid request"))
|
|
330
|
+
end
|
|
331
|
+
end
|
|
332
|
+
|
|
333
|
+
def test_mapquest_raises_exception_when_invalid_api_key
|
|
334
|
+
Geocoder2.configure(:always_raise => [Geocoder2::InvalidApiKey])
|
|
335
|
+
l = Geocoder2::Lookup.get(:mapquest)
|
|
336
|
+
assert_raises Geocoder2::InvalidApiKey do
|
|
337
|
+
l.send(:results, Geocoder2::Query.new("invalid api key"))
|
|
338
|
+
end
|
|
339
|
+
end
|
|
340
|
+
|
|
341
|
+
def test_mapquest_raises_exception_when_error
|
|
342
|
+
Geocoder2.configure(:always_raise => [Geocoder2::Error])
|
|
343
|
+
l = Geocoder2::Lookup.get(:mapquest)
|
|
344
|
+
assert_raises Geocoder2::Error do
|
|
345
|
+
l.send(:results, Geocoder2::Query.new("error"))
|
|
346
|
+
end
|
|
347
|
+
end
|
|
348
|
+
|
|
349
|
+
|
|
350
|
+
|
|
351
|
+
# --- Esri ---
|
|
352
|
+
|
|
353
|
+
def test_esri_query_for_geocode
|
|
354
|
+
query = Geocoder2::Query.new("Bluffton, SC")
|
|
355
|
+
lookup = Geocoder2::Lookup.get(:esri)
|
|
356
|
+
res = lookup.query_url(query)
|
|
357
|
+
assert_equal "http://geocode.arcgis.com/arcgis/rest/services/World/GeocodeServer/find?f=pjson&outFields=%2A&text=Bluffton%2C+SC",
|
|
358
|
+
res
|
|
359
|
+
end
|
|
360
|
+
|
|
361
|
+
def test_esri_query_for_reverse_geocode
|
|
362
|
+
query = Geocoder2::Query.new([45.423733, -75.676333])
|
|
363
|
+
lookup = Geocoder2::Lookup.get(:esri)
|
|
364
|
+
res = lookup.query_url(query)
|
|
365
|
+
assert_equal "http://geocode.arcgis.com/arcgis/rest/services/World/GeocodeServer/reverseGeocode?f=pjson&location=-75.676333%2C45.423733&outFields=%2A",
|
|
366
|
+
res
|
|
367
|
+
end
|
|
368
|
+
|
|
369
|
+
def test_esri_results_component
|
|
370
|
+
Geocoder2.configure(:lookup => :esri)
|
|
371
|
+
result = Geocoder2.search("Madison Square Garden, New York, NY").first
|
|
372
|
+
assert_equal "10001", result.postal_code
|
|
373
|
+
assert_equal "USA", result.country
|
|
374
|
+
assert_equal "Madison Square Garden", result.address
|
|
375
|
+
assert_equal "New York", result.city
|
|
376
|
+
assert_equal "New York", result.state
|
|
377
|
+
assert_equal 40.75004981300049, result.coordinates[0]
|
|
378
|
+
assert_equal -73.99423889799965, result.coordinates[1]
|
|
379
|
+
end
|
|
380
|
+
|
|
381
|
+
def test_esri_results_component_when_reverse_geocoding
|
|
382
|
+
Geocoder2.configure(:lookup => :esri)
|
|
383
|
+
result = Geocoder2.search([45.423733, -75.676333]).first
|
|
384
|
+
assert_equal "75007", result.postal_code
|
|
385
|
+
assert_equal "FRA", result.country
|
|
386
|
+
assert_equal "4 Avenue Gustave Eiffel", result.address
|
|
387
|
+
assert_equal "Paris", result.city
|
|
388
|
+
assert_equal "Île-de-France", result.state
|
|
389
|
+
assert_equal 48.858129997357558, result.coordinates[0]
|
|
390
|
+
assert_equal 2.2956200048981574, result.coordinates[1]
|
|
391
|
+
end
|
|
392
|
+
|
|
393
|
+
end
|
data/test/test_helper.rb
ADDED
|
@@ -0,0 +1,289 @@
|
|
|
1
|
+
require 'rubygems'
|
|
2
|
+
require 'test/unit'
|
|
3
|
+
|
|
4
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
|
5
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
|
6
|
+
|
|
7
|
+
class MysqlConnection
|
|
8
|
+
def adapter_name
|
|
9
|
+
"mysql"
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
##
|
|
14
|
+
# Simulate enough of ActiveRecord::Base that objects can be used for testing.
|
|
15
|
+
#
|
|
16
|
+
module ActiveRecord
|
|
17
|
+
class Base
|
|
18
|
+
|
|
19
|
+
def initialize
|
|
20
|
+
@attributes = {}
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def read_attribute(attr_name)
|
|
24
|
+
@attributes[attr_name.to_sym]
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def write_attribute(attr_name, value)
|
|
28
|
+
@attributes[attr_name.to_sym] = value
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def update_attribute(attr_name, value)
|
|
32
|
+
write_attribute(attr_name.to_sym, value)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def self.scope(*args); end
|
|
36
|
+
|
|
37
|
+
def self.connection
|
|
38
|
+
MysqlConnection.new
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def method_missing(name, *args, &block)
|
|
42
|
+
if name.to_s[-1..-1] == "="
|
|
43
|
+
write_attribute name.to_s[0...-1], *args
|
|
44
|
+
else
|
|
45
|
+
read_attribute name
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
class << self
|
|
50
|
+
def table_name
|
|
51
|
+
'test_table_name'
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def primary_key
|
|
55
|
+
:id
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
# simulate Rails module so Railtie gets loaded
|
|
63
|
+
module Rails
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
# Require Geocoder2 after ActiveRecord simulator.
|
|
67
|
+
require 'geocoder2'
|
|
68
|
+
require "geocoder2/lookups/base"
|
|
69
|
+
|
|
70
|
+
##
|
|
71
|
+
# Mock HTTP request to geocoding service.
|
|
72
|
+
#
|
|
73
|
+
module Geocoder2
|
|
74
|
+
module Lookup
|
|
75
|
+
class Base
|
|
76
|
+
private
|
|
77
|
+
def fixture_exists?(filename)
|
|
78
|
+
File.exist?(File.join("test", "fixtures", filename))
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def read_fixture(file)
|
|
82
|
+
filepath = File.join("test", "fixtures", file)
|
|
83
|
+
s = File.read(filepath).strip.gsub(/\n\s*/, "")
|
|
84
|
+
s.instance_eval do
|
|
85
|
+
def body; self; end
|
|
86
|
+
def code; "200"; end
|
|
87
|
+
end
|
|
88
|
+
s
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
##
|
|
92
|
+
# Fixture to use if none match the given query.
|
|
93
|
+
#
|
|
94
|
+
def default_fixture_filename
|
|
95
|
+
"#{fixture_prefix}_madison_square_garden"
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
def fixture_prefix
|
|
99
|
+
handle
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
def fixture_for_query(query)
|
|
103
|
+
label = query.reverse_geocode? ? "reverse" : query.text.gsub(/[ \.]/, "_")
|
|
104
|
+
filename = "#{fixture_prefix}_#{label}"
|
|
105
|
+
fixture_exists?(filename) ? filename : default_fixture_filename
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
def make_api_request(query)
|
|
109
|
+
raise TimeoutError if query.text == "timeout"
|
|
110
|
+
raise SocketError if query.text == "socket_error"
|
|
111
|
+
read_fixture fixture_for_query(query)
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
class GooglePremier
|
|
116
|
+
private
|
|
117
|
+
def fixture_prefix
|
|
118
|
+
"google"
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
class Dstk
|
|
123
|
+
private
|
|
124
|
+
def fixture_prefix
|
|
125
|
+
"google"
|
|
126
|
+
end
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
class Yandex
|
|
130
|
+
private
|
|
131
|
+
def default_fixture_filename
|
|
132
|
+
"yandex_kremlin"
|
|
133
|
+
end
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
class Freegeoip
|
|
137
|
+
private
|
|
138
|
+
def default_fixture_filename
|
|
139
|
+
"freegeoip_74_200_247_59"
|
|
140
|
+
end
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
class Maxmind
|
|
144
|
+
private
|
|
145
|
+
def default_fixture_filename
|
|
146
|
+
"maxmind_74_200_247_59"
|
|
147
|
+
end
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
class Baidu
|
|
151
|
+
private
|
|
152
|
+
def fixture_prefix
|
|
153
|
+
"baidu"
|
|
154
|
+
end
|
|
155
|
+
def default_fixture_filename
|
|
156
|
+
"baidu_shanghai_pearl_tower"
|
|
157
|
+
end
|
|
158
|
+
end
|
|
159
|
+
end
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
##
|
|
163
|
+
# Geocoded model.
|
|
164
|
+
#
|
|
165
|
+
class Venue < ActiveRecord::Base
|
|
166
|
+
geocoded_by :address
|
|
167
|
+
|
|
168
|
+
def initialize(name, address)
|
|
169
|
+
super()
|
|
170
|
+
write_attribute :name, name
|
|
171
|
+
write_attribute :address, address
|
|
172
|
+
end
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
##
|
|
176
|
+
# Geocoded model.
|
|
177
|
+
# - Has user-defined primary key (not just 'id')
|
|
178
|
+
#
|
|
179
|
+
class VenuePlus < Venue
|
|
180
|
+
|
|
181
|
+
class << self
|
|
182
|
+
def primary_key
|
|
183
|
+
:custom_primary_key_id
|
|
184
|
+
end
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
##
|
|
190
|
+
# Reverse geocoded model.
|
|
191
|
+
#
|
|
192
|
+
class Landmark < ActiveRecord::Base
|
|
193
|
+
reverse_geocoded_by :latitude, :longitude
|
|
194
|
+
|
|
195
|
+
def initialize(name, latitude, longitude)
|
|
196
|
+
super()
|
|
197
|
+
write_attribute :name, name
|
|
198
|
+
write_attribute :latitude, latitude
|
|
199
|
+
write_attribute :longitude, longitude
|
|
200
|
+
end
|
|
201
|
+
end
|
|
202
|
+
|
|
203
|
+
##
|
|
204
|
+
# Geocoded model with block.
|
|
205
|
+
#
|
|
206
|
+
class Event < ActiveRecord::Base
|
|
207
|
+
geocoded_by :address do |obj,results|
|
|
208
|
+
if result = results.first
|
|
209
|
+
obj.coords_string = "#{result.latitude},#{result.longitude}"
|
|
210
|
+
else
|
|
211
|
+
obj.coords_string = "NOT FOUND"
|
|
212
|
+
end
|
|
213
|
+
end
|
|
214
|
+
|
|
215
|
+
def initialize(name, address)
|
|
216
|
+
super()
|
|
217
|
+
write_attribute :name, name
|
|
218
|
+
write_attribute :address, address
|
|
219
|
+
end
|
|
220
|
+
end
|
|
221
|
+
|
|
222
|
+
##
|
|
223
|
+
# Reverse geocoded model with block.
|
|
224
|
+
#
|
|
225
|
+
class Party < ActiveRecord::Base
|
|
226
|
+
reverse_geocoded_by :latitude, :longitude do |obj,results|
|
|
227
|
+
if result = results.first
|
|
228
|
+
obj.country = result.country_code
|
|
229
|
+
end
|
|
230
|
+
end
|
|
231
|
+
|
|
232
|
+
def initialize(name, latitude, longitude)
|
|
233
|
+
super()
|
|
234
|
+
write_attribute :name, name
|
|
235
|
+
write_attribute :latitude, latitude
|
|
236
|
+
write_attribute :longitude, longitude
|
|
237
|
+
end
|
|
238
|
+
end
|
|
239
|
+
|
|
240
|
+
##
|
|
241
|
+
# Forward and reverse geocoded model.
|
|
242
|
+
# Should fill in whatever's missing (coords or address).
|
|
243
|
+
#
|
|
244
|
+
class GasStation < ActiveRecord::Base
|
|
245
|
+
geocoded_by :address, :latitude => :lat, :longitude => :lon
|
|
246
|
+
reverse_geocoded_by :lat, :lon, :address => :location
|
|
247
|
+
|
|
248
|
+
def initialize(name)
|
|
249
|
+
super()
|
|
250
|
+
write_attribute :name, name
|
|
251
|
+
end
|
|
252
|
+
end
|
|
253
|
+
|
|
254
|
+
|
|
255
|
+
class Test::Unit::TestCase
|
|
256
|
+
|
|
257
|
+
def setup
|
|
258
|
+
Geocoder2.configure(:maxmind => {:service => :city_isp_org})
|
|
259
|
+
end
|
|
260
|
+
|
|
261
|
+
def teardown
|
|
262
|
+
Geocoder2.send(:remove_const, :Configuration)
|
|
263
|
+
load "geocoder2/configuration.rb"
|
|
264
|
+
end
|
|
265
|
+
|
|
266
|
+
def venue_params(abbrev)
|
|
267
|
+
{
|
|
268
|
+
:msg => ["Madison Square Garden", "4 Penn Plaza, New York, NY"]
|
|
269
|
+
}[abbrev]
|
|
270
|
+
end
|
|
271
|
+
|
|
272
|
+
def landmark_params(abbrev)
|
|
273
|
+
{
|
|
274
|
+
:msg => ["Madison Square Garden", 40.750354, -73.993371]
|
|
275
|
+
}[abbrev]
|
|
276
|
+
end
|
|
277
|
+
|
|
278
|
+
def set_api_key!(lookup_name)
|
|
279
|
+
lookup = Geocoder2::Lookup.get(lookup_name)
|
|
280
|
+
if lookup.required_api_key_parts.size == 1
|
|
281
|
+
key = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'
|
|
282
|
+
elsif lookup.required_api_key_parts.size > 1
|
|
283
|
+
key = lookup.required_api_key_parts
|
|
284
|
+
else
|
|
285
|
+
key = nil
|
|
286
|
+
end
|
|
287
|
+
Geocoder2.configure(:api_key => key)
|
|
288
|
+
end
|
|
289
|
+
end
|