graticule 2.3.0 → 2.4.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.
Files changed (77) hide show
  1. data/.autotest +13 -0
  2. data/.gitignore +10 -0
  3. data/.travis.yml +14 -0
  4. data/CHANGELOG.txt +4 -1
  5. data/Gemfile +7 -0
  6. data/LICENSE.txt +1 -1
  7. data/README.md +122 -0
  8. data/Rakefile +78 -0
  9. data/graticule.gemspec +26 -0
  10. data/lib/graticule/cli.rb +3 -1
  11. data/lib/graticule/geocoder/google.rb +33 -4
  12. data/lib/graticule/geocoder/mapquest.rb +52 -59
  13. data/lib/graticule/precision.rb +3 -1
  14. data/lib/graticule/version.rb +1 -1
  15. data/site/index.html +114 -0
  16. data/site/plugin.html +82 -0
  17. data/site/stylesheets/style.css +69 -0
  18. data/test/config.yml.default +33 -0
  19. data/test/fixtures/responses/freethepostcode/not_found.txt +3 -0
  20. data/test/fixtures/responses/freethepostcode/success.txt +2 -0
  21. data/test/fixtures/responses/geocoder_ca/success.xml +12 -0
  22. data/test/fixtures/responses/geocoder_us/success.xml +8 -0
  23. data/test/fixtures/responses/geocoder_us/unknown.xml +1 -0
  24. data/test/fixtures/responses/geonames/missing.xml +4 -0
  25. data/test/fixtures/responses/geonames/success.xml +14 -0
  26. data/test/fixtures/responses/geonames/unknown.xml +4 -0
  27. data/test/fixtures/responses/google/address.json +64 -0
  28. data/test/fixtures/responses/google/badkey.json +4 -0
  29. data/test/fixtures/responses/google/country.json +43 -0
  30. data/test/fixtures/responses/google/limit.json +4 -0
  31. data/test/fixtures/responses/google/locality.json +58 -0
  32. data/test/fixtures/responses/google/region.json +48 -0
  33. data/test/fixtures/responses/google/server_error.json +4 -0
  34. data/test/fixtures/responses/google/street.json +58 -0
  35. data/test/fixtures/responses/google/success.json +64 -0
  36. data/test/fixtures/responses/google/success_multiple_results.json +68 -0
  37. data/test/fixtures/responses/google/zero_results.json +4 -0
  38. data/test/fixtures/responses/host_ip/private.txt +4 -0
  39. data/test/fixtures/responses/host_ip/success.txt +4 -0
  40. data/test/fixtures/responses/host_ip/unknown.txt +4 -0
  41. data/test/fixtures/responses/local_search_maps/empty.txt +1 -0
  42. data/test/fixtures/responses/local_search_maps/not_found.txt +1 -0
  43. data/test/fixtures/responses/local_search_maps/success.txt +1 -0
  44. data/test/fixtures/responses/mapquest/multi_result.xml +317 -0
  45. data/test/fixtures/responses/mapquest/success.xml +54 -0
  46. data/test/fixtures/responses/multimap/missing_params.xml +4 -0
  47. data/test/fixtures/responses/multimap/no_matches.xml +4 -0
  48. data/test/fixtures/responses/multimap/success.xml +19 -0
  49. data/test/fixtures/responses/simple_geo/error.json +4 -0
  50. data/test/fixtures/responses/simple_geo/success.json +255 -0
  51. data/test/fixtures/responses/yahoo/success.xml +3 -0
  52. data/test/fixtures/responses/yahoo/unknown_address.xml +6 -0
  53. data/test/fixtures/responses/yandex/badkey.xml +5 -0
  54. data/test/fixtures/responses/yandex/success.xml +204 -0
  55. data/test/graticule/distance_test.rb +59 -0
  56. data/test/graticule/geocoder/freethepostcode_test.rb +37 -0
  57. data/test/graticule/geocoder/geocoder_ca_test.rb +42 -0
  58. data/test/graticule/geocoder/geocoder_us_test.rb +44 -0
  59. data/test/graticule/geocoder/geocoders.rb +56 -0
  60. data/test/graticule/geocoder/geonames_test.rb +56 -0
  61. data/test/graticule/geocoder/google_signed_test.rb +19 -0
  62. data/test/graticule/geocoder/google_test.rb +138 -0
  63. data/test/graticule/geocoder/host_ip_test.rb +41 -0
  64. data/test/graticule/geocoder/local_search_maps_test.rb +31 -0
  65. data/test/graticule/geocoder/mapquest_test.rb +56 -0
  66. data/test/graticule/geocoder/multi_test.rb +52 -0
  67. data/test/graticule/geocoder/multimap_test.rb +53 -0
  68. data/test/graticule/geocoder/simple_geo_test.rb +45 -0
  69. data/test/graticule/geocoder/yahoo_test.rb +50 -0
  70. data/test/graticule/geocoder/yandex_test.rb +42 -0
  71. data/test/graticule/geocoder_test.rb +24 -0
  72. data/test/graticule/location_test.rb +79 -0
  73. data/test/graticule/precision_test.rb +38 -0
  74. data/test/mocks/uri.rb +53 -0
  75. data/test/test_helper.rb +32 -0
  76. metadata +147 -75
  77. data/README.textile +0 -64
@@ -0,0 +1,41 @@
1
+ # encoding: UTF-8
2
+ require 'test_helper'
3
+
4
+ module Graticule
5
+ module Geocoder
6
+ class HostIpTest < Test::Unit::TestCase
7
+
8
+ def setup
9
+ @geocoder = HostIp.new
10
+ URI::HTTP.responses = []
11
+ URI::HTTP.uris = []
12
+ end
13
+
14
+ def test_success
15
+ prepare_response :success
16
+
17
+ location = Location.new :country => 'US', :locality => 'Mountain View',
18
+ :region => 'CA', :latitude => 37.402, :longitude => -122.078
19
+
20
+ assert_equal location, @geocoder.locate('64.233.167.99')
21
+ end
22
+
23
+ def test_unknown
24
+ prepare_response :unknown
25
+ assert_raises(AddressError) { @geocoder.locate('127.0.0.1') }
26
+ end
27
+
28
+ def test_private_ip
29
+ prepare_response :private
30
+ assert_raises(AddressError) { @geocoder.locate('127.0.0.1') }
31
+ end
32
+
33
+ private
34
+
35
+ def prepare_response(id = :success)
36
+ URI::HTTP.responses << response('host_ip', id, 'txt')
37
+ end
38
+
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,31 @@
1
+ # encoding: UTF-8
2
+ require 'test_helper'
3
+
4
+ module Graticule
5
+ module Geocoder
6
+ class LocalSearchMapsTest < Test::Unit::TestCase
7
+
8
+ def setup
9
+ @geocoder = LocalSearchMaps.new
10
+ URI::HTTP.responses = []
11
+ URI::HTTP.uris = []
12
+ end
13
+
14
+ def test_success
15
+ prepare_response :success
16
+
17
+ location = Location.new :latitude => 51.510036, :longitude => -0.130427
18
+
19
+ assert_equal location, @geocoder.locate(:street => '48 Leicester Square',
20
+ :locality => 'London', :country => 'UK')
21
+ end
22
+
23
+ private
24
+
25
+ def prepare_response(id = :success)
26
+ URI::HTTP.responses << response('local_search_maps', id, 'txt')
27
+ end
28
+
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,56 @@
1
+ # encoding: UTF-8
2
+ require 'test_helper'
3
+
4
+ module Graticule
5
+ module Geocoder
6
+ class MapquestTest < Test::Unit::TestCase
7
+ def setup
8
+ URI::HTTP.responses = []
9
+ URI::HTTP.uris = []
10
+ @geocoder = Mapquest.new('api_key')
11
+ end
12
+
13
+ def test_success
14
+ prepare_response(:success)
15
+ location = Location.new(
16
+ :country => "US",
17
+ :latitude => 44.15175,
18
+ :locality => "Lovell",
19
+ :longitude => -70.893,
20
+ :postal_code => "04051-3919",
21
+ :precision => :point,
22
+ :region => "ME",
23
+ :street => "44 Allen Rd"
24
+ )
25
+ assert_equal(location, @geocoder.locate('44 Allen Rd., Lovell, ME 04051'))
26
+ end
27
+
28
+ def test_multi_result
29
+ prepare_response(:multi_result)
30
+ location = Location.new(
31
+ :country => "US",
32
+ :latitude => 40.925598,
33
+ :locality => "Stony Brook",
34
+ :longitude => -73.141403,
35
+ :postal_code => nil,
36
+ :precision => :locality,
37
+ :region => "NY",
38
+ :street => nil
39
+ )
40
+ assert_equal(location, @geocoder.locate('217 Union St., NY'))
41
+ end
42
+
43
+ def test_query_construction
44
+ request = Mapquest::Request.new("217 Union St., NY", "api_key")
45
+ query = %Q{key=api_key&outFormat=xml&inFormat=kvp&location=217%20Union%20St.,%20NY}
46
+ assert_equal(query, request.query)
47
+ end
48
+
49
+ protected
50
+
51
+ def prepare_response(id)
52
+ URI::HTTP.responses << response('mapquest', id)
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,52 @@
1
+ # encoding: UTF-8
2
+ require 'test_helper'
3
+
4
+ module Graticule
5
+ module Geocoder
6
+ class MultiTest < Test::Unit::TestCase
7
+
8
+ def setup
9
+ @mock_geocoders = [mock("geocoder 1"), mock("geocoder 2")]
10
+ @mock_geocoders.each {|g| g.stubs(:locate) }
11
+ @geocoder = Multi.new(*@mock_geocoders)
12
+ end
13
+
14
+ def test_locate_calls_each_geocoder_and_raises_error
15
+ @mock_geocoders.each do |g|
16
+ g.expects(:locate).with('test').raises(Graticule::AddressError)
17
+ end
18
+ assert_raises(Graticule::AddressError) { @geocoder.locate 'test' }
19
+ end
20
+
21
+ def test_locate_returns_first_result_without_calling_others
22
+ result = mock("result")
23
+ @mock_geocoders.first.expects(:locate).returns(result)
24
+ @mock_geocoders.last.expects(:locate).never
25
+ assert_equal result, @geocoder.locate('test')
26
+ end
27
+
28
+ def test_locate_with_custom_block
29
+ @mock_geocoders.first.expects(:locate).returns(1)
30
+ @mock_geocoders.last.expects(:locate).returns(2)
31
+ @geocoder = Multi.new(*@mock_geocoders) {|r| r == 2 }
32
+ assert_equal 2, @geocoder.locate('test')
33
+ end
34
+
35
+ def test_locate_with_custom_block_and_no_match
36
+ @mock_geocoders.first.expects(:locate).returns(1)
37
+ @mock_geocoders.last.expects(:locate).returns(2)
38
+ @geocoder = Multi.new(*@mock_geocoders) {|r| r == 3 }
39
+ assert_raises(Graticule::AddressError) { @geocoder.locate('test') }
40
+ end
41
+
42
+ def test_timeout
43
+ @mock = @mock_geocoders.first
44
+ def @mock.locate(*x)
45
+ sleep 1
46
+ end
47
+ @geocoder = Multi.new(@mock, :timeout => 0.1)
48
+ assert_raise(Timeout::Error) { @geocoder.locate('foo') }
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,53 @@
1
+ # encoding: UTF-8
2
+ require 'test_helper'
3
+
4
+ module Graticule
5
+ module Geocoder
6
+ class MultimapTest < Test::Unit::TestCase
7
+
8
+ def setup
9
+ URI::HTTP.responses = []
10
+ URI::HTTP.uris = []
11
+ @geocoder = Multimap.new 'API_KEY'
12
+ @location = Location.new(
13
+ :street => "Oxford Street",
14
+ :locality => "LONDON",
15
+ :postal_code => "W1",
16
+ :country => "GB",
17
+ :longitude => -0.14839,
18
+ :latitude => 51.51452,
19
+ :precision => :address
20
+ )
21
+ end
22
+
23
+ def test_locate
24
+ prepare_response(:success)
25
+ assert_equal @location, @geocoder.locate('Oxford Street, LONDON, W1')
26
+ end
27
+
28
+ def test_url_from_string
29
+ prepare_response(:success)
30
+ @geocoder.locate('Oxford Street, LONDON, W1')
31
+ assert_equal 'http://clients.multimap.com/API/geocode/1.2/API_KEY?qs=Oxford%20Street,%20LONDON,%20W1', URI::HTTP.uris.first
32
+ end
33
+
34
+ def test_url_from_location
35
+ prepare_response(:success)
36
+ @geocoder.locate(:street => 'Oxford Street', :locality => 'London')
37
+ assert_equal 'http://clients.multimap.com/API/geocode/1.2/API_KEY?city=London&countryCode=&postalCode=&region=&street=Oxford%20Street', URI::HTTP.uris.first
38
+ end
39
+
40
+
41
+ def test_locate_bad_address
42
+ prepare_response(:no_matches)
43
+ assert_raise(Error) { @geocoder.locate('yucksthoeusthaoeusnhtaosu') }
44
+ end
45
+
46
+ protected
47
+ def prepare_response(id)
48
+ URI::HTTP.responses << response('multimap', id)
49
+ end
50
+
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,45 @@
1
+ # encoding: UTF-8
2
+ require 'test_helper'
3
+
4
+ module Graticule
5
+ module Geocoder
6
+ class SimpleGeoTest < Test::Unit::TestCase
7
+
8
+ def setup
9
+ URI::HTTP.responses = []
10
+ URI::HTTP.uris = []
11
+ @geocoder = SimpleGeo.new('TOKEN')
12
+ end
13
+
14
+ def test_success
15
+ return unless prepare_response(:success)
16
+
17
+ location = Location.new(
18
+ :longitude => -117.373982,
19
+ :latitude => 34.482358,
20
+ :precision => :unknown
21
+ )
22
+ assert_equal location, @geocoder.locate('1600 Amphitheatre Parkway, Mountain View, CA')
23
+ end
24
+
25
+ def test_error
26
+ prepare_response :error
27
+ assert_raises(Error) { @geocoder.locate('') }
28
+ end
29
+
30
+ def test_time_zone
31
+ URI::HTTP.uris = []
32
+ URI::HTTP.responses = []
33
+ URI::HTTP.responses << response('simple_geo', :success, 'json')
34
+ los_angeles = Location.new(:latitude => 34.48, :longitude => -117.37)
35
+ assert_equal 'America/Los_Angeles', @geocoder.time_zone(los_angeles)
36
+ end
37
+
38
+ private
39
+
40
+ def prepare_response(id = :success)
41
+ URI::HTTP.responses << response('simple_geo', id, 'json')
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,50 @@
1
+ # encoding: UTF-8
2
+ require 'test_helper'
3
+
4
+ module Graticule
5
+ module Geocoder
6
+ class YahooTest < Test::Unit::TestCase
7
+
8
+ def setup
9
+ URI::HTTP.responses = []
10
+ URI::HTTP.uris = []
11
+ @geocoder = Yahoo.new 'APP_ID'
12
+ @location = Location.new(
13
+ :street => "701 1st Ave",
14
+ :locality => "Sunnyvale",
15
+ :region => "CA",
16
+ :postal_code => "94089-1019",
17
+ :country => "US",
18
+ :longitude => -122.025055,
19
+ :latitude => 37.416397,
20
+ :precision => :address,
21
+ :warning => "The exact location could not be found, here is the closest match: 701 First Ave, Sunnyvale, CA 94089"
22
+ )
23
+ end
24
+
25
+ def test_locate
26
+ prepare_response(:success)
27
+ assert_equal @location, @geocoder.locate('701 First Street, Sunnyvale, CA')
28
+ end
29
+
30
+ def test_url
31
+ prepare_response(:success)
32
+ @geocoder.locate('701 First Street, Sunnyvale, CA')
33
+ assert_equal 'http://api.local.yahoo.com/MapsService/V1/geocode?appid=APP_ID&location=701%20First%20Street,%20Sunnyvale,%20CA&output=xml',
34
+ URI::HTTP.uris.first
35
+ end
36
+
37
+
38
+ def test_locate_bad_address
39
+ prepare_response(:unknown_address)
40
+ assert_raise(Error) { @geocoder.locate('yucksthoeusthaoeusnhtaosu') }
41
+ end
42
+
43
+ protected
44
+ def prepare_response(id)
45
+ URI::HTTP.responses << response('yahoo', id)
46
+ end
47
+
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,42 @@
1
+ # encoding: UTF-8
2
+ require 'test_helper'
3
+
4
+ module Graticule
5
+ module Geocoder
6
+ class YandexTest < Test::Unit::TestCase
7
+ def setup
8
+ URI::HTTP.responses = []
9
+ URI::HTTP.uris = []
10
+ @geocoder = Yandex.new('APP_ID')
11
+ end
12
+
13
+ def test_success
14
+ return unless prepare_response(:success)
15
+
16
+ location = Location.new(
17
+ :street => "Моховая улица",
18
+ :locality => "Москва",
19
+ :country => "RU",
20
+ :longitude => 37.612281,
21
+ :latitude => 55.753342,
22
+ :precision => :address
23
+ )
24
+ assert_equal location, @geocoder.locate('Россия, Москва, ул. Моховая, д.18')
25
+ end
26
+
27
+ def test_bad_key
28
+ return unless prepare_response(:badkey)
29
+
30
+ assert_raises(CredentialsError) { @geocoder.locate('x') }
31
+ end
32
+
33
+ protected
34
+
35
+ def prepare_response(id = :success)
36
+ URI::HTTP.responses << response('yandex', id)
37
+ end
38
+
39
+ end
40
+ end
41
+ end
42
+
@@ -0,0 +1,24 @@
1
+ # encoding: UTF-8
2
+ require 'test_helper'
3
+
4
+ module Graticule
5
+ class GeocoderTest < Test::Unit::TestCase
6
+
7
+ def test_bogus_service
8
+ assert_equal Geocoder::Bogus, Graticule.service(:bogus)
9
+ end
10
+
11
+ def test_yahoo_service
12
+ assert_equal Geocoder::Yahoo, Graticule.service(:yahoo)
13
+ end
14
+
15
+ def test_google_service
16
+ assert_equal Geocoder::Google, Graticule.service(:google)
17
+ end
18
+
19
+ def test_geocoder_us_service
20
+ assert_equal Geocoder::GeocoderUs, Graticule.service(:geocoder_us)
21
+ end
22
+
23
+ end
24
+ end
@@ -0,0 +1,79 @@
1
+ # encoding: UTF-8
2
+ require 'test_helper'
3
+
4
+ module Graticule
5
+ class LocationTest < Test::Unit::TestCase
6
+
7
+ def setup
8
+ @washington_dc = Location.new :latitude => 38.898748, :longitude => -77.037684,
9
+ :street => '1600 Pennsylvania Avenue, NW', :locality => 'Washington',
10
+ :region => 'DC', :postal_code => 20500, :country => 'US'
11
+ end
12
+
13
+ def test_distance_to
14
+ chicago = Location.new(:latitude => 41.85, :longitude => -87.65)
15
+ assert_in_delta 594.820, @washington_dc.distance_to(chicago), 1.0
16
+ end
17
+
18
+ def test_responds_to
19
+ [:latitude, :longitude, :street, :locality, :region, :postal_code, :country, :coordinates, :precision].each do |m|
20
+ assert Location.new.respond_to?(m), "should respond to #{m}"
21
+ end
22
+ end
23
+
24
+ def test_coordinates
25
+ l = Location.new(:latitude => 100, :longitude => 50)
26
+ assert_equal [100, 50], l.coordinates
27
+ end
28
+
29
+ def test_equal
30
+ assert_equal Location.new, Location.new
31
+
32
+ attrs = {:latitude => 100.5389, :longitude => -147.5893, :street => '123 A Street',
33
+ :locality => 'Somewhere', :region => 'NO', :postal_code => '12345', :country => 'USA'}
34
+
35
+ assert_equal Location.new(attrs), Location.new(attrs)
36
+ attrs.each do |k,v|
37
+ assert_equal Location.new(k => v), Location.new(k => v)
38
+ assert_not_equal Location.new, Location.new(k => v)
39
+ assert_not_equal Location.new(attrs), Location.new(attrs.update(k => nil))
40
+ end
41
+ end
42
+
43
+ def test_antipode
44
+ chicago = Location.new(:latitude => 41.85, :longitude => -87.65)
45
+
46
+ assert_equal [-38.898748, 102.962316], @washington_dc.antipode.coordinates
47
+ assert_equal [-41.85, 92.35], chicago.antipode.coordinates
48
+ assert_equal [-41, -180], Graticule::Location.new(:latitude => 41, :longitude => 0).antipode.coordinates
49
+ assert_equal [-41, 179], Graticule::Location.new(:latitude => 41, :longitude => -1).antipode.coordinates
50
+ assert_equal [-41, -179], Graticule::Location.new(:latitude => 41, :longitude => 1).antipode.coordinates
51
+
52
+ assert_equal @washington_dc.coordinates, @washington_dc.antipode.antipode.coordinates
53
+ assert_equal chicago.coordinates, chicago.antipode.antipode.coordinates
54
+ end
55
+
56
+ def test_to_s
57
+ assert_equal "1600 Pennsylvania Avenue, NW\nWashington, DC 20500 US",
58
+ @washington_dc.to_s
59
+ assert_equal "1600 Pennsylvania Avenue, NW\nWashington, DC 20500",
60
+ @washington_dc.to_s(:country => false)
61
+ assert_equal "1600 Pennsylvania Avenue, NW\nWashington, DC 20500",
62
+ @washington_dc.to_s(:country => false)
63
+ assert_equal "1600 Pennsylvania Avenue, NW\nWashington, DC 20500\nlatitude: 38.898748, longitude: -77.037684",
64
+ @washington_dc.to_s(:country => false, :coordinates => true)
65
+ end
66
+
67
+ def test_blank?
68
+ assert Location.new.blank?
69
+ [:latitude, :longitude, :street, :locality, :region, :postal_code, :country].each do |attr|
70
+ assert !Location.new(attr => 'Foo').blank?
71
+ end
72
+ end
73
+
74
+ def test_casts_precision
75
+ assert_equal Precision::Region, Location.new(:precision => :region).precision
76
+ assert_equal Precision::Street, Location.new(:precision => Precision::Street).precision
77
+ end
78
+ end
79
+ end