geocoder 1.1.3 → 1.1.4

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of geocoder might be problematic. Click here for more details.

Files changed (45) hide show
  1. data/CHANGELOG.rdoc +12 -0
  2. data/README.md +580 -0
  3. data/examples/autoexpire_cache.rb +30 -0
  4. data/lib/geocoder.rb +9 -85
  5. data/lib/geocoder/calculations.rb +1 -1
  6. data/lib/geocoder/cli.rb +9 -10
  7. data/lib/geocoder/configuration.rb +3 -1
  8. data/lib/geocoder/lookup.rb +81 -0
  9. data/lib/geocoder/lookups/base.rb +20 -32
  10. data/lib/geocoder/lookups/bing.rb +12 -8
  11. data/lib/geocoder/lookups/freegeoip.rb +5 -5
  12. data/lib/geocoder/lookups/geocoder_ca.rb +13 -9
  13. data/lib/geocoder/lookups/google.rb +19 -7
  14. data/lib/geocoder/lookups/google_premier.rb +8 -7
  15. data/lib/geocoder/lookups/mapquest.rb +5 -23
  16. data/lib/geocoder/lookups/nominatim.rb +16 -13
  17. data/lib/geocoder/lookups/test.rb +8 -6
  18. data/lib/geocoder/lookups/yahoo.rb +49 -10
  19. data/lib/geocoder/lookups/yandex.rb +15 -8
  20. data/lib/geocoder/models/mongoid.rb +0 -1
  21. data/lib/geocoder/query.rb +88 -0
  22. data/lib/geocoder/results/mapquest.rb +2 -61
  23. data/lib/geocoder/results/nominatim.rb +24 -3
  24. data/lib/geocoder/sql.rb +104 -0
  25. data/lib/geocoder/stores/active_record.rb +68 -140
  26. data/lib/geocoder/stores/mongo_base.rb +2 -2
  27. data/lib/geocoder/version.rb +1 -1
  28. data/test/active_record_test.rb +15 -0
  29. data/test/calculations_test.rb +7 -0
  30. data/test/error_handling_test.rb +7 -7
  31. data/test/fixtures/yahoo_madison_square_garden.json +49 -43
  32. data/test/fixtures/yahoo_v1_madison_square_garden.json +46 -0
  33. data/test/fixtures/yahoo_v1_no_results.json +10 -0
  34. data/test/https_test.rb +2 -2
  35. data/test/integration/smoke_test.rb +6 -4
  36. data/test/lookup_test.rb +13 -6
  37. data/test/query_test.rb +34 -0
  38. data/test/result_test.rb +1 -1
  39. data/test/services_test.rb +48 -7
  40. data/test/test_helper.rb +64 -49
  41. data/test/test_mode_test.rb +0 -1
  42. metadata +13 -7
  43. data/README.rdoc +0 -552
  44. data/test/fixtures/yahoo_garbage.json +0 -50
  45. data/test/input_handling_test.rb +0 -43
@@ -59,7 +59,7 @@ module Geocoder::Store
59
59
  do_lookup(false) do |o,rs|
60
60
  if r = rs.first
61
61
  unless r.coordinates.nil?
62
- o.send :write_attribute, self.class.geocoder_options[:coordinates], r.coordinates.reverse
62
+ o.__send__ "#{self.class.geocoder_options[:coordinates]}=", r.coordinates.reverse
63
63
  end
64
64
  r.coordinates
65
65
  end
@@ -74,7 +74,7 @@ module Geocoder::Store
74
74
  do_lookup(true) do |o,rs|
75
75
  if r = rs.first
76
76
  unless r.address.nil?
77
- o.send :write_attribute, self.class.geocoder_options[:fetched_address], r.address
77
+ o.__send__ "#{self.class.geocoder_options[:fetched_address]}=", r.address
78
78
  end
79
79
  r.address
80
80
  end
@@ -1,3 +1,3 @@
1
1
  module Geocoder
2
- VERSION = "1.1.3"
2
+ VERSION = "1.1.4"
3
3
  end
@@ -0,0 +1,15 @@
1
+ # encoding: utf-8
2
+ require 'test_helper'
3
+
4
+ class ActiveRecordTest < Test::Unit::TestCase
5
+
6
+ def test_exclude_condition_when_model_has_a_custom_primary_key
7
+ venue = VenuePlus.new(*venue_params(:msg))
8
+
9
+ # just call private method directly so we don't have to stub .near scope
10
+ conditions = venue.class.send(:add_exclude_condition, ["fake_condition"], venue)
11
+
12
+ assert_match( /#{VenuePlus.primary_key}/, conditions.join)
13
+ end
14
+
15
+ end
@@ -185,4 +185,11 @@ class CalculationsTest < Test::Unit::TestCase
185
185
  assert !Geocoder::Calculations.coordinates_present?(Geocoder::Calculations::NAN)
186
186
  assert !Geocoder::Calculations.coordinates_present?(3.23, nil)
187
187
  end
188
+
189
+ def test_extract_coordinates
190
+ coords = [-23,47]
191
+ l = Landmark.new("Madagascar", coords[0], coords[1])
192
+ assert_equal coords, Geocoder::Calculations.extract_coordinates(l)
193
+ assert_equal coords, Geocoder::Calculations.extract_coordinates(coords)
194
+ end
188
195
  end
@@ -10,7 +10,7 @@ class ErrorHandlingTest < Test::Unit::TestCase
10
10
  def test_does_not_choke_on_timeout
11
11
  # keep test output clean: suppress timeout warning
12
12
  orig = $VERBOSE; $VERBOSE = nil
13
- all_lookups_except_test.each do |l|
13
+ Geocoder::Lookup.all_services_except_test.each do |l|
14
14
  Geocoder::Configuration.lookup = l
15
15
  assert_nothing_raised { Geocoder.search("timeout") }
16
16
  end
@@ -19,20 +19,20 @@ class ErrorHandlingTest < Test::Unit::TestCase
19
19
 
20
20
  def test_always_raise_timeout_error
21
21
  Geocoder::Configuration.always_raise = [TimeoutError]
22
- all_lookups_except_test.each do |l|
23
- lookup = Geocoder.send(:get_lookup, l)
22
+ Geocoder::Lookup.all_services_except_test.each do |l|
23
+ lookup = Geocoder::Lookup.get(l)
24
24
  assert_raises TimeoutError do
25
- lookup.send(:results, "timeout")
25
+ lookup.send(:results, Geocoder::Query.new("timeout"))
26
26
  end
27
27
  end
28
28
  end
29
29
 
30
30
  def test_always_raise_socket_error
31
31
  Geocoder::Configuration.always_raise = [SocketError]
32
- all_lookups_except_test.each do |l|
33
- lookup = Geocoder.send(:get_lookup, l)
32
+ Geocoder::Lookup.all_services_except_test.each do |l|
33
+ lookup = Geocoder::Lookup.get(l)
34
34
  assert_raises SocketError do
35
- lookup.send(:results, "socket_error")
35
+ lookup.send(:results, Geocoder::Query.new("socket_error"))
36
36
  end
37
37
  end
38
38
  end
@@ -1,46 +1,52 @@
1
1
  {
2
- "ResultSet":{
3
- "version":"1.0",
4
- "Error":0,
5
- "ErrorMessage":"No error",
6
- "Locale":"us_US",
7
- "Quality":90,
8
- "Found":1,
9
- "Results":[{
10
- "quality":90,
11
- "latitude":"40.750381",
12
- "longitude":"-73.993988",
13
- "offsetlat":"40.750381",
14
- "offsetlon":"-73.993988",
15
- "radius":100,
16
- "name":"Madison Square Garden",
17
- "line1":"Madison Square Garden",
18
- "line2":"New York, NY 10001",
19
- "line3":"",
20
- "line4":"United States",
21
- "house":"",
22
- "street":"",
23
- "xstreet":"",
24
- "unittype":"",
25
- "unit":"",
26
- "postal":"10001",
27
- "neighborhood":"",
28
- "city":"New York",
29
- "county":"New York County",
30
- "state":"New York",
31
- "country":"United States",
32
- "countrycode":"US",
33
- "statecode":"NY",
34
- "countycode":"",
35
- "uzip":"10001",
36
- "hash":"",
37
- "woeid":23617041,
38
- "woetype":20,
39
- "cross":"",
40
- "timezone":"America/New_York",
41
- "neighborhood":"Garment District|Midtown|Midtown West|Manhattan",
42
- "areacode":"212",
43
- "boundingbox":{"north":"40.750832","south":"40.749931","east":"-73.993393","west":"-73.994591"}
44
- }]
2
+ "@lang": "en-US",
3
+ "ResultSet": {
4
+ "@version": "2.0",
5
+ "@lang": "en-US",
6
+ "Error": "0",
7
+ "ErrorMessage": "No error",
8
+ "Locale": "en-US",
9
+ "Found": "1",
10
+ "Quality": "90",
11
+ "Result": {
12
+ "quality": "90",
13
+ "latitude": "40.750381",
14
+ "longitude": "-73.993988",
15
+ "offsetlat": "40.750381",
16
+ "offsetlon": "-73.993988",
17
+ "radius": "100",
18
+ "boundingbox": {
19
+ "north": "40.750832",
20
+ "south": "40.749931",
21
+ "east": "-73.993393",
22
+ "west": "-73.994591"
23
+ },
24
+ "name": "Madison Square Garden",
25
+ "line1": "Madison Square Garden",
26
+ "line2": "New York, NY 10001",
27
+ "line3": "",
28
+ "line4": "United States",
29
+ "cross": "",
30
+ "house": "",
31
+ "street": "",
32
+ "xstreet": "",
33
+ "unittype": "",
34
+ "unit": "",
35
+ "postal": "10001",
36
+ "neighborhood": "Garment District|Midtown|Midtown West|Manhattan",
37
+ "city": "New York",
38
+ "county": "New York County",
39
+ "state": "New York",
40
+ "country": "United States",
41
+ "countrycode": "US",
42
+ "statecode": "NY",
43
+ "countycode": "",
44
+ "timezone": "America/New_York",
45
+ "areacode": "212",
46
+ "uzip": "10001",
47
+ "hash": "",
48
+ "woeid": "23617041",
49
+ "woetype": "20"
50
+ }
45
51
  }
46
52
  }
@@ -0,0 +1,46 @@
1
+ {
2
+ "ResultSet":{
3
+ "version":"1.0",
4
+ "Error":0,
5
+ "ErrorMessage":"No error",
6
+ "Locale":"us_US",
7
+ "Quality":90,
8
+ "Found":1,
9
+ "Results":[{
10
+ "quality":90,
11
+ "latitude":"40.750381",
12
+ "longitude":"-73.993988",
13
+ "offsetlat":"40.750381",
14
+ "offsetlon":"-73.993988",
15
+ "radius":100,
16
+ "name":"Madison Square Garden",
17
+ "line1":"Madison Square Garden",
18
+ "line2":"New York, NY 10001",
19
+ "line3":"",
20
+ "line4":"United States",
21
+ "house":"",
22
+ "street":"",
23
+ "xstreet":"",
24
+ "unittype":"",
25
+ "unit":"",
26
+ "postal":"10001",
27
+ "neighborhood":"",
28
+ "city":"New York",
29
+ "county":"New York County",
30
+ "state":"New York",
31
+ "country":"United States",
32
+ "countrycode":"US",
33
+ "statecode":"NY",
34
+ "countycode":"",
35
+ "uzip":"10001",
36
+ "hash":"",
37
+ "woeid":23617041,
38
+ "woetype":20,
39
+ "cross":"",
40
+ "timezone":"America/New_York",
41
+ "neighborhood":"Garment District|Midtown|Midtown West|Manhattan",
42
+ "areacode":"212",
43
+ "boundingbox":{"north":"40.750832","south":"40.749931","east":"-73.993393","west":"-73.994591"}
44
+ }]
45
+ }
46
+ }
@@ -0,0 +1,10 @@
1
+ {
2
+ "ResultSet":{
3
+ "version":"1.0",
4
+ "Error":0,
5
+ "ErrorMessage":"No error",
6
+ "Locale":"us_US",
7
+ "Quality":10,
8
+ "Found":0
9
+ }
10
+ }
@@ -6,11 +6,11 @@ class HttpsTest < Test::Unit::TestCase
6
6
  def test_uses_https_for_secure_query
7
7
  Geocoder::Configuration.use_https = true
8
8
  g = Geocoder::Lookup::Google.new
9
- assert_match /^https:/, g.send(:query_url, {:a => 1, :b => 2})
9
+ assert_match /^https:/, g.send(:query_url, Geocoder::Query.new("test"))
10
10
  end
11
11
 
12
12
  def test_uses_http_by_default
13
13
  g = Geocoder::Lookup::Google.new
14
- assert_match /^http:/, g.send(:query_url, {:a => 1, :b => 2})
14
+ assert_match /^http:/, g.send(:query_url, Geocoder::Query.new("test"))
15
15
  end
16
16
  end
@@ -8,15 +8,17 @@ class SmokeTest < Test::Unit::TestCase
8
8
 
9
9
  def test_simple_zip_code_search
10
10
  result = Geocoder.search "27701"
11
- assert_equal "Durham", result.first.city
12
- assert_equal "North Carolina", result.first.state
11
+ assert_not_nil (r = result.first)
12
+ assert_equal "Durham", r.city
13
+ assert_equal "North Carolina", r.state
13
14
  end
14
15
 
15
16
  def test_simple_zip_code_search_with_ssl
16
17
  Geocoder::Configuration.use_https = true
17
18
  result = Geocoder.search "27701"
18
- assert_equal "Durham", result.first.city
19
- assert_equal "North Carolina", result.first.state
19
+ assert_not_nil (r = result.first)
20
+ assert_equal "Durham", r.city
21
+ assert_equal "North Carolina", r.state
20
22
  ensure
21
23
  Geocoder::Configuration.use_https = false
22
24
  end
@@ -4,13 +4,20 @@ require 'test_helper'
4
4
  class LookupTest < Test::Unit::TestCase
5
5
 
6
6
  def test_search_returns_empty_array_when_no_results
7
- all_lookups_except_test.each do |l|
8
- lookup = Geocoder.send(:get_lookup, l)
9
- assert_equal [], lookup.send(:results, "no results"),
7
+ Geocoder::Lookup.all_services_except_test.each do |l|
8
+ lookup = Geocoder::Lookup.get(l)
9
+ assert_equal [], lookup.send(:results, Geocoder::Query.new("no results")),
10
10
  "Lookup #{l} does not return empty array when no results."
11
11
  end
12
12
  end
13
13
 
14
+ def test_does_not_choke_on_nil_address
15
+ Geocoder::Lookup.all_services.each do |l|
16
+ Geocoder::Configuration.lookup = l
17
+ assert_nothing_raised { Venue.new("Venue", nil).geocode }
18
+ end
19
+ end
20
+
14
21
  def test_hash_to_query
15
22
  g = Geocoder::Lookup::Google.new
16
23
  assert_equal "a=1&b=2", g.send(:hash_to_query, {:a => 1, :b => 2})
@@ -19,19 +26,19 @@ class LookupTest < Test::Unit::TestCase
19
26
  def test_google_api_key
20
27
  Geocoder::Configuration.api_key = "MY_KEY"
21
28
  g = Geocoder::Lookup::Google.new
22
- assert_match "key=MY_KEY", g.send(:query_url, "Madison Square Garden, New York, NY 10001, United States")
29
+ assert_match "key=MY_KEY", g.send(:query_url, Geocoder::Query.new("Madison Square Garden, New York, NY 10001, United States"))
23
30
  end
24
31
 
25
32
  def test_yahoo_app_id
26
33
  Geocoder::Configuration.api_key = "MY_KEY"
27
34
  g = Geocoder::Lookup::Yahoo.new
28
- assert_match "appid=MY_KEY", g.send(:query_url, "Madison Square Garden, New York, NY 10001, United States")
35
+ assert_match "appid=MY_KEY", g.send(:query_url, Geocoder::Query.new("Madison Square Garden, New York, NY 10001, United States"))
29
36
  end
30
37
 
31
38
  def test_geocoder_ca_showpostal
32
39
  Geocoder::Configuration.api_key = "MY_KEY"
33
40
  g = Geocoder::Lookup::GeocoderCa.new
34
- assert_match "showpostal=1", g.send(:query_url, "Madison Square Garden, New York, NY 10001, United States")
41
+ assert_match "showpostal=1", g.send(:query_url, Geocoder::Query.new("Madison Square Garden, New York, NY 10001, United States"))
35
42
  end
36
43
 
37
44
  end
@@ -0,0 +1,34 @@
1
+ # encoding: utf-8
2
+ require 'test_helper'
3
+
4
+ class QueryTest < Test::Unit::TestCase
5
+
6
+ def test_ip_address_detection
7
+ assert Geocoder::Query.new("232.65.123.94").ip_address?
8
+ assert Geocoder::Query.new("666.65.123.94").ip_address? # technically invalid
9
+ assert Geocoder::Query.new("::ffff:12.34.56.78").ip_address?
10
+ assert !Geocoder::Query.new("232.65.123.94.43").ip_address?
11
+ assert !Geocoder::Query.new("232.65.123").ip_address?
12
+ assert !Geocoder::Query.new("::ffff:123.456.789").ip_address?
13
+ end
14
+
15
+ def test_blank_query_detection
16
+ assert Geocoder::Query.new(nil).blank?
17
+ assert Geocoder::Query.new("").blank?
18
+ assert Geocoder::Query.new("\t ").blank?
19
+ assert !Geocoder::Query.new("a").blank?
20
+ assert !Geocoder::Query.new("Москва").blank? # no ASCII characters
21
+ end
22
+
23
+ def test_coordinates_detection
24
+ assert Geocoder::Query.new("51.178844,5").coordinates?
25
+ assert Geocoder::Query.new("51.178844, -1.826189").coordinates?
26
+ assert !Geocoder::Query.new("232.65.123").coordinates?
27
+ end
28
+
29
+ def test_loopback_ip_address
30
+ assert Geocoder::Query.new("0.0.0.0").loopback_ip_address?
31
+ assert Geocoder::Query.new("127.0.0.1").loopback_ip_address?
32
+ assert !Geocoder::Query.new("232.65.123.234").loopback_ip_address?
33
+ end
34
+ end
@@ -4,7 +4,7 @@ require 'test_helper'
4
4
  class ResultTest < Test::Unit::TestCase
5
5
 
6
6
  def test_result_has_required_attributes
7
- all_lookups_except_test.each do |l|
7
+ Geocoder::Lookup.all_services_except_test.each do |l|
8
8
  Geocoder::Configuration.lookup = l
9
9
  result = Geocoder.search([45.423733, -75.676333]).first
10
10
  assert_result_has_required_attributes(result)
@@ -4,6 +4,18 @@ require 'test_helper'
4
4
  class ServicesTest < Test::Unit::TestCase
5
5
 
6
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
+
7
19
  # --- Google ---
8
20
 
9
21
  def test_google_result_components
@@ -28,6 +40,14 @@ class ServicesTest < Test::Unit::TestCase
28
40
  result.precision
29
41
  end
30
42
 
43
+ def test_google_query_url_contains_bounds
44
+ lookup = Geocoder::Lookup::Google.new
45
+ url = lookup.send(:query_url, Geocoder::Query.new(
46
+ "Some Intersection",
47
+ :bounds => [[40.0, -120.0], [39.0, -121.0]]
48
+ ))
49
+ assert_match /bounds=40.0+%2C-120.0+%7C39.0+%2C-121.0+/, url
50
+ end
31
51
 
32
52
  # --- Google Premier ---
33
53
 
@@ -41,23 +61,44 @@ class ServicesTest < Test::Unit::TestCase
41
61
  def test_google_premier_query_url
42
62
  Geocoder::Configuration.api_key = ["deadbeef", "gme-test", "test-dev"]
43
63
  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=",
44
- Geocoder::Lookup::GooglePremier.new.send(:query_url, "Madison Square Garden, New York, NY", false)
64
+ Geocoder::Lookup::GooglePremier.new.send(:query_url, Geocoder::Query.new("Madison Square Garden, New York, NY"))
45
65
  end
46
66
 
47
67
 
48
68
  # --- Yahoo ---
49
69
 
50
- def test_yahoo_result_components
70
+ def test_yahoo_v1_no_results
51
71
  Geocoder::Configuration.lookup = :yahoo
52
- result = Geocoder.search("Madison Square Garden, New York, NY").first
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
53
78
  assert_equal "10001", result.postal_code
54
79
  end
55
80
 
56
- def test_yahoo_address_formatting
81
+ def test_yahoo_v1_address_formatting
57
82
  Geocoder::Configuration.lookup = :yahoo
58
- result = Geocoder.search("Madison Square Garden, New York, NY").first
59
- assert_equal "Madison Square Garden, New York, NY 10001, United States",
60
- result.address
83
+ result = Geocoder.search("madison square garden v1").first
84
+ assert_equal "Madison Square Garden, New York, NY 10001, United States", result.address
85
+ end
86
+
87
+ def test_yahoo_v2_no_results
88
+ Geocoder::Configuration.lookup = :yahoo
89
+ assert_equal [], Geocoder.search("no results")
90
+ end
91
+
92
+ def test_yahoo_v2_result_components
93
+ Geocoder::Configuration.lookup = :yahoo
94
+ result = Geocoder.search("madison square garden v2").first
95
+ assert_equal "10001", result.postal_code
96
+ end
97
+
98
+ def test_yahoo_v2_address_formatting
99
+ Geocoder::Configuration.lookup = :yahoo
100
+ result = Geocoder.search("madison square garden v2").first
101
+ assert_equal "Madison Square Garden, New York, NY 10001, United States", result.address
61
102
  end
62
103
 
63
104