mapquest 0.0.1 → 0.0.2

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/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format documentation
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # MapQuest [![Build Status](https://travis-ci.org/ggordan/mapquest.png?branch=master)](https://travis-ci.org/ggordan/mapquest)
1
+ # MapQuest [![Build Status](https://travis-ci.org/ggordan/mapquest.png?branch=master)](https://travis-ci.org/ggordan/mapquest) [![Code Climate](https://codeclimate.com/github/ggordan/mapquest.png)](https://codeclimate.com/github/ggordan/mapquest)
2
2
 
3
3
  A gem to communicate with the MapQuest web services.
4
4
 
@@ -28,7 +28,7 @@ Or install it yourself as:
28
28
  mapquest = MapQuest.new API_KEY
29
29
 
30
30
  # Get geolocation data
31
- data = mapquest.geocoding.decode :location => "London, UK"
31
+ data = mapquest.geocoding.address "London, UK"
32
32
 
33
33
  # Get lat/long coordinates of all the locations found
34
34
  data.locations.each { |location| puts location[:latLng] }
data/Rakefile CHANGED
@@ -3,7 +3,7 @@ require 'bundler/gem_tasks'
3
3
  require 'rspec/core/rake_task'
4
4
 
5
5
  RSpec::Core::RakeTask.new(:spec) do |spec|
6
- spec.pattern = FileList['test/**/*_spec.rb']
6
+ spec.pattern = FileList['spec/**/*_spec.rb']
7
7
  end
8
8
 
9
9
  task :default => :spec
@@ -8,27 +8,33 @@ require "mapquest/services/geocoding"
8
8
 
9
9
  class MapQuest
10
10
 
11
- attr_accessor :api_key, :response
12
- class Error < StandardError; end
11
+ attr_accessor :api_key
13
12
 
14
13
  def initialize(key)
15
14
  @api_key = key
16
15
  end
17
16
 
17
+ # Acess the geocoding API
18
18
  def geocoding
19
19
  Services::Geocoding.new self
20
20
  end
21
21
 
22
+ # Access the directions API
22
23
  def directions
23
24
  Services::Directions.new self
24
25
  end
25
26
 
27
+ # Request handler for the web services. Creates a new request based on the API method provided, and returns a new
28
+ # response object. Removes any empty parameters that were provided. This method is only used internally.
29
+ # ==Required parameters
30
+ # * method [Hash] The hash containing the API method, version and type.
31
+ # * params [Hash] The parameters used for creating the query string
32
+ # * response [Response] The response object of the API being called
26
33
  def request(method, params, response)
27
34
  req = Request.new method
28
35
  params.merge! :key => api_key
29
36
  params.each { |k,v| params.delete(k) if v.nil? }
30
- @response = response.new req.send(params)
31
- return @response
37
+ response.new req.query(params), params
32
38
  end
33
39
 
34
40
  end
@@ -8,7 +8,7 @@ class MapQuest
8
8
  super API_ROOT % [method[:location], method[:version], method[:call]]
9
9
  end
10
10
 
11
- def send(params)
11
+ def query(params)
12
12
  get :params => params
13
13
  end
14
14
 
@@ -1,12 +1,30 @@
1
1
  class MapQuest
2
2
  class Response
3
3
 
4
- attr_reader :response, :valid
4
+ attr_reader :response, :valid, :params
5
5
 
6
6
  class InvalidRequest < StandardError; end
7
7
 
8
- def initialize(response_string)
8
+ def initialize(response_string, params = {})
9
+ @params = params
9
10
  @response = JSON.parse(response_string, :symbolize_names => true)
11
+ valid_request?
12
+ end
13
+
14
+ # Check whether the request made to the API call is valid. Raises an error if the response code is 500
15
+ def valid_request?
16
+ # 400 - Error with input
17
+ # 403 - Key related error
18
+ # 500 -Unknown error
19
+ # Check http://www.mapquestapi.com/geocoding/status_codes.html for more details
20
+ @valid = case status[:code]
21
+ when 500
22
+ raise InvalidRequest
23
+ when 400, 403
24
+ false
25
+ else
26
+ true
27
+ end
10
28
  end
11
29
 
12
30
  def info
@@ -17,6 +35,10 @@ class MapQuest
17
35
  info[:copyright]
18
36
  end
19
37
 
38
+ def options
39
+ response[:options]
40
+ end
41
+
20
42
  # Returns information about the response.
21
43
  # :code is an integer return value. See http://www.mapquestapi.com/geocoding/status_codes.html
22
44
  # :messages subfield is an array of error messages which describe the status.
@@ -4,8 +4,19 @@ class MapQuest
4
4
 
5
5
  attr_accessor :mapquest
6
6
 
7
- def initialize(mq)
8
- @mapquest = mq
7
+ def initialize(mapquest)
8
+ @mapquest = mapquest
9
+ end
10
+
11
+ def call_api(api, version, call, options)
12
+ # Remove invalid options
13
+ options.keys.select { |k| api.class::VALID_OPTIONS.include? k }
14
+ api_method = {
15
+ :location => api.class::API_LOCATION,
16
+ :version => version,
17
+ :call => call
18
+ }
19
+ mapquest.request api_method, options, api.class::Response
9
20
  end
10
21
 
11
22
  end
@@ -1,30 +1,32 @@
1
1
  class MapQuest
2
2
  module Services
3
+ # The main class used for communicating with the MapQuest Directions API
3
4
  class Directions < Core
4
5
 
5
6
  API_LOCATION = :directions
7
+ VALID_OPTIONS = [:to, :from]
6
8
 
7
- def get(params)
8
- if params.has_key? :from && :to
9
- api_method = {
10
- :location => API_LOCATION,
11
- :version => '1',
12
- :call => 'route'
13
- }
14
- response = mapquest.request api_method, params, Response
9
+ # Allows you to search for direction to a location. It returns a response object of the route
10
+ #
11
+ # Example: .route :to => "London, UK", "Manchester, UK"
12
+ #
13
+ # ==Required parameters
14
+ # * from [String] The location where to end route
15
+ # * to [String] The location from which to start route
16
+ def route(from, to, options = {})
17
+ if from && to
18
+ options[:to] = to
19
+ options[:from] = from
20
+ call_api self, 1, 'route', options
15
21
  else
16
- raise Error
22
+ raise ArgumentError, 'The method must receive the to, and from parameters'
17
23
  end
18
24
  end
19
25
 
20
26
  class Response < MapQuest::Response
21
27
 
22
- def valid_request?
23
- if response[:route].any?
24
- true
25
- else
26
- false
27
- end
28
+ def initialize(response_string, params = {})
29
+ super
28
30
  end
29
31
 
30
32
  def route
@@ -38,25 +40,29 @@ class MapQuest
38
40
 
39
41
  # Returns the calculated distance of the route in <b>miles</b>
40
42
  def distance
41
- route[:distance].to_i
43
+ if valid
44
+ route[:distance].to_i
45
+ end
42
46
  end
43
47
 
44
48
  def locations
45
- route[:locations]
49
+ if valid
50
+ route[:locations]
51
+ end
46
52
  end
47
53
 
48
54
  # Returns a hash of the maneuvers in the route
49
55
  def maneuvers
50
- route[:legs].first[:maneuvers]
56
+ if valid
57
+ route[:legs].first[:maneuvers]
58
+ end
51
59
  end
52
60
 
53
61
  # Returns only the narratives for the route as a list
54
62
  def narrative
55
- narrative = []
56
- route[:legs].first[:maneuvers].each do |maneuver|
57
- narrative.push maneuver[:narrative]
63
+ if valid
64
+ route[:legs].first[:maneuvers].map { |maneuver| maneuver[:narrative] }
58
65
  end
59
- narrative
60
66
  end
61
67
 
62
68
  end
@@ -1,79 +1,60 @@
1
1
  class MapQuest
2
2
  module Services
3
+ # The main class used for communicating with the MapQuest Geocoding API
3
4
  class Geocoding < Core
4
5
 
5
6
  API_LOCATION = :geocoding
7
+ VALID_OPTIONS = [:location,:maxResults,:thumbMaps]
6
8
 
7
- # Returns a response object of the found locations
8
- # == Required parameters
9
- # * :location [String] The location for which you wish to get data
10
- # == Optional parameters
9
+ class TooManyLocations < StandardError; end
10
+
11
+ # Allows you to search for a single location and returns a response object of the found locations
12
+ #
13
+ # Example: .address :location => "London, UK"
14
+ #
15
+ # ==Required parameters
16
+ # * location [String] The location for which you wish to get data
17
+ # ==Optional parameters
11
18
  # * :maxResults [Integer] The number of results to limit the response to. Defaults to -1 (-1 indicates no limit)
12
19
  # * :thumbMaps [Boolean] Return a URL to a static map thumbnail image for a location. Defaults to true
13
- def decode(params = {})
14
- raise Error unless params.has_key? :location
15
-
16
- # Remove keys that are not supported
17
- params.keys.each { |k| params.delete(k) unless [:location,:maxResults,:thumbMaps].include? k }
18
- api_method = {
19
- :location => API_LOCATION,
20
- :version => '1',
21
- :call => 'address'
22
- }
23
- mapquest.request api_method, params, Response
20
+ def address(location, options = {})
21
+ raise ArgumentError, 'Method must receive a location (string)' unless location
22
+ options[:location] = location
23
+ call_api self, 1, 'address', options
24
24
  end
25
25
 
26
- # Returns a response object of the found locations
27
- # == Required parameters
28
- # * :location [Array] The lat, and lng to search for
29
- # == Optional parameters
26
+ # Allows you to search for a location using lat/lng values and returns a response object of the found locations
27
+ #
28
+ # Example: .reverse :location => ['40.0755','-76.329999']
29
+ #
30
+ # ==Required parameters
31
+ # * location [Array] The lat, and lng to search for
32
+ # ==Optional parameters
30
33
  # * :maxResults [Integer] The number of results to limit the response to. Defaults to -1 (-1 indicates no limit)
31
34
  # * :thumbMaps [Boolean] Return a URL to a static map thumbnail image for a location. Defaults to true
32
- def reverse(params = {})
33
- raise Error unless params.has_key?(:location) && params[:location].kind_of?(Array)
34
- params[:location] = params[:location].join(',')
35
- api_method = {
36
- :location => API_LOCATION,
37
- :version => '1',
38
- :call => 'reverse'
39
- }
40
- mapquest.request api_method, params, Response
35
+ def reverse(location, options = {})
36
+ raise ArgumentError, 'Method must receive a location (array)' unless location && location.kind_of?(Array)
37
+ options[:location] = location.join(',')
38
+ call_api self, 1, 'reverse', options
41
39
  end
42
40
 
43
- class Response < MapQuest::Response
44
41
 
45
- def initialize(response_string)
46
- super response_string
47
- valid_request?
48
- end
42
+ class Response < MapQuest::Response
49
43
 
50
- # Check whether the request made to the API call is valid. Raises an error if the response code is 500
51
- def valid_request?
52
- # 400 - Error with input
53
- # 403 - Key related error
54
- # 500 -Unknown error
55
- # Check http://www.mapquestapi.com/geocoding/status_codes.html for more details
56
- invalid_requests = [400, 403, 500]
57
- if invalid_requests.include? status[:code]
58
- if status[:code] === 500
59
- raise InvalidRequest
60
- end
61
- @valid = false
62
- else
63
- @valid = true
64
- end
44
+ def initialize(response_string, params = {})
45
+ super
65
46
  end
66
47
 
67
48
  def locations
68
- if valid then response[:results].first[:locations] else status end
49
+ if valid
50
+ response[:results].first[:locations]
51
+ end
69
52
  end
70
53
 
71
54
  def providedLocation
72
- if valid then response[:results].first[:providedLocation] else status end
73
- end
74
-
75
- def options
76
- if valid then response[:options] else status end
55
+ if valid
56
+ response[:results].first[:providedLocation]
57
+ end
77
58
  end
78
59
 
79
60
  end
@@ -1,3 +1,3 @@
1
1
  class MapQuest
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
3
3
  end
@@ -21,7 +21,8 @@ Gem::Specification.new do |spec|
21
21
  spec.add_dependency "json"
22
22
  spec.add_dependency "rest-client"
23
23
 
24
- spec.add_development_dependency "rspec", "~> 2.8.0"
25
- spec.add_development_dependency "bundler", "~> 1.3"
24
+ spec.add_development_dependency "rspec", "~> 2.8"
25
+ spec.add_development_dependency "bundler", "~> 1.0"
26
+ spec.add_development_dependency "webmock", "~> 1.11"
26
27
  spec.add_development_dependency "rake"
27
28
  end
@@ -0,0 +1,92 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe MapQuest::Services::Directions do
4
+
5
+ let(:mapquest) { MapQuest.new 'xxx' }
6
+
7
+ describe '#route' do
8
+ it 'should be an instance of Directions' do
9
+ mapquest.directions.should be_an_instance_of MapQuest::Services::Directions
10
+ end
11
+ end
12
+
13
+ describe '#route' do
14
+
15
+ context 'to or from are not provided' do
16
+ it 'should raise an error if location is not provided' do
17
+ expect { mapquest.directions.route 'xxx' }.to raise_error ArgumentError
18
+ end
19
+ end
20
+
21
+ context 'to and from are provided' do
22
+ subject(:directions) { mapquest.directions.route 'Lancaster,PA', 'York,PA' }
23
+
24
+ it 'should receive to and from' do
25
+ fixture = fixture 'directions/route_only'
26
+ query = {
27
+ :key => 'xxx',
28
+ :from => 'Lancaster,PA',
29
+ :to => 'York,PA'
30
+ }
31
+ stub_request(:get, 'www.mapquestapi.com/directions/v1/route').with(:query => query).to_return(:body => fixture)
32
+ end
33
+ end
34
+
35
+ context 'when request is valid' do
36
+
37
+ describe MapQuest::Services::Directions::Response do
38
+
39
+ let(:max_results) { -1 }
40
+ let(:fixt) { 'directions/route_only' }
41
+ let(:thumb_maps) { true }
42
+
43
+ let(:valid_response) do
44
+ query = {
45
+ :key => 'xxx',
46
+ :from => 'Lancaster,PA',
47
+ :to => 'York,PA'
48
+ }
49
+ MapQuest::Services::Directions::Response.new fixture(fixt), query
50
+ end
51
+
52
+ it { valid_response.status[:code].should == 0 }
53
+ it { valid_response.status[:messages].should == [] }
54
+ it { valid_response.valid.should == true }
55
+ it { valid_response.locations.should be_kind_of(Array) }
56
+ it { valid_response.maneuvers.should be_kind_of(Array) }
57
+ it { valid_response.distance.should be_kind_of(Integer) }
58
+ it { valid_response.time.should be_kind_of(Integer) }
59
+ it { valid_response.route.should be_kind_of(Hash) }
60
+
61
+ end
62
+ end
63
+
64
+ context 'when invalid request' do
65
+
66
+ context 'when api key is invalid' do
67
+ let(:wrong_api_key_response) do
68
+ MapQuest::Services::Directions::Response.new fixture 'directions/invalid_key'
69
+ end
70
+
71
+ describe MapQuest::Services::Geocoding::Response do
72
+ it { wrong_api_key_response.status[:code].should == 403 }
73
+ it { wrong_api_key_response.status[:messages].first.should match /^This is not a valid key/ }
74
+ end
75
+ end
76
+
77
+ context 'when argument is invalid' do
78
+
79
+ let(:invalid_argument) do
80
+ MapQuest::Services::Geocoding::Response.new fixture 'directions/invalid_value'
81
+ end
82
+
83
+ describe MapQuest::Services::Geocoding::Response do
84
+ it { invalid_argument.status[:code].should == 400 }
85
+ it { invalid_argument.status[:messages].first.should match /^Error processing route/ }
86
+ end
87
+
88
+ end
89
+ end
90
+
91
+ end
92
+ end