routing 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/.gitignore +22 -0
- data/Gemfile +8 -0
- data/Guardfile +5 -0
- data/LICENSE +22 -0
- data/README.md +54 -0
- data/Rakefile +10 -0
- data/lib/routing.rb +77 -0
- data/lib/routing/adapter.rb +22 -0
- data/lib/routing/adapter/navteq.rb +83 -0
- data/lib/routing/adapter/test.rb +24 -0
- data/lib/routing/geo_point.rb +34 -0
- data/lib/routing/middleware.rb +29 -0
- data/lib/routing/parser.rb +26 -0
- data/lib/routing/parser/navteq_simple.rb +112 -0
- data/lib/routing/version.rb +3 -0
- data/routing.gemspec +24 -0
- data/spec/fixtures/navteq/error_response.json +1 -0
- data/spec/fixtures/navteq/response.json +357 -0
- data/spec/routing/adapter/navteq_spec.rb +59 -0
- data/spec/routing/adapter/test_spec.rb +29 -0
- data/spec/routing/geo_point_spec.rb +40 -0
- data/spec/routing/parser/navteq_simple_spec.rb +81 -0
- data/spec/routing_spec.rb +82 -0
- data/spec/spec_helper.rb +23 -0
- metadata +113 -0
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Routing::Adapter::Test do
|
4
|
+
|
5
|
+
context 'creating a new instance' do
|
6
|
+
|
7
|
+
it 'can be instantiated without arguments' do
|
8
|
+
expect { Routing::Adapter::Test.new }.to_not raise_error
|
9
|
+
end
|
10
|
+
|
11
|
+
end
|
12
|
+
|
13
|
+
describe '#calculate' do
|
14
|
+
|
15
|
+
let(:geo_points) { [stub(:lat => 1, :lng => 2), stub(:lat => 3, :lng => 4), stub(:lat => 5, :lng => 6)] }
|
16
|
+
|
17
|
+
it 'returns an array of geopoints with values that are passed to the method' do
|
18
|
+
subject.calculate(geo_points).each_with_index do |new_geo_point, index|
|
19
|
+
new_geo_point.lat.should eql(geo_points[index].lat)
|
20
|
+
new_geo_point.lng.should eql(geo_points[index].lng)
|
21
|
+
new_geo_point.original_lng.should eql(geo_points[index].lng)
|
22
|
+
new_geo_point.original_lng.should eql(geo_points[index].lng)
|
23
|
+
new_geo_point.should be_waypoint
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Routing::GeoPoint do
|
4
|
+
|
5
|
+
context 'creating a new instance' do
|
6
|
+
it 'can be instantiated without arguments' do
|
7
|
+
expect { described_class.new }.to_not raise_error
|
8
|
+
end
|
9
|
+
|
10
|
+
context 'initialized with attributes' do
|
11
|
+
subject { described_class.new(:lat => 1, :lng => 2) }
|
12
|
+
|
13
|
+
its(:lat) { should be(1) }
|
14
|
+
its(:lng) { should be(2) }
|
15
|
+
|
16
|
+
it 'ignores passed attributes that dont exist' do
|
17
|
+
expect { described_class.new(:hello => :world) }.to_not raise_error
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
[:lat, :lng, :original_lat, :original_lng, :relative_time, :distance, :waypoint].each do |attribute|
|
23
|
+
it { should respond_to attribute }
|
24
|
+
end
|
25
|
+
|
26
|
+
describe '#waypoint?' do
|
27
|
+
it { should_not be_waypoint }
|
28
|
+
|
29
|
+
context 'when a truthy waypoint value is set' do
|
30
|
+
before { subject.waypoint = true }
|
31
|
+
it { should be_waypoint }
|
32
|
+
end
|
33
|
+
|
34
|
+
context 'when a falsy waypoint value is set' do
|
35
|
+
before { subject.waypoint = false }
|
36
|
+
it { should_not be_waypoint }
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'json'
|
3
|
+
|
4
|
+
describe Routing::Parser::NavteqSimple do
|
5
|
+
|
6
|
+
context 'with a error response' do
|
7
|
+
let(:error_response) { fixture('navteq/error_response.json') }
|
8
|
+
|
9
|
+
it 'should throw an RoutingFailed error' do
|
10
|
+
lambda{ described_class.new(error_response) }.should raise_error(Routing::Parser::RoutingFailed)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
context 'with a successful routing response' do
|
15
|
+
let(:response) { fixture('navteq/response.json') }
|
16
|
+
let(:json_response) { JSON.parse(response) }
|
17
|
+
let(:original_geo_points) do
|
18
|
+
json_response['Response']['Route'].first['Waypoint'].collect do |waypoint|
|
19
|
+
mock({
|
20
|
+
lat: waypoint['OriginalPosition']['Latitude'],
|
21
|
+
lng: waypoint['OriginalPosition']['Longitude']
|
22
|
+
})
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
describe '#to_geo_points' do
|
27
|
+
subject { described_class.new(response).to_geo_points }
|
28
|
+
|
29
|
+
it 'returns geopoints' do
|
30
|
+
subject.each { |point| point.should be_a(::Routing::GeoPoint) }
|
31
|
+
end
|
32
|
+
|
33
|
+
describe 'number of geo points' do
|
34
|
+
let(:leg_size) { json_response["Response"]["Route"].first["Leg"].size }
|
35
|
+
let(:leg_touching_point_size) { leg_size - 1 }
|
36
|
+
let(:maneuver_size) { json_response["Response"]["Route"].first["Leg"].inject(0) { |sum, leg| sum + leg["Maneuver"].size } }
|
37
|
+
|
38
|
+
it 'has the length of all maneuvers minus the duplicate ones at the touching points' do
|
39
|
+
should have(maneuver_size - leg_touching_point_size).geo_points
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
describe 'coordinates' do
|
44
|
+
it 'sets the calculated latitude and longitude for each geo point' do
|
45
|
+
subject.each do |geo_point|
|
46
|
+
geo_point.lat.should be
|
47
|
+
geo_point.lng.should be
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
describe 'original waypoints' do
|
53
|
+
subject { described_class.new(response).to_geo_points.select(&:waypoint?) }
|
54
|
+
|
55
|
+
it 'includes the same number of waypoints as passed in' do
|
56
|
+
should have(original_geo_points.size).geo_points
|
57
|
+
end
|
58
|
+
|
59
|
+
it 'sets original_lat and original_lng on the waypoints' do
|
60
|
+
subject.each_with_index do |geo_point, index|
|
61
|
+
geo_point.original_lat.should eq(original_geo_points[index].lat)
|
62
|
+
geo_point.original_lng.should eq(original_geo_points[index].lng)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
context 'when response does not contain the original waypoints' do
|
67
|
+
let(:response) do
|
68
|
+
corrupted_response = JSON.parse(fixture('navteq/response.json'))
|
69
|
+
corrupted_response['Response']['Route'].first['Waypoint'].first['MappedPosition']['Latitude'] += 0.1
|
70
|
+
corrupted_response['Response']['Route'].first['Waypoint'].first['MappedPosition']['Longitude'] += 0.1
|
71
|
+
JSON.dump(corrupted_response)
|
72
|
+
end
|
73
|
+
|
74
|
+
it 'raises an exception if no matching original position was found' do
|
75
|
+
expect { subject }.to raise_error(Routing::Parser::NoMatchingMappedPositionFound)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Routing do
|
4
|
+
|
5
|
+
context 'creating a new instance' do
|
6
|
+
|
7
|
+
let(:adapter) { mock }
|
8
|
+
|
9
|
+
it 'can be called without arguments' do
|
10
|
+
expect { Routing.new }.to_not raise_error
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'uses the default adapter, if no adapter is passed' do
|
14
|
+
described_class.default_adapter.should_receive(:calculate)
|
15
|
+
subject.calculate(stub, stub)
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'takes the passed adapter, if given' do
|
19
|
+
adapter.should_receive(:calculate)
|
20
|
+
described_class.new(adapter).calculate(stub, stub)
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'takes a configuration block' do
|
24
|
+
expect { described_class.new { throw :called } }.to throw_symbol(:called)
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'passes itself to the configuration block' do
|
28
|
+
described_class.new { |r| r.should be_instance_of(described_class) }
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
|
33
|
+
describe '#calculate' do
|
34
|
+
let(:geo_points) { [stub(:lat => 1, :lng => 2), stub(:lat => 3, :lng => 4), stub(:lat => 5, :lng => 6)] }
|
35
|
+
let(:adapter) { mock(:calculate => geo_points) }
|
36
|
+
|
37
|
+
subject { described_class.new(adapter) }
|
38
|
+
|
39
|
+
it 'should call the adapter' do
|
40
|
+
adapter.should_receive(:calculate).with(geo_points)
|
41
|
+
subject.calculate(geo_points)
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'should call each middleware in the given order' do
|
45
|
+
first_middleware = double(Routing::Middleware)
|
46
|
+
first_middleware.should_receive(:calculate).
|
47
|
+
with(geo_points).and_yield(geo_points)
|
48
|
+
|
49
|
+
second_middleware = double(Routing::Middleware)
|
50
|
+
second_middleware.should_receive(:calculate).
|
51
|
+
with(geo_points)
|
52
|
+
|
53
|
+
subject.stub(:middlewares).and_return([first_middleware, second_middleware])
|
54
|
+
|
55
|
+
subject.calculate(geo_points)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
context 'using the middleware' do
|
60
|
+
|
61
|
+
it 'has an empty array of middlewares by default' do
|
62
|
+
subject.middlewares.should be_an(Array)
|
63
|
+
subject.should have(0).middlewares
|
64
|
+
end
|
65
|
+
|
66
|
+
describe '#use' do
|
67
|
+
it 'appends the new middleware to the stack' do
|
68
|
+
subject.use(:hello)
|
69
|
+
subject.use(:world)
|
70
|
+
subject.middlewares.should == [:hello, :world]
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
describe '#middlewares' do
|
75
|
+
it 'replaces all middlewares' do
|
76
|
+
subject.use(:original)
|
77
|
+
subject.middlewares = :first, :second
|
78
|
+
subject.middlewares.should == [:first, :second]
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'bundler'
|
3
|
+
|
4
|
+
Bundler.require(:default, :test)
|
5
|
+
|
6
|
+
module RoutingFixtures
|
7
|
+
def fixture(name)
|
8
|
+
path = File.expand_path("../fixtures/#{name}", __FILE__)
|
9
|
+
File.open(path).read
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
RSpec.configure do |config|
|
14
|
+
config.include RoutingFixtures
|
15
|
+
end
|
16
|
+
|
17
|
+
if File.exist?('.navteq_host')
|
18
|
+
class Routing::Adapter::Navteq
|
19
|
+
def host
|
20
|
+
File.read('.navteq_host')
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
metadata
ADDED
@@ -0,0 +1,113 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: routing
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.2
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Christian Bäuerlein
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-05-11 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: faraday
|
16
|
+
requirement: &70233528536000 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: 0.7.0
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *70233528536000
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: json
|
27
|
+
requirement: &70233528535500 !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ! '>='
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '0'
|
33
|
+
type: :runtime
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: *70233528535500
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: rspec
|
38
|
+
requirement: &70233528534920 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ! '>='
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: 2.9.0
|
44
|
+
type: :development
|
45
|
+
prerelease: false
|
46
|
+
version_requirements: *70233528534920
|
47
|
+
description: ! "\n Provides a generic interface for routing services that can by
|
48
|
+
used to calculate directions between geolocations.\n Makes parsing and use-case
|
49
|
+
specific data handling easy trough an extendable middleware stack.\n "
|
50
|
+
email:
|
51
|
+
- christian@ffwdme.com
|
52
|
+
executables: []
|
53
|
+
extensions: []
|
54
|
+
extra_rdoc_files: []
|
55
|
+
files:
|
56
|
+
- .gitignore
|
57
|
+
- Gemfile
|
58
|
+
- Guardfile
|
59
|
+
- LICENSE
|
60
|
+
- README.md
|
61
|
+
- Rakefile
|
62
|
+
- lib/routing.rb
|
63
|
+
- lib/routing/adapter.rb
|
64
|
+
- lib/routing/adapter/navteq.rb
|
65
|
+
- lib/routing/adapter/test.rb
|
66
|
+
- lib/routing/geo_point.rb
|
67
|
+
- lib/routing/middleware.rb
|
68
|
+
- lib/routing/parser.rb
|
69
|
+
- lib/routing/parser/navteq_simple.rb
|
70
|
+
- lib/routing/version.rb
|
71
|
+
- routing.gemspec
|
72
|
+
- spec/fixtures/navteq/error_response.json
|
73
|
+
- spec/fixtures/navteq/response.json
|
74
|
+
- spec/routing/adapter/navteq_spec.rb
|
75
|
+
- spec/routing/adapter/test_spec.rb
|
76
|
+
- spec/routing/geo_point_spec.rb
|
77
|
+
- spec/routing/parser/navteq_simple_spec.rb
|
78
|
+
- spec/routing_spec.rb
|
79
|
+
- spec/spec_helper.rb
|
80
|
+
homepage: https://github.com/flinc/routing
|
81
|
+
licenses: []
|
82
|
+
post_install_message:
|
83
|
+
rdoc_options: []
|
84
|
+
require_paths:
|
85
|
+
- lib
|
86
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
87
|
+
none: false
|
88
|
+
requirements:
|
89
|
+
- - ! '>='
|
90
|
+
- !ruby/object:Gem::Version
|
91
|
+
version: '0'
|
92
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
93
|
+
none: false
|
94
|
+
requirements:
|
95
|
+
- - ! '>='
|
96
|
+
- !ruby/object:Gem::Version
|
97
|
+
version: '0'
|
98
|
+
requirements: []
|
99
|
+
rubyforge_project:
|
100
|
+
rubygems_version: 1.8.17
|
101
|
+
signing_key:
|
102
|
+
specification_version: 3
|
103
|
+
summary: A ruby interface for route calculation services
|
104
|
+
test_files:
|
105
|
+
- spec/fixtures/navteq/error_response.json
|
106
|
+
- spec/fixtures/navteq/response.json
|
107
|
+
- spec/routing/adapter/navteq_spec.rb
|
108
|
+
- spec/routing/adapter/test_spec.rb
|
109
|
+
- spec/routing/geo_point_spec.rb
|
110
|
+
- spec/routing/parser/navteq_simple_spec.rb
|
111
|
+
- spec/routing_spec.rb
|
112
|
+
- spec/spec_helper.rb
|
113
|
+
has_rdoc:
|