geocoder 1.1.4 → 1.1.8

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.
Files changed (110) hide show
  1. data/.travis.yml +4 -0
  2. data/{CHANGELOG.rdoc → CHANGELOG.md} +120 -39
  3. data/README.md +200 -54
  4. data/examples/autoexpire_cache_dalli.rb +62 -0
  5. data/examples/{autoexpire_cache.rb → autoexpire_cache_redis.rb} +4 -6
  6. data/lib/generators/geocoder/config/templates/initializer.rb +19 -23
  7. data/lib/geocoder/cache.rb +6 -1
  8. data/lib/geocoder/calculations.rb +45 -13
  9. data/lib/geocoder/cli.rb +10 -11
  10. data/lib/geocoder/configuration.rb +67 -43
  11. data/lib/geocoder/configuration_hash.rb +11 -0
  12. data/lib/geocoder/exceptions.rb +3 -0
  13. data/lib/geocoder/lookup.rb +3 -1
  14. data/lib/geocoder/lookups/base.rb +89 -27
  15. data/lib/geocoder/lookups/bing.rb +21 -11
  16. data/lib/geocoder/lookups/esri.rb +48 -0
  17. data/lib/geocoder/lookups/freegeoip.rb +8 -4
  18. data/lib/geocoder/lookups/geocoder_ca.rb +11 -7
  19. data/lib/geocoder/lookups/google.rb +18 -9
  20. data/lib/geocoder/lookups/google_premier.rb +16 -8
  21. data/lib/geocoder/lookups/mapquest.rb +33 -5
  22. data/lib/geocoder/lookups/maxmind.rb +88 -0
  23. data/lib/geocoder/lookups/nominatim.rb +13 -8
  24. data/lib/geocoder/lookups/ovi.rb +52 -0
  25. data/lib/geocoder/lookups/test.rb +10 -0
  26. data/lib/geocoder/lookups/yahoo.rb +51 -38
  27. data/lib/geocoder/lookups/yandex.rb +17 -9
  28. data/lib/geocoder/models/mongoid.rb +1 -1
  29. data/lib/geocoder/query.rb +20 -5
  30. data/lib/geocoder/request.rb +7 -1
  31. data/lib/geocoder/results/base.rb +8 -2
  32. data/lib/geocoder/results/esri.rb +51 -0
  33. data/lib/geocoder/results/google.rb +34 -0
  34. data/lib/geocoder/results/mapquest.rb +46 -2
  35. data/lib/geocoder/results/maxmind.rb +135 -0
  36. data/lib/geocoder/results/nominatim.rb +0 -10
  37. data/lib/geocoder/results/ovi.rb +62 -0
  38. data/lib/geocoder/results/test.rb +2 -1
  39. data/lib/geocoder/results/yahoo.rb +9 -2
  40. data/lib/geocoder/results/yandex.rb +12 -2
  41. data/lib/geocoder/sql.rb +6 -4
  42. data/lib/geocoder/stores/active_record.rb +57 -30
  43. data/lib/geocoder/stores/base.rb +3 -2
  44. data/lib/geocoder/stores/mongo_base.rb +2 -1
  45. data/lib/geocoder/version.rb +1 -1
  46. data/lib/geocoder.rb +2 -4
  47. data/lib/hash_recursive_merge.rb +74 -0
  48. data/lib/oauth_util.rb +112 -0
  49. data/test/cache_test.rb +19 -0
  50. data/test/calculations_test.rb +10 -4
  51. data/test/configuration_test.rb +26 -51
  52. data/test/error_handling_test.rb +8 -4
  53. data/test/fixtures/bing_invalid_key +1 -0
  54. data/test/fixtures/esri_madison_square_garden +59 -0
  55. data/test/fixtures/esri_no_results +8 -0
  56. data/test/fixtures/esri_reverse +21 -0
  57. data/test/fixtures/mapquest_madison_square_garden +52 -0
  58. data/test/fixtures/mapquest_no_results +7 -0
  59. data/test/fixtures/maxmind_24_24_24_21 +1 -0
  60. data/test/fixtures/maxmind_24_24_24_22 +1 -0
  61. data/test/fixtures/maxmind_24_24_24_23 +1 -0
  62. data/test/fixtures/maxmind_24_24_24_24 +1 -0
  63. data/test/fixtures/maxmind_74_200_247_59 +1 -0
  64. data/test/fixtures/maxmind_invalid_key +1 -0
  65. data/test/fixtures/maxmind_no_results +1 -0
  66. data/test/fixtures/ovi_madison_square_garden +72 -0
  67. data/test/fixtures/ovi_no_results +8 -0
  68. data/test/fixtures/yahoo_error +1 -0
  69. data/test/fixtures/yahoo_invalid_key +2 -0
  70. data/test/fixtures/yahoo_madison_square_garden +52 -0
  71. data/test/fixtures/yahoo_no_results +10 -0
  72. data/test/fixtures/yahoo_over_limit +2 -0
  73. data/test/fixtures/yandex_no_city_and_town +112 -0
  74. data/test/https_test.rb +3 -3
  75. data/test/integration/smoke_test.rb +2 -2
  76. data/test/lookup_test.rb +84 -11
  77. data/test/near_test.rb +43 -0
  78. data/test/oauth_util_test.rb +30 -0
  79. data/test/proxy_test.rb +2 -2
  80. data/test/query_test.rb +13 -0
  81. data/test/request_test.rb +29 -0
  82. data/test/result_test.rb +12 -2
  83. data/test/services_test.rb +208 -57
  84. data/test/test_helper.rb +66 -100
  85. data/test/test_mode_test.rb +35 -26
  86. metadata +58 -35
  87. data/test/fixtures/mapquest_madison_square_garden.json +0 -27
  88. data/test/fixtures/mapquest_no_results.json +0 -1
  89. data/test/fixtures/yahoo_madison_square_garden.json +0 -52
  90. data/test/fixtures/yahoo_no_results.json +0 -10
  91. data/test/fixtures/yahoo_v1_madison_square_garden.json +0 -46
  92. data/test/fixtures/yahoo_v1_no_results.json +0 -10
  93. /data/test/fixtures/{bing_madison_square_garden.json → bing_madison_square_garden} +0 -0
  94. /data/test/fixtures/{bing_no_results.json → bing_no_results} +0 -0
  95. /data/test/fixtures/{bing_reverse.json → bing_reverse} +0 -0
  96. /data/test/fixtures/{freegeoip_74_200_247_59.json → freegeoip_74_200_247_59} +0 -0
  97. /data/test/fixtures/{freegeoip_no_results.json → freegeoip_no_results} +0 -0
  98. /data/test/fixtures/{geocoder_ca_madison_square_garden.json → geocoder_ca_madison_square_garden} +0 -0
  99. /data/test/fixtures/{geocoder_ca_no_results.json → geocoder_ca_no_results} +0 -0
  100. /data/test/fixtures/{geocoder_ca_reverse.json → geocoder_ca_reverse} +0 -0
  101. /data/test/fixtures/{google_garbage.json → google_garbage} +0 -0
  102. /data/test/fixtures/{google_madison_square_garden.json → google_madison_square_garden} +0 -0
  103. /data/test/fixtures/{google_no_city_data.json → google_no_city_data} +0 -0
  104. /data/test/fixtures/{google_no_locality.json → google_no_locality} +0 -0
  105. /data/test/fixtures/{google_no_results.json → google_no_results} +0 -0
  106. /data/test/fixtures/{nominatim_madison_square_garden.json → nominatim_madison_square_garden} +0 -0
  107. /data/test/fixtures/{nominatim_no_results.json → nominatim_no_results} +0 -0
  108. /data/test/fixtures/{yandex_invalid_key.json → yandex_invalid_key} +0 -0
  109. /data/test/fixtures/{yandex_kremlin.json → yandex_kremlin} +0 -0
  110. /data/test/fixtures/{yandex_no_results.json → yandex_no_results} +0 -0
@@ -0,0 +1,29 @@
1
+ # encoding: utf-8
2
+ require 'test_helper'
3
+
4
+ class RequestTest < Test::Unit::TestCase
5
+ class MockRequest
6
+ include Geocoder::Request
7
+ attr_accessor :env, :ip
8
+ def initialize(env={}, ip="")
9
+ @env = env
10
+ @ip = ip
11
+ end
12
+ end
13
+ def test_http_x_real_ip
14
+ req = MockRequest.new({"HTTP_X_REAL_IP" => "74.200.247.59"})
15
+ assert req.location.is_a?(Geocoder::Result::Freegeoip)
16
+ end
17
+ def test_http_x_forwarded_for_without_proxy
18
+ req = MockRequest.new({"HTTP_X_FORWARDED_FOR" => "74.200.247.59"})
19
+ assert req.location.is_a?(Geocoder::Result::Freegeoip)
20
+ end
21
+ def test_http_x_forwarded_for_with_proxy
22
+ req = MockRequest.new({"HTTP_X_FORWARDED_FOR" => "74.200.247.59, 74.200.247.59"})
23
+ assert req.location.is_a?(Geocoder::Result::Freegeoip)
24
+ end
25
+ def test_with_request_ip
26
+ req = MockRequest.new({}, "74.200.247.59")
27
+ assert req.location.is_a?(Geocoder::Result::Freegeoip)
28
+ end
29
+ end
data/test/result_test.rb CHANGED
@@ -5,17 +5,27 @@ class ResultTest < Test::Unit::TestCase
5
5
 
6
6
  def test_result_has_required_attributes
7
7
  Geocoder::Lookup.all_services_except_test.each do |l|
8
- Geocoder::Configuration.lookup = l
8
+ Geocoder.configure(:lookup => l)
9
+ set_api_key!(l)
9
10
  result = Geocoder.search([45.423733, -75.676333]).first
10
11
  assert_result_has_required_attributes(result)
11
12
  end
12
13
  end
13
14
 
15
+ def test_yandex_result_without_city_does_not_raise_exception
16
+ assert_nothing_raised do
17
+ Geocoder.configure(:lookup => :yandex)
18
+ set_api_key!(:yandex)
19
+ result = Geocoder.search("no city and town").first
20
+ assert_equal "", result.city
21
+ end
22
+ end
23
+
14
24
 
15
25
  private # ------------------------------------------------------------------
16
26
 
17
27
  def assert_result_has_required_attributes(result)
18
- m = "Lookup #{Geocoder::Configuration.lookup} does not support %s attribute."
28
+ m = "Lookup #{Geocoder.config.lookup} does not support %s attribute."
19
29
  assert result.coordinates.is_a?(Array), m % "coordinates"
20
30
  assert result.latitude.is_a?(Float), m % "latitude"
21
31
  assert result.longitude.is_a?(Float), m % "longitude"
@@ -3,19 +3,6 @@ require 'test_helper'
3
3
 
4
4
  class ServicesTest < Test::Unit::TestCase
5
5
 
6
-
7
- def test_query_url_contains_values_in_params_hash
8
- Geocoder::Lookup.all_services_except_test.each do |l|
9
- next if l == :google_premier # TODO: need to set keys to test
10
- next if l == :freegeoip # does not use query string
11
- url = Geocoder::Lookup.get(l).send(:query_url, Geocoder::Query.new(
12
- "test", :params => {:one_in_the_hand => "two in the bush"}
13
- ))
14
- assert_match /one_in_the_hand=two\+in\+the\+bush/, url,
15
- "Lookup #{l} does not appear to support arbitrary params in URL"
16
- end
17
- end
18
-
19
6
  # --- Google ---
20
7
 
21
8
  def test_google_result_components
@@ -24,6 +11,18 @@ class ServicesTest < Test::Unit::TestCase
24
11
  result.address_components_of_type(:sublocality).first['long_name']
25
12
  end
26
13
 
14
+ def test_google_result_components_contains_route
15
+ result = Geocoder.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 = Geocoder.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
+
27
26
  def test_google_returns_city_when_no_locality_in_result
28
27
  result = Geocoder.search("no locality").first
29
28
  assert_equal "Haram", result.city
@@ -34,6 +33,11 @@ class ServicesTest < Test::Unit::TestCase
34
33
  assert_equal nil, result.city
35
34
  end
36
35
 
36
+ def test_google_street_address_returns_formatted_street_address
37
+ result = Geocoder.search("Madison Square Garden, New York, NY").first
38
+ assert_equal "4 Penn Plaza", result.street_address
39
+ end
40
+
37
41
  def test_google_precision
38
42
  result = Geocoder.search("Madison Square Garden, New York, NY").first
39
43
  assert_equal "ROOFTOP",
@@ -42,81 +46,104 @@ class ServicesTest < Test::Unit::TestCase
42
46
 
43
47
  def test_google_query_url_contains_bounds
44
48
  lookup = Geocoder::Lookup::Google.new
45
- url = lookup.send(:query_url, Geocoder::Query.new(
49
+ url = lookup.query_url(Geocoder::Query.new(
46
50
  "Some Intersection",
47
51
  :bounds => [[40.0, -120.0], [39.0, -121.0]]
48
52
  ))
49
53
  assert_match /bounds=40.0+%2C-120.0+%7C39.0+%2C-121.0+/, url
50
54
  end
51
55
 
56
+ def test_google_query_url_contains_region
57
+ lookup = Geocoder::Lookup::Google.new
58
+ url = lookup.query_url(Geocoder::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 = Geocoder::Lookup::Google.new
67
+ url = lookup.query_url(Geocoder::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 = Geocoder::Lookup::Google.new
77
+ url = lookup.query_url(Geocoder::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
+
52
85
  # --- Google Premier ---
53
86
 
54
87
  def test_google_premier_result_components
55
- Geocoder::Configuration.lookup = :google_premier
88
+ Geocoder.configure(:lookup => :google_premier)
89
+ set_api_key!(:google_premier)
56
90
  result = Geocoder.search("Madison Square Garden, New York, NY").first
57
91
  assert_equal "Manhattan",
58
92
  result.address_components_of_type(:sublocality).first['long_name']
59
93
  end
60
94
 
61
95
  def test_google_premier_query_url
62
- Geocoder::Configuration.api_key = ["deadbeef", "gme-test", "test-dev"]
96
+ Geocoder.configure(:api_key => ["deadbeef", "gme-test", "test-dev"])
63
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=",
64
- Geocoder::Lookup::GooglePremier.new.send(:query_url, Geocoder::Query.new("Madison Square Garden, New York, NY"))
98
+ Geocoder::Lookup::GooglePremier.new.query_url(Geocoder::Query.new("Madison Square Garden, New York, NY"))
65
99
  end
66
100
 
67
101
 
68
102
  # --- Yahoo ---
69
103
 
70
- def test_yahoo_v1_no_results
71
- Geocoder::Configuration.lookup = :yahoo
72
- assert_equal [], Geocoder.search("no results v1")
73
- end
74
-
75
- def test_yahoo_v1_result_components
76
- Geocoder::Configuration.lookup = :yahoo
77
- result = Geocoder.search("madison square garden v1").first
78
- assert_equal "10001", result.postal_code
79
- end
80
-
81
- def test_yahoo_v1_address_formatting
82
- Geocoder::Configuration.lookup = :yahoo
83
- result = Geocoder.search("madison square garden v1").first
84
- assert_equal "Madison Square Garden, New York, NY 10001, United States", result.address
104
+ def test_yahoo_no_results
105
+ Geocoder.configure(:lookup => :yahoo)
106
+ set_api_key!(:yahoo)
107
+ assert_equal [], Geocoder.search("no results")
85
108
  end
86
109
 
87
- def test_yahoo_v2_no_results
88
- Geocoder::Configuration.lookup = :yahoo
89
- assert_equal [], Geocoder.search("no results")
110
+ def test_yahoo_error
111
+ Geocoder.configure(:lookup => :yahoo)
112
+ set_api_key!(:yahoo)
113
+ # keep test output clean: suppress timeout warning
114
+ orig = $VERBOSE; $VERBOSE = nil
115
+ assert_equal [], Geocoder.search("error")
116
+ ensure
117
+ $VERBOSE = orig
90
118
  end
91
119
 
92
- def test_yahoo_v2_result_components
93
- Geocoder::Configuration.lookup = :yahoo
94
- result = Geocoder.search("madison square garden v2").first
120
+ def test_yahoo_result_components
121
+ Geocoder.configure(:lookup => :yahoo)
122
+ set_api_key!(:yahoo)
123
+ result = Geocoder.search("madison square garden").first
95
124
  assert_equal "10001", result.postal_code
96
125
  end
97
126
 
98
- def test_yahoo_v2_address_formatting
99
- Geocoder::Configuration.lookup = :yahoo
100
- result = Geocoder.search("madison square garden v2").first
127
+ def test_yahoo_address_formatting
128
+ Geocoder.configure(:lookup => :yahoo)
129
+ set_api_key!(:yahoo)
130
+ result = Geocoder.search("madison square garden").first
101
131
  assert_equal "Madison Square Garden, New York, NY 10001, United States", result.address
102
132
  end
103
133
 
104
-
105
- # --- Yandex ---
106
-
107
- def test_yandex_with_invalid_key
108
- # keep test output clean: suppress timeout warning
109
- orig = $VERBOSE; $VERBOSE = nil
110
- Geocoder::Configuration.lookup = :yandex
111
- assert_equal [], Geocoder.search("invalid key")
112
- $VERBOSE = orig
134
+ def test_yahoo_raises_exception_when_over_query_limit
135
+ Geocoder.configure(:always_raise => [Geocoder::OverQueryLimitError])
136
+ l = Geocoder::Lookup.get(:yahoo)
137
+ assert_raises Geocoder::OverQueryLimitError do
138
+ l.send(:results, Geocoder::Query.new("over limit"))
139
+ end
113
140
  end
114
141
 
115
-
116
142
  # --- Geocoder.ca ---
117
143
 
118
144
  def test_geocoder_ca_result_components
119
- Geocoder::Configuration.lookup = :geocoder_ca
145
+ Geocoder.configure(:lookup => :geocoder_ca)
146
+ set_api_key!(:geocoder_ca)
120
147
  result = Geocoder.search([45.423733, -75.676333]).first
121
148
  assert_equal "CA", result.country_code
122
149
  assert_equal "289 Somerset ST E, Ottawa, ON K1N6W1, Canada", result.address
@@ -135,11 +162,56 @@ class ServicesTest < Test::Unit::TestCase
135
162
  assert_equal "Plano, TX 75093, United States", result.address
136
163
  end
137
164
 
165
+ # --- MaxMind ---
166
+
167
+ def test_maxmind_result_on_ip_address_search
168
+ Geocoder.configure(:ip_lookup => :maxmind, :maxmind => {:service => :city_isp_org})
169
+ result = Geocoder.search("74.200.247.59").first
170
+ assert result.is_a?(Geocoder::Result::Maxmind)
171
+ end
172
+
173
+ def test_maxmind_result_knows_country_service_name
174
+ Geocoder.configure(:ip_lookup => :maxmind, :maxmind => {:service => :country})
175
+ assert_equal :country, Geocoder.search("24.24.24.21").first.service_name
176
+ end
177
+
178
+ def test_maxmind_result_knows_city_service_name
179
+ Geocoder.configure(:ip_lookup => :maxmind, :maxmind => {:service => :city})
180
+ assert_equal :city, Geocoder.search("24.24.24.22").first.service_name
181
+ end
182
+
183
+ def test_maxmind_result_knows_city_isp_org_service_name
184
+ Geocoder.configure(:ip_lookup => :maxmind, :maxmind => {:service => :city_isp_org})
185
+ assert_equal :city_isp_org, Geocoder.search("24.24.24.23").first.service_name
186
+ end
187
+
188
+ def test_maxmind_result_knows_omni_service_name
189
+ Geocoder.configure(:ip_lookup => :maxmind, :maxmind => {:service => :omni})
190
+ assert_equal :omni, Geocoder.search("24.24.24.24").first.service_name
191
+ end
192
+
193
+ def test_maxmind_special_result_components
194
+ Geocoder.configure(:ip_lookup => :maxmind, :maxmind => {:service => :omni})
195
+ result = Geocoder.search("24.24.24.24").first
196
+ assert_equal "Road Runner", result.isp_name
197
+ assert_equal "Cable/DSL", result.netspeed
198
+ assert_equal "rr.com", result.domain
199
+ end
200
+
201
+ def test_maxmind_raises_exception_when_service_not_configured
202
+ Geocoder.configure(:ip_lookup => :maxmind)
203
+ Geocoder.configure(:maxmind => {:service => nil})
204
+ assert_raises Geocoder::ConfigurationError do
205
+ Geocoder::Query.new("24.24.24.24").url
206
+ end
207
+ end
208
+
138
209
 
139
210
  # --- Bing ---
140
211
 
141
212
  def test_bing_result_components
142
- Geocoder::Configuration.lookup = :bing
213
+ Geocoder.configure(:lookup => :bing)
214
+ set_api_key!(:bing)
143
215
  result = Geocoder.search("Madison Square Garden, New York, NY").first
144
216
  assert_equal "Madison Square Garden, NY", result.address
145
217
  assert_equal "NY", result.state
@@ -147,23 +219,102 @@ class ServicesTest < Test::Unit::TestCase
147
219
  end
148
220
 
149
221
  def test_bing_no_results
150
- Geocoder::Configuration.lookup = :bing
222
+ Geocoder.configure(:lookup => :bing)
223
+ set_api_key!(:bing)
151
224
  results = Geocoder.search("no results")
152
225
  assert_equal 0, results.length
153
226
  end
154
227
 
155
228
  # --- Nominatim ---
156
229
 
157
- def test_nominatim_result_components
158
- Geocoder::Configuration.lookup = :nominatim
230
+ def test_nominatim_result_components
231
+ Geocoder.configure(:lookup => :nominatim)
232
+ set_api_key!(:nominatim)
159
233
  result = Geocoder.search("Madison Square Garden, New York, NY").first
160
234
  assert_equal "10001", result.postal_code
161
235
  end
162
236
 
163
237
  def test_nominatim_address_formatting
164
- Geocoder::Configuration.lookup = :nominatim
238
+ Geocoder.configure(:lookup => :nominatim)
239
+ set_api_key!(:nominatim)
165
240
  result = Geocoder.search("Madison Square Garden, New York, NY").first
166
241
  assert_equal "Madison Square Garden, West 31st Street, Long Island City, New York City, New York, 10001, United States of America",
167
242
  result.address
168
243
  end
244
+
245
+ def test_nominatim_host_config
246
+ Geocoder.configure(:lookup => :nominatim, :nominatim => {:host => "local.com"})
247
+ lookup = Geocoder::Lookup::Nominatim.new
248
+ query = Geocoder::Query.new("Bluffton, SC")
249
+ assert_match %r(http://local\.com), lookup.query_url(query)
250
+ end
251
+
252
+ # --- MapQuest ---
253
+
254
+ def test_api_route
255
+ Geocoder.configure(:lookup => :mapquest, :api_key => "abc123")
256
+ lookup = Geocoder::Lookup::Mapquest.new
257
+ query = Geocoder::Query.new("Bluffton, SC")
258
+ res = lookup.query_url(query)
259
+ assert_equal "http://www.mapquestapi.com/geocoding/v1/address?key=abc123&location=Bluffton%2C+SC",
260
+ res
261
+ end
262
+
263
+ def test_mapquest_result_components
264
+ Geocoder.configure(:lookup => :mapquest)
265
+ set_api_key!(:mapquest)
266
+ result = Geocoder.search("Madison Square Garden, New York, NY").first
267
+ assert_equal "10001", result.postal_code
268
+ end
269
+
270
+ def test_mapquest_address_formatting
271
+ Geocoder.configure(:lookup => :mapquest)
272
+ set_api_key!(:mapquest)
273
+ result = Geocoder.search("Madison Square Garden, New York, NY").first
274
+ assert_equal "46 West 31st Street, New York, NY, 10001, US",
275
+ result.address
276
+ end
277
+
278
+ # --- Esri ---
279
+
280
+ def test_esri_query_for_geocode
281
+ query = Geocoder::Query.new("Bluffton, SC")
282
+ lookup = Geocoder::Lookup.get(:esri)
283
+ res = lookup.query_url(query)
284
+ assert_equal "http://geocode.arcgis.com/arcgis/rest/services/World/GeocodeServer/find?f=pjson&outFields=%2A&text=Bluffton%2C+SC",
285
+ res
286
+ end
287
+
288
+ def test_esri_query_for_reverse_geocode
289
+ query = Geocoder::Query.new([45.423733, -75.676333])
290
+ lookup = Geocoder::Lookup.get(:esri)
291
+ res = lookup.query_url(query)
292
+ assert_equal "http://geocode.arcgis.com/arcgis/rest/services/World/GeocodeServer/reverseGeocode?f=pjson&location=-75.676333%2C45.423733&outFields=%2A",
293
+ res
294
+ end
295
+
296
+ def test_esri_results_component
297
+ Geocoder.configure(:lookup => :esri)
298
+ result = Geocoder.search("Madison Square Garden, New York, NY").first
299
+ assert_equal "10001", result.postal_code
300
+ assert_equal "USA", result.country
301
+ assert_equal "Madison Square Garden", result.address
302
+ assert_equal "New York", result.city
303
+ assert_equal "New York", result.state
304
+ assert_equal 40.75004981300049, result.coordinates[0]
305
+ assert_equal -73.99423889799965, result.coordinates[1]
306
+ end
307
+
308
+ def test_esri_results_component_when_reverse_geocoding
309
+ Geocoder.configure(:lookup => :esri)
310
+ result = Geocoder.search([45.423733, -75.676333]).first
311
+ assert_equal "75007", result.postal_code
312
+ assert_equal "FRA", result.country
313
+ assert_equal "4 Avenue Gustave Eiffel", result.address
314
+ assert_equal "Paris", result.city
315
+ assert_equal "Île-de-France", result.state
316
+ assert_equal 48.858129997357558, result.coordinates[0]
317
+ assert_equal 2.2956200048981574, result.coordinates[1]
318
+ end
319
+
169
320
  end
data/test/test_helper.rb CHANGED
@@ -4,6 +4,12 @@ require 'test/unit'
4
4
  $LOAD_PATH.unshift(File.dirname(__FILE__))
5
5
  $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
6
6
 
7
+ class MysqlConnection
8
+ def adapter_name
9
+ "mysql"
10
+ end
11
+ end
12
+
7
13
  ##
8
14
  # Simulate enough of ActiveRecord::Base that objects can be used for testing.
9
15
  #
@@ -28,6 +34,10 @@ module ActiveRecord
28
34
 
29
35
  def self.scope(*args); end
30
36
 
37
+ def self.connection
38
+ MysqlConnection.new
39
+ end
40
+
31
41
  def method_missing(name, *args, &block)
32
42
  if name.to_s[-1..-1] == "="
33
43
  write_attribute name.to_s[0...-1], *args
@@ -63,129 +73,70 @@ require "geocoder/lookups/base"
63
73
  module Geocoder
64
74
  module Lookup
65
75
  class Base
66
- private #-----------------------------------------------------------------
67
- def read_fixture(file)
68
- File.read(File.join("test", "fixtures", file)).strip.gsub(/\n\s*/, "")
76
+ private
77
+ def fixture_exists?(filename)
78
+ File.exist?(File.join("test", "fixtures", filename))
69
79
  end
70
- end
71
80
 
72
- class Google < Base
73
- private #-----------------------------------------------------------------
74
- def fetch_raw_data(query)
75
- raise TimeoutError if query.text == "timeout"
76
- raise SocketError if query.text == "socket_error"
77
- file = case query.text
78
- when "no results"; :no_results
79
- when "no locality"; :no_locality
80
- when "no city data"; :no_city_data
81
- else :madison_square_garden
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
82
87
  end
83
- read_fixture "google_#{file}.json"
88
+ s
84
89
  end
85
- end
86
90
 
87
- class GooglePremier < Google
88
- end
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
89
97
 
90
- class Yahoo < Base
91
- private #-----------------------------------------------------------------
92
- def fetch_raw_data(query)
93
- raise TimeoutError if query.text == "timeout"
94
- raise SocketError if query.text == "socket_error"
95
- file = case query.text
96
- when "no results v1"; :v1_no_results
97
- when "madison square garden v1"; :v1_madison_square_garden
98
- when "no results"; :no_results
99
- else :madison_square_garden
100
- end
101
- read_fixture "yahoo_#{file}.json"
98
+ def fixture_prefix
99
+ handle
102
100
  end
103
- end
104
101
 
105
- class Yandex < Base
106
- private #-----------------------------------------------------------------
107
- def fetch_raw_data(query)
108
- raise TimeoutError if query.text == "timeout"
109
- raise SocketError if query.text == "socket_error"
110
- file = case query.text
111
- when "no results"; :no_results
112
- when "invalid key"; :invalid_key
113
- else :kremlin
114
- end
115
- read_fixture "yandex_#{file}.json"
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
116
106
  end
117
- end
118
107
 
119
- class GeocoderCa < Base
120
- private #-----------------------------------------------------------------
121
- def fetch_raw_data(query)
108
+ def make_api_request(query)
122
109
  raise TimeoutError if query.text == "timeout"
123
110
  raise SocketError if query.text == "socket_error"
124
- if query.reverse_geocode?
125
- read_fixture "geocoder_ca_reverse.json"
126
- else
127
- file = case query.text
128
- when "no results"; :no_results
129
- else :madison_square_garden
130
- end
131
- read_fixture "geocoder_ca_#{file}.json"
132
- end
111
+ read_fixture fixture_for_query(query)
133
112
  end
134
113
  end
135
114
 
136
- class Freegeoip < Base
137
- private #-----------------------------------------------------------------
138
- def fetch_raw_data(query)
139
- raise TimeoutError if query.text == "timeout"
140
- raise SocketError if query.text == "socket_error"
141
- file = case query.text
142
- when "no results"; :no_results
143
- else "74_200_247_59"
144
- end
145
- read_fixture "freegeoip_#{file}.json"
115
+ class GooglePremier
116
+ private
117
+ def fixture_prefix
118
+ "google"
146
119
  end
147
120
  end
148
121
 
149
- class Bing < Base
150
- private #-----------------------------------------------------------------
151
- def fetch_raw_data(query)
152
- raise TimeoutError if query.text == "timeout"
153
- raise SocketError if query.text == "socket_error"
154
- if query.reverse_geocode?
155
- read_fixture "bing_reverse.json"
156
- else
157
- file = case query.text
158
- when "no results"; :no_results
159
- else :madison_square_garden
160
- end
161
- read_fixture "bing_#{file}.json"
162
- end
122
+ class Yandex
123
+ private
124
+ def default_fixture_filename
125
+ "yandex_kremlin"
163
126
  end
164
127
  end
165
128
 
166
- class Nominatim < Base
167
- private #-----------------------------------------------------------------
168
- def fetch_raw_data(query)
169
- raise TimeoutError if query.text == "timeout"
170
- raise SocketError if query.text == "socket_error"
171
- file = case query.text
172
- when "no results"; :no_results
173
- else :madison_square_garden
174
- end
175
- read_fixture "nominatim_#{file}.json"
129
+ class Freegeoip
130
+ private
131
+ def default_fixture_filename
132
+ "freegeoip_74_200_247_59"
176
133
  end
177
134
  end
178
135
 
179
- class Mapquest < Nominatim
180
- private #-----------------------------------------------------------------
181
- def fetch_raw_data(query)
182
- raise TimeoutError if query.text == "timeout"
183
- raise SocketError if query.text == "socket_error"
184
- file = case query.text
185
- when "no results"; :no_results
186
- else :madison_square_garden
187
- end
188
- read_fixture "mapquest_#{file}.json"
136
+ class Maxmind
137
+ private
138
+ def default_fixture_filename
139
+ "maxmind_74_200_247_59"
189
140
  end
190
141
  end
191
142
 
@@ -287,6 +238,10 @@ end
287
238
 
288
239
  class Test::Unit::TestCase
289
240
 
241
+ def setup
242
+ Geocoder.configure(:maxmind => {:service => :city_isp_org})
243
+ end
244
+
290
245
  def teardown
291
246
  Geocoder.send(:remove_const, :Configuration)
292
247
  load "geocoder/configuration.rb"
@@ -309,5 +264,16 @@ class Test::Unit::TestCase
309
264
  return false unless coordinates.size == 2 # Should have dimension 2
310
265
  coordinates[0].nan? && coordinates[1].nan? # Both coordinates should be NaN
311
266
  end
312
- end
313
267
 
268
+ def set_api_key!(lookup_name)
269
+ lookup = Geocoder::Lookup.get(lookup_name)
270
+ if lookup.required_api_key_parts.size == 1
271
+ key = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'
272
+ elsif lookup.required_api_key_parts.size > 1
273
+ key = lookup.required_api_key_parts
274
+ else
275
+ key = nil
276
+ end
277
+ Geocoder.configure(:api_key => key)
278
+ end
279
+ end