reittiopas2 0.0.1
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.
- checksums.yaml +7 -0
- data/.gitignore +20 -0
- data/.rspec +2 -0
- data/Gemfile +3 -0
- data/Guardfile +7 -0
- data/LICENSE +22 -0
- data/README.md +32 -0
- data/Rakefile +6 -0
- data/lib/reittiopas2/connection.rb +84 -0
- data/lib/reittiopas2/geocoding.rb +123 -0
- data/lib/reittiopas2/routing.rb +145 -0
- data/lib/reittiopas2/version.rb +3 -0
- data/lib/reittiopas2.rb +19 -0
- data/reittiopas2.gemspec +25 -0
- data/spec/connection_spec.rb +84 -0
- data/spec/data/geocode.json +2 -0
- data/spec/data/reverse_geocode.json +2 -0
- data/spec/geocoding_spec.rb +136 -0
- data/spec/routing_spec.rb +83 -0
- data/spec/spec_helper.rb +15 -0
- metadata +153 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: dd7af7e068a579e9245cfb7ca79121e9a4310fdd
|
4
|
+
data.tar.gz: 5445ce3e8a5846c31ac8ccad61c557eb3375594c
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 9377560e0fa31558ccc6f733a4c0de539b47d86686d7adb62240c833bf49a67a5959270518c2d1bbae3495a13a2d3a225acb7b9b60c78d16b052c0bd7da91a5b
|
7
|
+
data.tar.gz: 7fc721b52e394ae44299c1e32a9fab26a157dfe139fd97f421adac22be4d68378494288748f2281becf3733627593a35626f76f7fed7ddd6787b276303cd244d
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/Gemfile
ADDED
data/Guardfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2012 Iivari Äikäs, Jussi Virtanen
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
# Reittiopas2
|
2
|
+
|
3
|
+
Barebones gem wrapping
|
4
|
+
[reittiopas v2 API](http://developer.reittiopas.fi/pages/fi/reittiopas-api.php),
|
5
|
+
providing simple route searching and geocoding.
|
6
|
+
|
7
|
+
|
8
|
+
## Installation
|
9
|
+
|
10
|
+
Add this line to your application's Gemfile:
|
11
|
+
|
12
|
+
gem 'reittiopas2'
|
13
|
+
|
14
|
+
And then execute:
|
15
|
+
|
16
|
+
$ bundle
|
17
|
+
|
18
|
+
Or install it yourself as:
|
19
|
+
|
20
|
+
$ gem install reittiopas2
|
21
|
+
|
22
|
+
## Usage
|
23
|
+
|
24
|
+
Sadly, you have to dive into docstrings for documentation.
|
25
|
+
|
26
|
+
## Contributing
|
27
|
+
|
28
|
+
1. Fork it
|
29
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
30
|
+
3. Commit your changes (`git commit -am 'Added some feature'`)
|
31
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
32
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1,84 @@
|
|
1
|
+
class Reittiopas2
|
2
|
+
|
3
|
+
# Handles connectting to Reittiopas API and transforms query hashes into form
|
4
|
+
# that Reittiopas API can digest them. This class is also responsible for
|
5
|
+
# parsing response into Ruby readable form.
|
6
|
+
#
|
7
|
+
# @api private
|
8
|
+
class Connection
|
9
|
+
|
10
|
+
def initialize(username, password)
|
11
|
+
@base_url = "http://api.reittiopas.fi/hsl/prod/"
|
12
|
+
@base_query = {"user" => username, "pass" => password}
|
13
|
+
end
|
14
|
+
|
15
|
+
|
16
|
+
# Forms proper query from credentials + given query and sends it to API
|
17
|
+
# endpoint. Also parses response into Ruby readable form.
|
18
|
+
#
|
19
|
+
# In case of errors, be those from API endpoint or from internal processes,
|
20
|
+
# return value will be hash with one field 'error' which contains error
|
21
|
+
# message.
|
22
|
+
#
|
23
|
+
# In fatal error situations Exception will be thrown, only exception for this
|
24
|
+
# rule is JSON::ParserException which is caught and returned as value of
|
25
|
+
# 'error' field.
|
26
|
+
#
|
27
|
+
# @param [Hash] query the query which is to be sent to API endpoint
|
28
|
+
# @return [Hash] the whatever data was requested from API, or Hash containing
|
29
|
+
# key 'error' containing error message.
|
30
|
+
def perform_query(query={})
|
31
|
+
query = fix_arrays(query)
|
32
|
+
uri = Addressable::URI.parse(@base_url)
|
33
|
+
uri.query_values = @base_query.merge(query)
|
34
|
+
|
35
|
+
res = Net::HTTP.get_response(uri)
|
36
|
+
|
37
|
+
if res.code == '500'
|
38
|
+
# In case of errors, code 500 is returned and there is explanation in
|
39
|
+
# response body as HTML.
|
40
|
+
{'error' => res.body}
|
41
|
+
elsif res.body.nil? or res.body.empty?
|
42
|
+
{'error' => "Response body was empty!"}
|
43
|
+
else
|
44
|
+
JSON.load res.body.to_s
|
45
|
+
end
|
46
|
+
rescue JSON::ParserError => ex
|
47
|
+
{'error' => ex.class}
|
48
|
+
end
|
49
|
+
|
50
|
+
|
51
|
+
private
|
52
|
+
|
53
|
+
|
54
|
+
# Reittiopas API wants arrays as values seperated with pipes. This method
|
55
|
+
# checks query for arrays and converts them to API friendly versions.
|
56
|
+
#
|
57
|
+
# @param [Hash] query the query to be checked for arrays to convert.
|
58
|
+
# @return [Hash] hash where arrays are converted to pipe presentation.
|
59
|
+
def fix_arrays(query)
|
60
|
+
retval = {}
|
61
|
+
query.each do |key, val|
|
62
|
+
if val.is_a? Array
|
63
|
+
retval[key] = array_to_query_form(val)
|
64
|
+
else
|
65
|
+
retval[key] = val
|
66
|
+
end
|
67
|
+
end
|
68
|
+
retval
|
69
|
+
end
|
70
|
+
|
71
|
+
|
72
|
+
def array_to_query_form(arr)
|
73
|
+
raise(ArgumentError, "arr is not Array") unless arr.is_a? Array
|
74
|
+
|
75
|
+
retval = ""
|
76
|
+
arr.each do |val|
|
77
|
+
retval << val << "|"
|
78
|
+
end
|
79
|
+
|
80
|
+
retval[0..-2] # Remove last pipe
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
end
|
@@ -0,0 +1,123 @@
|
|
1
|
+
class Reittiopas2
|
2
|
+
|
3
|
+
# Module containing public API to perform geocoding and reverse geocoding
|
4
|
+
# operations.
|
5
|
+
#
|
6
|
+
# Location info returned from geocode methods is following form:
|
7
|
+
# @example geocode location info
|
8
|
+
# [
|
9
|
+
# {
|
10
|
+
# 'locType' => 'stop',
|
11
|
+
# 'locTypeId' => '10',
|
12
|
+
# 'name' => 'Elielinaukio',
|
13
|
+
# 'matchedName' => 'Elielinaukio',
|
14
|
+
# 'lang' => 'fi',
|
15
|
+
# 'city' => 'Helsinki',
|
16
|
+
# 'coords' => '2552335,6673660',
|
17
|
+
# 'details' => {
|
18
|
+
# 'address' => 'Elielinaukio',
|
19
|
+
# 'code' => '1020128',
|
20
|
+
# 'shortCode' => '2020',
|
21
|
+
# 'lines' => [
|
22
|
+
# '1015A 1:Länsiterminaali',
|
23
|
+
# '1015A 2:Elielinaukio'
|
24
|
+
# ]
|
25
|
+
# }
|
26
|
+
# }
|
27
|
+
# ]
|
28
|
+
#
|
29
|
+
#
|
30
|
+
# @example reverse_geocode location info
|
31
|
+
# [
|
32
|
+
# {
|
33
|
+
# 'locType' => 'address',
|
34
|
+
# 'locTypeId' => '900',
|
35
|
+
# 'name' => 'Purotie 8, Helsinki',
|
36
|
+
# 'matchedName' => nil,
|
37
|
+
# 'lang' => 'fi',
|
38
|
+
# 'city' => 'Helsinki',
|
39
|
+
# 'coords' => '2552335,6673660',
|
40
|
+
# 'distance' => '38.4187454245971',
|
41
|
+
# 'details' => {
|
42
|
+
# 'address' => nil,
|
43
|
+
# 'houseNumber' => '8',
|
44
|
+
# }
|
45
|
+
# }
|
46
|
+
# ]
|
47
|
+
#
|
48
|
+
module Geocoding
|
49
|
+
|
50
|
+
# Search for information about place.
|
51
|
+
#
|
52
|
+
# @param [String] place_name the name of place to be searched. This can be
|
53
|
+
# street name, point of interest, bus stop, etc.
|
54
|
+
# @param [Hash] opts the optional parameters which can be used to alter search
|
55
|
+
# results. Any invalid keys are removed from query parameters, but values
|
56
|
+
# are never checked.
|
57
|
+
#
|
58
|
+
# @option opts [String] 'cities' ('all') List of cities which are accepted.
|
59
|
+
# @option opts [String] 'loc_types' ('all') List of location types which are
|
60
|
+
# accepted.
|
61
|
+
# @option opts [Integer] 'disable_error_correction' (0) Disable levenshtein
|
62
|
+
# error correction. 1 = Error correction NOT in use, 0 = error correction in
|
63
|
+
# use.
|
64
|
+
# @option opts [Integer] 'disable_unique_stop_names' (1) Disable unique stop
|
65
|
+
# names in the result. 1 = all stops are shown in the result, 0 = only one
|
66
|
+
# stop is included in the result for stops with same name.
|
67
|
+
#
|
68
|
+
# @return [Array<Hash>] array containing location hashes matched given query.
|
69
|
+
# @see #reverse_geocode
|
70
|
+
def geocode(place_name, opts={})
|
71
|
+
clean = geocode_remove_invalid_keys(opts)
|
72
|
+
query = {'request' =>'geocode', 'key' => place_name}.merge(clean)
|
73
|
+
@connection.perform_query(query)
|
74
|
+
end
|
75
|
+
|
76
|
+
|
77
|
+
# Do reverse geocode search to find information about given coordinates.
|
78
|
+
#
|
79
|
+
# @param [String] coords the coordinate pair "<x_coordinate>,<y_coordinate>"
|
80
|
+
# @param [Hash] opts the optional parameters which can be used to alter query
|
81
|
+
# results. Any invalid keys are removed from query parameters, but values
|
82
|
+
# are never checked.
|
83
|
+
#
|
84
|
+
# @option opts [Integer] 'limit' (1) Limit for the number of locations
|
85
|
+
# returned.
|
86
|
+
# @option opts [Integer] 'radius' (1000) Radius of the search in meters. Range
|
87
|
+
# 1-1000.
|
88
|
+
# @option opts [String] 'result_contains' ('address') Limit the search to
|
89
|
+
# given location types. Possible values are: address, stop, poi
|
90
|
+
#
|
91
|
+
# @return [Array<Hash>] array containing location hashes matching given
|
92
|
+
# coordinates.
|
93
|
+
# @see #geocode
|
94
|
+
def reverse_geocode(coords, opts={})
|
95
|
+
clean = reverse_geocode_remove_invalid_keys(opts)
|
96
|
+
query = {'request' => 'reverse_geocode', 'coordinate' => coords}.merge(clean)
|
97
|
+
@connection.perform_query(query)
|
98
|
+
end
|
99
|
+
|
100
|
+
|
101
|
+
private
|
102
|
+
|
103
|
+
|
104
|
+
def geocode_remove_invalid_keys(query)
|
105
|
+
whitelist = [ 'key', 'cities', 'loc_types', 'disable_error_correction',
|
106
|
+
'disable_unique_stop_names' ]
|
107
|
+
|
108
|
+
query.select do |key, val|
|
109
|
+
whitelist.include? key
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
def reverse_geocode_remove_invalid_keys(query)
|
114
|
+
whitelist = [ 'coordinate', 'limit', 'radius', 'result_contains' ]
|
115
|
+
|
116
|
+
query.select do |key, val|
|
117
|
+
whitelist.include? key
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
|
123
|
+
end
|
@@ -0,0 +1,145 @@
|
|
1
|
+
|
2
|
+
class Reittiopas2
|
3
|
+
|
4
|
+
# Routing module contains all needed functionality to query route information.
|
5
|
+
module Routing
|
6
|
+
|
7
|
+
# Query the route between two coordinate points. In routing it is recommended
|
8
|
+
# to use street addresses (their coordinates) as it is difficult for the end
|
9
|
+
# user to know where exactly a stop is located. There might be several stops
|
10
|
+
# with the same name that are located far away from each other (for example
|
11
|
+
# the stop 'Sturenkatu' in Helsinki).
|
12
|
+
#
|
13
|
+
# @param [String, Hash] from Coordinates where route begins.
|
14
|
+
# @param [String, Hash] to Coordinates where route ends.
|
15
|
+
# @param [Hash] opts Optional parameters to query.
|
16
|
+
# @return [Hash] the route between given points.
|
17
|
+
#
|
18
|
+
# @option opts [String] via
|
19
|
+
# @option opts [Number] date (Current date) YYYYMMDD
|
20
|
+
# @option opts [Number] time (Current time) HHMM
|
21
|
+
# @option opts [String] timetype ('departure') Time of the request is either
|
22
|
+
# * 'departure'
|
23
|
+
# * 'arrival'
|
24
|
+
# @option opts [Number] via_time Minimum time spent at a via_point in
|
25
|
+
# minutes.
|
26
|
+
# @option opts [String] zone (No restriction) Ticket zone, possible values
|
27
|
+
# are:
|
28
|
+
# * 'helsinki',
|
29
|
+
# * 'espoo',
|
30
|
+
# * 'vantaa',
|
31
|
+
# * 'whole' (Helsinki, Espoo, Kauniainen, Vantaa, Kirkkonummi and Kerava.
|
32
|
+
# Whole region, excluding non HSL areas),
|
33
|
+
# * 'region' (Helsinki, Espoo, Kauniainen and Vantaa region)
|
34
|
+
# @option opts [String, Array<String>] transport_types ('all') Transport
|
35
|
+
# types included in the request. Possible types are:
|
36
|
+
# * 'all',
|
37
|
+
# * 'bus',
|
38
|
+
# * 'train',
|
39
|
+
# * 'metro',
|
40
|
+
# * 'tram',
|
41
|
+
# * 'service',
|
42
|
+
# * 'U-line',
|
43
|
+
# * 'ferry',
|
44
|
+
# * 'walk' (ONLY walking)
|
45
|
+
# @option opts [String] optimize ('default') Routing profile. Possible
|
46
|
+
# values:
|
47
|
+
# * 'default' = (wait cost=1.0, walk cost=1.2, change cost=6),
|
48
|
+
# * 'fastest' = (wait cost=1.0, walk cost=1.0, change cost=0),
|
49
|
+
# * 'least_transfers' = (wait cost=1.0, walk cost=1.5, change cost=20),
|
50
|
+
# * 'least_walking' = (wait cost=1.0, walk cost=5.0, change cost=6)
|
51
|
+
# @option opts [Number] change_margin (3) The minimum number of minutes
|
52
|
+
# between changes. Range 0-10.
|
53
|
+
# @option opts [Number] change_cost Penalty for a change, user is rather
|
54
|
+
# N minutes later at the destination than changes to another vehicle. Range
|
55
|
+
# 1-99. This parameter overrides the setting from optimize.
|
56
|
+
# @option opts [Number] wait_cost With this parameter you can weigh wait
|
57
|
+
# time cost when calculating fastest route. Range 0.1 – 10.0. This
|
58
|
+
# parameter overrides optimize parameter.
|
59
|
+
# @option opts [Number] walk_speed (70) Walking speed. m/min, range 1-500.
|
60
|
+
# @option opts [String] detail ('normal') Detail level of the response.
|
61
|
+
# Possible values:
|
62
|
+
# * 'limited' = only legs are returned,
|
63
|
+
# * 'normal' = intermiediate stops are returned,
|
64
|
+
# * 'full' = route share coordinates are returned
|
65
|
+
# @option opts [Number] show (3) Number of routes in the response.
|
66
|
+
# @option opts [Number] mode_cost_|transport_type_id| Mode costs for different
|
67
|
+
# transport types. These settings override previous values set with
|
68
|
+
# transport_types-parameter. Values may range from 0.1 to 10 or it can be -1
|
69
|
+
# when the transport type is excluded from routing.
|
70
|
+
#
|
71
|
+
# transport_type_id in the parameter name may be any of the following:
|
72
|
+
# 1. Helsinki internal bus lines
|
73
|
+
# 2. trams
|
74
|
+
# 3. Espoo internal bus lines
|
75
|
+
# 4. Vantaa internal bus lines
|
76
|
+
# 5. regional bus lines
|
77
|
+
# 6. metro
|
78
|
+
# 7. ferry
|
79
|
+
# 8. U-lines
|
80
|
+
# 12. commuter trains
|
81
|
+
# 21. Helsinki service lines
|
82
|
+
# 22. Helsinki night buses
|
83
|
+
# 23. Espoo service lines
|
84
|
+
# 24. Vantaa service lines
|
85
|
+
# 25. region night buses
|
86
|
+
# 36. Kirkkonummi internal bus lines
|
87
|
+
# 39. Kerava internal bus lines
|
88
|
+
def route(from, to, opts={})
|
89
|
+
if from.class != to.class
|
90
|
+
return {'error' => 'ArgumentError: from.class != to.class'}
|
91
|
+
end
|
92
|
+
|
93
|
+
if from.is_a? String
|
94
|
+
query = route_query_from_strings(from, to)
|
95
|
+
elsif from.is_a? Hash and from['coordinate'] and to['coordinate']
|
96
|
+
query = route_query_from_locations(from, to)
|
97
|
+
else
|
98
|
+
return {'error' => 'ArgumentError: locations were not acceptable types'}
|
99
|
+
end
|
100
|
+
|
101
|
+
clean_opts = route_remove_invalid_keys(opts)
|
102
|
+
@connection.perform_query(clean_opts.merge(query))
|
103
|
+
end
|
104
|
+
|
105
|
+
|
106
|
+
private
|
107
|
+
|
108
|
+
|
109
|
+
def route_query_from_strings(from, to)
|
110
|
+
{
|
111
|
+
'request' => 'route',
|
112
|
+
'from' => from,
|
113
|
+
'to' => to
|
114
|
+
}
|
115
|
+
end
|
116
|
+
|
117
|
+
def route_query_from_locations(from, to)
|
118
|
+
{
|
119
|
+
'request' => 'route',
|
120
|
+
'from' => from['coordinate'],
|
121
|
+
'to' => to['coordinate']
|
122
|
+
}
|
123
|
+
end
|
124
|
+
|
125
|
+
def route_remove_invalid_keys(opts)
|
126
|
+
keys = ['via', 'date', 'time', 'timetype', 'via_time', 'zone',
|
127
|
+
'transport_types', 'optimize', 'change_margin', 'change_cost',
|
128
|
+
'wait_cost', 'walk_cost', 'walk_speed', 'detail', 'show']
|
129
|
+
mode_costs = ['mode_cost_1', 'mode_cost_2', 'mode_cost_3', 'mode_cost_4',
|
130
|
+
'mode_cost_5', 'mode_cost_6', 'mode_cost_7', 'mode_cost_7',
|
131
|
+
'mode_cost_8', 'mode_cost_12', 'mode_cost_21', 'mode_cost_22',
|
132
|
+
'mode_cost_23', 'mode_cost_24', 'mode_cost_25', 'mode_cost_36',
|
133
|
+
'mode_cost_39']
|
134
|
+
|
135
|
+
whitelist = []
|
136
|
+
whitelist.concat keys
|
137
|
+
whitelist.concat mode_costs
|
138
|
+
|
139
|
+
opts.select do |key, val|
|
140
|
+
whitelist.include? key
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
end
|
data/lib/reittiopas2.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
require "net/http"
|
2
|
+
require "addressable/uri"
|
3
|
+
require "json"
|
4
|
+
|
5
|
+
require "reittiopas2/version"
|
6
|
+
|
7
|
+
require "reittiopas2/connection"
|
8
|
+
require "reittiopas2/geocoding"
|
9
|
+
require "reittiopas2/routing"
|
10
|
+
|
11
|
+
class Reittiopas2
|
12
|
+
include Geocoding
|
13
|
+
include Routing
|
14
|
+
|
15
|
+
def initialize(username, password)
|
16
|
+
@connection = Reittiopas2::Connection.new(username, password)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
data/reittiopas2.gemspec
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path('../lib/reittiopas2/version', __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |gem|
|
5
|
+
gem.authors = ["Iivari Äikäs", "Jussi Virtanen"]
|
6
|
+
gem.email = ["iivari.aikas@gmail.com"]
|
7
|
+
gem.description = %q{Reittiopas version 2 API library.}
|
8
|
+
gem.summary = %q{Gem providing easy access to reittiopas version 2 API.}
|
9
|
+
gem.homepage = "https://github.com/orva/reittiopas2"
|
10
|
+
|
11
|
+
gem.files = `git ls-files`.split($\)
|
12
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
13
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
14
|
+
gem.name = "reittiopas2"
|
15
|
+
gem.require_paths = ["lib"]
|
16
|
+
gem.version = Reittiopas2::VERSION
|
17
|
+
|
18
|
+
gem.add_dependency "json", "~> 1.8"
|
19
|
+
gem.add_dependency "addressable", "~> 2.3"
|
20
|
+
|
21
|
+
gem.add_development_dependency "rspec", "~> 2.14"
|
22
|
+
gem.add_development_dependency "webmock", "~> 1.15"
|
23
|
+
gem.add_development_dependency "guard-rspec", "~> 4.0"
|
24
|
+
gem.add_development_dependency "simplecov", "~> 0.7"
|
25
|
+
end
|
@@ -0,0 +1,84 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Reittiopas2::Connection do
|
4
|
+
before :each do
|
5
|
+
@user = "username"
|
6
|
+
@pwd = "password"
|
7
|
+
@conn = Reittiopas2::Connection.new @user, @pwd
|
8
|
+
|
9
|
+
@base_url = "http://api.reittiopas.fi/hsl/prod/"
|
10
|
+
@query = {"user" => @user, "pass" => @pwd}
|
11
|
+
end
|
12
|
+
|
13
|
+
|
14
|
+
|
15
|
+
describe "query forming" do
|
16
|
+
it "should put pipes into arrays" do
|
17
|
+
q = @query.merge({ "array" => ["one", "two", "three"] })
|
18
|
+
expected_q = @query.merge({ "array" => "one|two|three"})
|
19
|
+
|
20
|
+
stub_request(:get, @base_url).
|
21
|
+
with(:query => expected_q)
|
22
|
+
|
23
|
+
@conn.perform_query(q)
|
24
|
+
a_request(:get, @base_url).with(:query => expected_q).should have_been_made
|
25
|
+
end
|
26
|
+
|
27
|
+
|
28
|
+
it "should form query only with credentials in case no query given." do
|
29
|
+
stub_request(:get, @base_url).
|
30
|
+
with(:query => @query)
|
31
|
+
|
32
|
+
@conn.perform_query
|
33
|
+
a_request(:get, @base_url).with(:query => @query).should have_been_made
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
|
38
|
+
describe "perform_query return value" do
|
39
|
+
it "should be hash filled with data in case of succesful query." do
|
40
|
+
body = '{"max":5000,"used":44}'
|
41
|
+
query = @query.merge({ "request" => "stats" })
|
42
|
+
|
43
|
+
stub_request(:get, @base_url).
|
44
|
+
with(:query => query).
|
45
|
+
to_return(:body => body)
|
46
|
+
|
47
|
+
ret = @conn.perform_query(query)
|
48
|
+
ret.should == {"max" => 5000, "used" => 44}
|
49
|
+
end
|
50
|
+
|
51
|
+
|
52
|
+
it "should have response body in error field in case of 500 code" do
|
53
|
+
body = "Hello! Error!"
|
54
|
+
|
55
|
+
stub_request(:get, @base_url).
|
56
|
+
with(:query => @query).
|
57
|
+
to_return(:status => 500, :body => body)
|
58
|
+
|
59
|
+
ret = @conn.perform_query
|
60
|
+
ret.should == {'error' => body}
|
61
|
+
end
|
62
|
+
|
63
|
+
|
64
|
+
it "should error field in case of JSON parse error" do
|
65
|
+
body = "well this is not valid JSON"
|
66
|
+
|
67
|
+
stub_request(:get, @base_url).
|
68
|
+
with(:query => @query).
|
69
|
+
to_return(:body => body)
|
70
|
+
|
71
|
+
ret = @conn.perform_query
|
72
|
+
ret['error'].should_not be_nil
|
73
|
+
end
|
74
|
+
|
75
|
+
it "should have error field in case of empty response body" do
|
76
|
+
stub_request(:get, @base_url).
|
77
|
+
with(:query => @query).
|
78
|
+
to_return(:body => '')
|
79
|
+
|
80
|
+
ret = @conn.perform_query
|
81
|
+
ret.should == {'error' => 'Response body was empty!'}
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
@@ -0,0 +1,2 @@
|
|
1
|
+
[{"locType":"stop","locTypeId":10,"name":"Elielinaukio","matchedName":"Elielinaukio","lang":"fi","city":"Helsinki","coords":"2552335,6673660","details":{"address":"Elielinaukio","code":"1020128","shortCode":"2020","changeCost":0.6,"lines":["1015A 1:L\u00e4nsiterminaali","1015A 2:Elielinaukio","1018N 1:Elielinaukio","1039N 1:Konala-Malminkartano","1040 2:Elielinaukio","1042 2:Elielinaukio","1043 2:Elielinaukio","1063 2:Elielinaukio","1069 2:Elielinaukio","1102N 1:Kannelm\u00e4ki"],"transport_type_id":1}},{"locType":"stop","locTypeId":10,"name":"Elielinaukio","matchedName":"Elielinaukio","lang":"fi","city":"Helsinki","coords":"2552355,6673705","details":{"address":"Laituri 21","code":"1020129","shortCode":"2021","changeCost":0.3,"lines":["1040 1:Pohjois-Haagan asema","1102N 1:Kannelm\u00e4ki"],"transport_type_id":1}},{"locType":"stop","locTypeId":10,"name":"Elielinaukio","matchedName":"Elielinaukio","lang":"fi","city":"Helsinki","coords":"2552310,6673680","details":{"address":"Elielinaukio","code":"1020130","shortCode":"","changeCost":0.6,"lines":["2210N 1:Espoon keskus-Eliel","2220N 1:Jupperi-Eliel"],"transport_type_id":1}},{"locType":"stop","locTypeId":10,"name":"Elielinaukio","matchedName":"Elielinaukio","lang":"fi","city":"Helsinki","coords":"2552355,6673712","details":{"address":"Laituri 22","code":"1020131","shortCode":"2022","changeCost":0.3,"lines":["1043 1:Hakuninmaa"],"transport_type_id":1}},{"locType":"stop","locTypeId":10,"name":"Elielinaukio","matchedName":"Elielinaukio","lang":"fi","city":"Helsinki","coords":"2552355,6673733","details":{"address":"Laituri 25","code":"1020132","shortCode":"2025","changeCost":0.6,"lines":["1042 1:Kannelm\u00e4ki"],"transport_type_id":1}},{"locType":"stop","locTypeId":10,"name":"Elielinaukio","matchedName":"Elielinaukio","lang":"fi","city":"Helsinki","coords":"2552355,6673719","details":{"address":"Laituri 23","code":"1020133","shortCode":"2023","changeCost":0.3,"lines":["1018N 1:Elielinaukio","1063 1:Palohein\u00e4"],"transport_type_id":1}},{"locType":"stop","locTypeId":10,"name":"Elielinaukio","matchedName":"Elielinaukio","lang":"fi","city":"Helsinki","coords":"2552355,6673726","details":{"address":"Laituri 24","code":"1020135","shortCode":"2024","changeCost":0.3,"lines":["1039N 1:Konala-Malminkartano","1069 1:Malmi"],"transport_type_id":1}},{"locType":"stop","locTypeId":10,"name":"Elielinaukio","matchedName":"Elielinaukio","lang":"fi","city":"Helsinki","coords":"2552335,6673662","details":{"address":"Elielinaukio","code":"1020228","shortCode":"2020","changeCost":0.6,"lines":["2194 2:Elielinaukio, l. 36","2194A 2:Elielinaukio, l. 36","2195 2:Elielinaukio, l. 36","2195N 2:Elielinaukio, l. 36","2206 2:Elielinaukio, l. 35","2206A 2:Elielinaukio, l. 35","2212 2:Elielinaukio, l. 35","2213 2:Elielinaukio, l. 35","2213N 2:Elielinaukio, l. 35","2231 2:Elielinaukio, l. 34","2231K 2:Elielinaukio, l. 34","2231N 2:Elielinaukio, l. 34","2247 2:Elielinaukio, l. 34","2247A 2:Elielinaukio, l. 34","2248 2:Elielinaukio, l. 34","2248A 2:Elielinaukio, l. 34","2270 2:Elielinaukio, l. 34","2270A 2:Elielinaukio, l. 34","2270N 2:Elielinaukio, l. 34","2315 2:Elielinaukio, l. 26","2321 2:Elielinaukio, l. 26","2324 2:Elielinaukio, l. 27","2324K 2:Elielinaukio, l. 27","2324N 2:Elielinaukio, l. 27","2345 2:Elielinaukio, l. 27","2345N 2:Elielinaukio, l. 27","4300N 2:Elielinaukio, l. 28","4360 2:Elielinaukio, l. 29","4360K 2:Elielinaukio, l. 29","4361 2:Elielinaukio, l. 29","4362 2:Elielinaukio, l. 29","4362N 2:Elielinaukio, l. 29","4362T 2:Elielinaukio, l. 29","4363 2:Elielinaukio, l. 28","4363A 2:Elielinaukio, l. 28","4364 2:Elielinaukio, l. 29","4415 2:Elielinaukio, l. 31","4451 2:Elielinaukio, l. 31","4452 2:Elielinaukio, l. 32","4452K 2:Elielinaukio, l. 32","4453 2:Elielinaukio, l. 33","4453Z 2:Elielinaukio, l. 33","4474 2:Elielinaukio,l.31","4474A 2:Elielinaukio,l.31","4474AK2:Elielinaukio,l.31","4474K 2:Elielinaukio,l.31","4474V 2:Elielinaukio,l.31","4474VK2:Elielinaukio,l.31"],"transport_type_id":1}},{"locType":"stop","locTypeId":10,"name":"Elielinaukio","matchedName":"Elielinaukio","lang":"fi","city":"Helsinki","coords":"2552355,6673740","details":{"address":"Laituri 26","code":"1020239","shortCode":"2026","changeCost":0.3,"lines":["2315 1:Vanhakartano","2321 1:Koskelo"],"transport_type_id":1}},{"locType":"stop","locTypeId":10,"name":"Elielinaukio","matchedName":"Elielinaukio","lang":"fi","city":"Helsinki","coords":"2552355,6673747","details":{"address":"Laituri 27","code":"1020241","shortCode":"2027","changeCost":0.3,"lines":["2324 1:Kalaj\u00e4rvi","2324K 1:Kalaj\u00e4rvi","2324N 1:Kalaj\u00e4rvi","2345 1:Rinnekoti","2345N 1:Rinnekoti"],"transport_type_id":1}},{"locType":"stop","locTypeId":10,"name":"Elielinaukio","matchedName":"Elielinaukio","lang":"fi","city":"Helsinki","coords":"2552355,6673754","details":{"address":"Laituri 28","code":"1020243","shortCode":"2028","changeCost":0.3,"lines":["4300N 1:H\u00e4meenkyl\u00e4","4363 1:H\u00e4meenkyl\u00e4","4363A 1:Askisto"],"transport_type_id":1}},{"locType":"stop","locTypeId":10,"name":"Elielinaukio","matchedName":"Elielinaukio","lang":"fi","city":"Helsinki","coords":"2552355,6673761","details":{"address":"Laituri 29","code":"1020245","shortCode":"2029","changeCost":0.3,"lines":["4360 1:Petikko","4360K 1:Petikko","4361 1:Petikko","4362 1:Petikko","4362N 1:Askisto","4362T 1:Petikko","4364 1:Askisto"],"transport_type_id":1}},{"locType":"stop","locTypeId":10,"name":"Elielinaukio","matchedName":"Elielinaukio","lang":"fi","city":"Helsinki","coords":"2552305,6673698","details":{"address":"Laituri 31","code":"1020249","shortCode":"2031","changeCost":0.3,"lines":["4415 1:Lentoasema, lait. 4","4451 1:Lentoasema, lait. 4","4474 1:Katriinan sairaala","4474A 1:Reuna","4474AK1:Reuna","4474K 1:Katriinan sairaala","4474V 1:Koivup\u00e4\u00e4","4474VK1:Koivup\u00e4\u00e4"],"transport_type_id":1}},{"locType":"stop","locTypeId":10,"name":"Elielinaukio","matchedName":"Elielinaukio","lang":"fi","city":"Helsinki","coords":"2552304,6673705","details":{"address":"Laituri 32","code":"1020251","shortCode":"2032","changeCost":0.3,"lines":["4400N 1:Pakkala","4452 1:Myyrm\u00e4en as, lait. 7","4452K 1:Myyrm\u00e4en as, lait. 7"],"transport_type_id":1}},{"locType":"stop","locTypeId":10,"name":"Elielinaukio","matchedName":"Elielinaukio","lang":"fi","city":"Helsinki","coords":"2552303,6673712","details":{"address":"Laituri 33","code":"1020253","shortCode":"2033","changeCost":0.3,"lines":["4453 1:Martinlaakso, lait.3","4453Z 1:Martinlaakso, lait.3"],"transport_type_id":1}},{"locType":"stop","locTypeId":10,"name":"Elielinaukio","matchedName":"Elielinaukio","lang":"fi","city":"Helsinki","coords":"2552302,6673719","details":{"address":"Laituri 34","code":"1020255","shortCode":"2034","changeCost":0.3,"lines":["2210N 1:Espoon keskus-Eliel","2220N 1:Jupperi-Eliel","2231 1:H\u00e4mevaara","2231K 1:H\u00e4mevaara","2231N 1:J\u00e4rvenper\u00e4","2247 1:L\u00e4hderanta","2247A 1:Jupperi","2248 1:L\u00e4hderanta","2248A 1:Jupperi","2270 1:Tuomarila","2270A 1:Kuurinniitty","2270N 1:Kuurinniitty"],"transport_type_id":1}},{"locType":"stop","locTypeId":10,"name":"Elielinaukio","matchedName":"Elielinaukio","lang":"fi","city":"Helsinki","coords":"2552301,6673726","details":{"address":"Laituri 35","code":"1020257","shortCode":"2035","changeCost":0.3,"lines":["2206 1:Karamalmi","2206A 1:Karamalmi","2212 1:Kauniainen","2213 1:Kauklahti","2213N 1:Kauklahti"],"transport_type_id":1}},{"locType":"stop","locTypeId":10,"name":"Elielinaukio","matchedName":"Elielinaukio","lang":"fi","city":"Helsinki","coords":"2552300,6673733","details":{"address":"Laituri 36","code":"1020259","shortCode":"2036","changeCost":0.3,"lines":["2194 1:Tapiola","2194A 1:Orion","2195 1:Latokaski","2195N 1:Latokaski"],"transport_type_id":1}}]
|
2
|
+
|
@@ -0,0 +1,136 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Reittiopas2::Geocoding do
|
4
|
+
|
5
|
+
before :each do
|
6
|
+
user = "username"
|
7
|
+
pwd = "password"
|
8
|
+
@reitti = Reittiopas2.new(user, pwd)
|
9
|
+
|
10
|
+
@base_query = {'user' => user, 'pass' => pwd}
|
11
|
+
@base_url = "http://api.reittiopas.fi/hsl/prod/"
|
12
|
+
end
|
13
|
+
|
14
|
+
|
15
|
+
describe "geocoding" do
|
16
|
+
before :each do
|
17
|
+
@city = 'Helsinki'
|
18
|
+
@query = @base_query.merge('request' => 'geocode', 'key' => @city)
|
19
|
+
end
|
20
|
+
|
21
|
+
|
22
|
+
it "should perform request to API geocode endpoint." do
|
23
|
+
stub_request(:get, @base_url).
|
24
|
+
with(:query => @query)
|
25
|
+
|
26
|
+
@reitti.geocode(@city)
|
27
|
+
|
28
|
+
a_request(:get, @base_url).
|
29
|
+
with(:query => @query).should have_been_made.once
|
30
|
+
end
|
31
|
+
|
32
|
+
|
33
|
+
it "should send only valid keys to API" do
|
34
|
+
valid_opts = {
|
35
|
+
'cities' => ["helsinki", "espoo"],
|
36
|
+
'loc_types' => ['stop', 'address'],
|
37
|
+
'disable_error_correction' => 0,
|
38
|
+
'disable_unique_stop_names' => 0
|
39
|
+
}
|
40
|
+
|
41
|
+
opts_query_form = {
|
42
|
+
"cities" => "helsinki|espoo",
|
43
|
+
"loc_types" => "stop|address",
|
44
|
+
"disable_error_correction" => 0,
|
45
|
+
"disable_unique_stop_names" => 0
|
46
|
+
}
|
47
|
+
|
48
|
+
|
49
|
+
query = @query.merge(opts_query_form)
|
50
|
+
opts = valid_opts.merge('not_valid_key' => 'or value')
|
51
|
+
|
52
|
+
stub_request(:get, @base_url).
|
53
|
+
with(:query => query)
|
54
|
+
|
55
|
+
@reitti.geocode(@city, opts)
|
56
|
+
|
57
|
+
a_request(:get, @base_url).
|
58
|
+
with(:query => query).should have_been_made.once
|
59
|
+
end
|
60
|
+
|
61
|
+
|
62
|
+
it "should return hash of location hashes if query is success" do
|
63
|
+
opts = {'loc_types' => 'stop'}
|
64
|
+
|
65
|
+
json = File.new('spec/data/geocode.json')
|
66
|
+
stub_request(:get, @base_url).
|
67
|
+
with(:query => @query.merge(opts)).
|
68
|
+
to_return(:body => json)
|
69
|
+
|
70
|
+
locs = @reitti.geocode("Helsinki", opts)
|
71
|
+
locs.should be_kind_of(Array)
|
72
|
+
locs[0].should be_kind_of(Hash)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
|
77
|
+
describe "reverse geocoding" do
|
78
|
+
before :each do
|
79
|
+
@coords = '2548196,6678528'
|
80
|
+
@query = @base_query.merge('request' => 'reverse_geocode',
|
81
|
+
'coordinate' => @coords)
|
82
|
+
end
|
83
|
+
|
84
|
+
|
85
|
+
it "should perform request to API reverse_geocode endpoint." do
|
86
|
+
stub_request(:get, @base_url).
|
87
|
+
with(:query => @query)
|
88
|
+
|
89
|
+
@reitti.reverse_geocode(@coords)
|
90
|
+
|
91
|
+
a_request(:get, @base_url).
|
92
|
+
with(:query => @query).should have_been_made.once
|
93
|
+
end
|
94
|
+
|
95
|
+
|
96
|
+
it "should send only valid keys to API" do
|
97
|
+
valid_opts = {
|
98
|
+
'coordinate' => '2552335,6673660',
|
99
|
+
'limit' => 1,
|
100
|
+
'radius' => 1000,
|
101
|
+
'result_contains' => 'stop'
|
102
|
+
}
|
103
|
+
|
104
|
+
opts_query_form = {
|
105
|
+
"coordinate" => "2552335,6673660",
|
106
|
+
"limit" => 1,
|
107
|
+
"radius" => 1000,
|
108
|
+
"result_contains" => "stop"
|
109
|
+
}
|
110
|
+
|
111
|
+
|
112
|
+
opts = valid_opts.merge('not_valid_key' => 'or value')
|
113
|
+
query = @query.merge(opts_query_form)
|
114
|
+
|
115
|
+
stub_request(:get, @base_url).
|
116
|
+
with(:query => query)
|
117
|
+
|
118
|
+
@reitti.reverse_geocode(@coords, opts)
|
119
|
+
|
120
|
+
a_request(:get, @base_url).
|
121
|
+
with(:query => query).should have_been_made.once
|
122
|
+
end
|
123
|
+
|
124
|
+
|
125
|
+
it "should return hash of location hashes if query is success" do
|
126
|
+
json = File.new('spec/data/reverse_geocode.json')
|
127
|
+
stub_request(:get, @base_url).
|
128
|
+
with(:query => @query).
|
129
|
+
to_return(:body => json)
|
130
|
+
|
131
|
+
locs = @reitti.reverse_geocode(@coords)
|
132
|
+
locs.should be_kind_of(Array)
|
133
|
+
locs[0].should be_kind_of(Hash)
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Reittiopas2::Routing do
|
4
|
+
before :each do
|
5
|
+
user = "username"
|
6
|
+
pass = "password"
|
7
|
+
@reitti = Reittiopas2.new(user, pass)
|
8
|
+
|
9
|
+
@base_query = {'user' => user, 'pass' => pass}
|
10
|
+
@base_url = "http://api.reittiopas.fi/hsl/prod/"
|
11
|
+
end
|
12
|
+
|
13
|
+
describe "route fetching" do
|
14
|
+
before :each do
|
15
|
+
@from = '2546445,6675512'
|
16
|
+
@to = '2549445,6675513'
|
17
|
+
@query = @base_query.merge('request' => 'route',
|
18
|
+
'from' => @from,
|
19
|
+
'to' => @to)
|
20
|
+
end
|
21
|
+
|
22
|
+
it "should accept coordinates as strings." do
|
23
|
+
stub_request(:get, @base_url).
|
24
|
+
with(:query => @query)
|
25
|
+
|
26
|
+
@reitti.route(@from, @to)
|
27
|
+
a_request(:get, @base_url).
|
28
|
+
with(:query => @query).should have_been_made.once
|
29
|
+
end
|
30
|
+
|
31
|
+
it "should accept location hashes as coordinates." do
|
32
|
+
from_hash = {'coordinate' => @from}
|
33
|
+
to_hash = {'coordinate' => @to}
|
34
|
+
|
35
|
+
stub_request(:get, @base_url).
|
36
|
+
with(:query => @query)
|
37
|
+
|
38
|
+
@reitti.route(from_hash, to_hash)
|
39
|
+
a_request(:get, @base_url).
|
40
|
+
with(:query => @query).should have_been_made.once
|
41
|
+
end
|
42
|
+
|
43
|
+
it "should reject hashes without coordinates." do
|
44
|
+
from_hash = {'fake' => @from}
|
45
|
+
to_hash = {'fake' => @to}
|
46
|
+
|
47
|
+
ret = @reitti.route(from_hash, to_hash)
|
48
|
+
ret['error'].should == 'ArgumentError: locations were not acceptable types'
|
49
|
+
end
|
50
|
+
|
51
|
+
it "should reject coordinates which are different types." do
|
52
|
+
from_hash = {'fake' => @from}
|
53
|
+
ret = @reitti.route(from_hash, @to)
|
54
|
+
ret['error'].should == 'ArgumentError: from.class != to.class'
|
55
|
+
end
|
56
|
+
|
57
|
+
# This test works because we are not checking values, only keys
|
58
|
+
it "should reject keys that are not valid query parameters" do
|
59
|
+
keys = ['via', 'date', 'time', 'timetype', 'via_time', 'zone',
|
60
|
+
'transport_types', 'optimize', 'change_margin', 'change_cost',
|
61
|
+
'wait_cost', 'walk_cost', 'walk_speed', 'detail', 'show']
|
62
|
+
mode_costs = ['mode_cost_1', 'mode_cost_2', 'mode_cost_3', 'mode_cost_4',
|
63
|
+
'mode_cost_5', 'mode_cost_6', 'mode_cost_7', 'mode_cost_7',
|
64
|
+
'mode_cost_8', 'mode_cost_12', 'mode_cost_21', 'mode_cost_22',
|
65
|
+
'mode_cost_23', 'mode_cost_24', 'mode_cost_25', 'mode_cost_36',
|
66
|
+
'mode_cost_39']
|
67
|
+
|
68
|
+
opts = {}
|
69
|
+
keys.each { |key| opts[key] = "_" }
|
70
|
+
mode_costs.each { |key| opts[key] = "_" }
|
71
|
+
|
72
|
+
query = @query.merge(opts)
|
73
|
+
stub_request(:get, @base_url).
|
74
|
+
with(:query => query)
|
75
|
+
|
76
|
+
invalid = query.merge('not valid' => 'at all')
|
77
|
+
@reitti.route(@from, @to, invalid)
|
78
|
+
|
79
|
+
a_request(:get, @base_url).
|
80
|
+
with(:query => query).should have_been_made.once
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
require "rubygems"
|
2
|
+
require "bundler/setup"
|
3
|
+
require "webmock/rspec"
|
4
|
+
|
5
|
+
require "simplecov"
|
6
|
+
SimpleCov.start
|
7
|
+
|
8
|
+
require "reittiopas2"
|
9
|
+
|
10
|
+
|
11
|
+
RSpec.configure do |config|
|
12
|
+
config.treat_symbols_as_metadata_keys_with_true_values = true
|
13
|
+
config.run_all_when_everything_filtered = true
|
14
|
+
config.filter_run :focus
|
15
|
+
end
|
metadata
ADDED
@@ -0,0 +1,153 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: reittiopas2
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Iivari Äikäs
|
8
|
+
- Jussi Virtanen
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-10-28 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: json
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
requirements:
|
18
|
+
- - ~>
|
19
|
+
- !ruby/object:Gem::Version
|
20
|
+
version: '1.8'
|
21
|
+
type: :runtime
|
22
|
+
prerelease: false
|
23
|
+
version_requirements: !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - ~>
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
version: '1.8'
|
28
|
+
- !ruby/object:Gem::Dependency
|
29
|
+
name: addressable
|
30
|
+
requirement: !ruby/object:Gem::Requirement
|
31
|
+
requirements:
|
32
|
+
- - ~>
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
version: '2.3'
|
35
|
+
type: :runtime
|
36
|
+
prerelease: false
|
37
|
+
version_requirements: !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - ~>
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: '2.3'
|
42
|
+
- !ruby/object:Gem::Dependency
|
43
|
+
name: rspec
|
44
|
+
requirement: !ruby/object:Gem::Requirement
|
45
|
+
requirements:
|
46
|
+
- - ~>
|
47
|
+
- !ruby/object:Gem::Version
|
48
|
+
version: '2.14'
|
49
|
+
type: :development
|
50
|
+
prerelease: false
|
51
|
+
version_requirements: !ruby/object:Gem::Requirement
|
52
|
+
requirements:
|
53
|
+
- - ~>
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: '2.14'
|
56
|
+
- !ruby/object:Gem::Dependency
|
57
|
+
name: webmock
|
58
|
+
requirement: !ruby/object:Gem::Requirement
|
59
|
+
requirements:
|
60
|
+
- - ~>
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: '1.15'
|
63
|
+
type: :development
|
64
|
+
prerelease: false
|
65
|
+
version_requirements: !ruby/object:Gem::Requirement
|
66
|
+
requirements:
|
67
|
+
- - ~>
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '1.15'
|
70
|
+
- !ruby/object:Gem::Dependency
|
71
|
+
name: guard-rspec
|
72
|
+
requirement: !ruby/object:Gem::Requirement
|
73
|
+
requirements:
|
74
|
+
- - ~>
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: '4.0'
|
77
|
+
type: :development
|
78
|
+
prerelease: false
|
79
|
+
version_requirements: !ruby/object:Gem::Requirement
|
80
|
+
requirements:
|
81
|
+
- - ~>
|
82
|
+
- !ruby/object:Gem::Version
|
83
|
+
version: '4.0'
|
84
|
+
- !ruby/object:Gem::Dependency
|
85
|
+
name: simplecov
|
86
|
+
requirement: !ruby/object:Gem::Requirement
|
87
|
+
requirements:
|
88
|
+
- - ~>
|
89
|
+
- !ruby/object:Gem::Version
|
90
|
+
version: '0.7'
|
91
|
+
type: :development
|
92
|
+
prerelease: false
|
93
|
+
version_requirements: !ruby/object:Gem::Requirement
|
94
|
+
requirements:
|
95
|
+
- - ~>
|
96
|
+
- !ruby/object:Gem::Version
|
97
|
+
version: '0.7'
|
98
|
+
description: Reittiopas version 2 API library.
|
99
|
+
email:
|
100
|
+
- iivari.aikas@gmail.com
|
101
|
+
executables: []
|
102
|
+
extensions: []
|
103
|
+
extra_rdoc_files: []
|
104
|
+
files:
|
105
|
+
- .gitignore
|
106
|
+
- .rspec
|
107
|
+
- Gemfile
|
108
|
+
- Guardfile
|
109
|
+
- LICENSE
|
110
|
+
- README.md
|
111
|
+
- Rakefile
|
112
|
+
- lib/reittiopas2.rb
|
113
|
+
- lib/reittiopas2/connection.rb
|
114
|
+
- lib/reittiopas2/geocoding.rb
|
115
|
+
- lib/reittiopas2/routing.rb
|
116
|
+
- lib/reittiopas2/version.rb
|
117
|
+
- reittiopas2.gemspec
|
118
|
+
- spec/connection_spec.rb
|
119
|
+
- spec/data/geocode.json
|
120
|
+
- spec/data/reverse_geocode.json
|
121
|
+
- spec/geocoding_spec.rb
|
122
|
+
- spec/routing_spec.rb
|
123
|
+
- spec/spec_helper.rb
|
124
|
+
homepage: https://github.com/orva/reittiopas2
|
125
|
+
licenses: []
|
126
|
+
metadata: {}
|
127
|
+
post_install_message:
|
128
|
+
rdoc_options: []
|
129
|
+
require_paths:
|
130
|
+
- lib
|
131
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
132
|
+
requirements:
|
133
|
+
- - '>='
|
134
|
+
- !ruby/object:Gem::Version
|
135
|
+
version: '0'
|
136
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
137
|
+
requirements:
|
138
|
+
- - '>='
|
139
|
+
- !ruby/object:Gem::Version
|
140
|
+
version: '0'
|
141
|
+
requirements: []
|
142
|
+
rubyforge_project:
|
143
|
+
rubygems_version: 2.0.3
|
144
|
+
signing_key:
|
145
|
+
specification_version: 4
|
146
|
+
summary: Gem providing easy access to reittiopas version 2 API.
|
147
|
+
test_files:
|
148
|
+
- spec/connection_spec.rb
|
149
|
+
- spec/data/geocode.json
|
150
|
+
- spec/data/reverse_geocode.json
|
151
|
+
- spec/geocoding_spec.rb
|
152
|
+
- spec/routing_spec.rb
|
153
|
+
- spec/spec_helper.rb
|