reittiopas 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.
@@ -0,0 +1,4 @@
1
+ === 0.0.1 2010-03-29
2
+
3
+ * 1 major enhancement:
4
+ * Initial release
@@ -0,0 +1,21 @@
1
+ History.txt
2
+ Manifest.txt
3
+ README.rdoc
4
+ Rakefile
5
+ deps.rip
6
+ lib/reittiopas.rb
7
+ lib/reittiopas/coordinates.rb
8
+ lib/reittiopas/geocoding.rb
9
+ lib/reittiopas/http.rb
10
+ lib/reittiopas/location.rb
11
+ lib/reittiopas/reittiopas.rb
12
+ lib/reittiopas/utils.rb
13
+ script/console
14
+ script/destroy
15
+ script/generate
16
+ spec/fixtures/key.xml
17
+ spec/fixtures/reverse_geocoding.xml
18
+ spec/reittiopas_spec.rb
19
+ spec/spec.opts
20
+ spec/spec_helper.rb
21
+ tasks/rspec.rake
@@ -0,0 +1,58 @@
1
+ = Reittiopas
2
+
3
+ * {Documentation at Github}[http://raneksi.github.com/reittiopas/]
4
+
5
+ == DESCRIPTION:
6
+
7
+ Reittiopas is a Ruby library for accessing the {Reittiopas Developer API}[http://developer.reittiopas.fi/pages/fi/reittiopas-api.php].
8
+
9
+ Requires an account to the service that can be requested through {the account request page}[http://developer.reittiopas.fi/pages/fi/accountrequest.php].
10
+
11
+ == SYNOPSIS:
12
+ require 'reittiopas'
13
+ reittiopas = Reittiopas.new(:username => 'myuser', :password => 'lolcats')
14
+
15
+ === Geocoding
16
+ Search for location by keyword _tee_.
17
+ location = reittiopas.location('tee').first
18
+ puts "#{location}, #{location.city}"
19
+ puts "http://maps.google.com/maps?q=#{URI.escape location.coordinates[:wgs]}"
20
+ Teeripuisto, Helsinki
21
+
22
+ http://maps.google.com/maps?q=60.2528,%2025.02051
23
+
24
+ === Reverse geocoding
25
+ Search for a location by KKJ[http://fi.wikipedia.org/wiki/Kartastokoordinaattij%C3%A4rjestelm%C3%A4] coordinates.
26
+ location = reittiopas.location(:x => 2546445, :y => 6675512).first
27
+ puts "#{location}, #{location.city}"
28
+ Otakaari 9, Espoo
29
+
30
+ == REQUIREMENTS:
31
+
32
+ * Nokogiri[http://nokogiri.org/]
33
+ * Addressable[http://github.com/sporkmonger/addressable]
34
+
35
+ == LICENSE:
36
+
37
+ (The MIT License)
38
+
39
+ Copyright (c) 2010 Raine Virta
40
+
41
+ Permission is hereby granted, free of charge, to any person obtaining
42
+ a copy of this software and associated documentation files (the
43
+ 'Software'), to deal in the Software without restriction, including
44
+ without limitation the rights to use, copy, modify, merge, publish,
45
+ distribute, sublicense, and/or sell copies of the Software, and to
46
+ permit persons to whom the Software is furnished to do so, subject to
47
+ the following conditions:
48
+
49
+ The above copyright notice and this permission notice shall be
50
+ included in all copies or substantial portions of the Software.
51
+
52
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
53
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
54
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
55
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
56
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
57
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
58
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,34 @@
1
+ require 'rubygems'
2
+ gem 'hoe', '>= 2.1.0'
3
+ require 'hoe'
4
+ require 'fileutils'
5
+ require './lib/reittiopas'
6
+
7
+ Hoe.plugin :newgem
8
+
9
+ $hoe = Hoe.spec 'reittiopas' do
10
+ developer 'Raine Virta', 'raine.virta@gmail.com'
11
+ self.rubyforge_name = self.name
12
+
13
+ %w{ addressable nokogiri }.each do |dep|
14
+ self.extra_dev_deps << [dep, '>= 0']
15
+ end
16
+
17
+ self.url = "http://github.com/raneksi/reittiopas"
18
+ self.extra_dev_deps = [['webmock', ">= 0"]]
19
+ self.readme_file = "README.rdoc"
20
+ self.extra_rdoc_files = FileList['*.rdoc']
21
+ end
22
+
23
+ require 'newgem/tasks'
24
+ Dir['tasks/**/*.rake'].each { |t| load t }
25
+
26
+ # remove_task :default
27
+ # task :default => [:spec, :features]
28
+
29
+ require 'gokdok'
30
+ Gokdok::Dokker.new do |gd|
31
+ gd.repo_url = "git@github.com:raneksi/reittiopas.git"
32
+ gd.rdoc_task = :docs
33
+ gd.doc_home = 'doc'
34
+ end
@@ -0,0 +1 @@
1
+ http://github.com/sporkmonger/addressable.git
@@ -0,0 +1,28 @@
1
+ $:.unshift(File.dirname(__FILE__)) unless
2
+ $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
3
+
4
+ require 'rubygems'
5
+ require 'uri'
6
+ require 'cgi'
7
+ require 'net/http'
8
+ require 'nokogiri'
9
+ require 'addressable/uri'
10
+
11
+ require 'reittiopas/utils'
12
+ require 'reittiopas/coordinates'
13
+ require 'reittiopas/location'
14
+ require 'reittiopas/geocoding'
15
+ require 'reittiopas/reittiopas'
16
+ require 'reittiopas/http'
17
+
18
+ class Reittiopas
19
+ # The version of Reittiopas you are using.
20
+ VERSION = "0.0.1"
21
+ end
22
+
23
+ # Shorter way for Reittiopas instance creation.
24
+ # In actuality, this doesn't make much sense since it just hides
25
+ # the +new+ method. FIXME
26
+ def Reittiopas(account)
27
+ return Reittiopas.new(account)
28
+ end
@@ -0,0 +1,25 @@
1
+ class Reittiopas
2
+ class Location
3
+ module Coordinates # :nodoc:
4
+ class WGS
5
+ attr_accessor :latitude, :longitude
6
+ def initialize(opts)
7
+ @latitude = opts[:lat].to_f
8
+ @longitude = opts[:lon].to_f
9
+ end
10
+
11
+ def to_s
12
+ [@latitude, @longitude].join(', ')
13
+ end
14
+ end
15
+
16
+ class KKJ
17
+ attr_accessor :x, :y
18
+ def initialize(opts)
19
+ @x = opts[:x].to_i
20
+ @y = opts[:y].to_i
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,53 @@
1
+ class Reittiopas
2
+
3
+ # Module implementing the geocoding features of the Reittiopas API
4
+ # documented at http://developer.reittiopas.fi/pages/fi/http-get-interface.php
5
+ module Geocoding
6
+
7
+ # Send a geocode location query to the API.
8
+ # Both geocoding, and reverse geocoding data is accessed through this method.
9
+ #
10
+ # Returns results as an array containing Reittiopas::Location objects.
11
+ #
12
+ # === Examples:
13
+ # * Search for location by keyword _tee_.
14
+ # reittiopas.location('tee')
15
+ #
16
+ # * Search for location by KKJ coordinates x: _2546445_, y: _6675512_.
17
+ # reittiopas.location(:x => 2546445, :y => 6675512)
18
+ #
19
+ def location(opts)
20
+ params = if opts.is_a? String
21
+ {:key => opts}
22
+ elsif opts.is_a? Hash
23
+ opts
24
+ end
25
+
26
+ parse @http.get(params), opts
27
+ end
28
+
29
+ private
30
+ # Parse XML received from a geocoding API query.
31
+ def parse(xml, opts)
32
+ doc = Nokogiri::XML(xml)
33
+
34
+ locations = doc.search('LOC').map do |loc|
35
+ Reittiopas::Location.parse(loc)
36
+ end
37
+
38
+ # Add KKJ coordinates from REVERSE tag to each Location returned
39
+ # in case it was a reverse geocoding query
40
+ if opts.is_a? Hash
41
+ reverse = doc.search('REVERSE').last
42
+ x = reverse.get_attr_value('x').to_i
43
+ y = reverse.get_attr_value('y').to_i
44
+
45
+ locations.each do |loc|
46
+ loc.coordinates = { :kkj => Reittiopas::Location::Coordinates::KKJ.new(:x => x, :y => y) }
47
+ end
48
+ end
49
+
50
+ return locations
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,40 @@
1
+ class Reittiopas
2
+
3
+ # Reittiopas::HTTP is initialized with account details upon initialization
4
+ # of a Reittiopas object.
5
+ #
6
+ # Since Reittiopas API is to be queried using
7
+ # GET requests with appropriate query parameters, Reittiopas::HTTP exists
8
+ # to simplify the process by offering a +get+ method that accepts a hash
9
+ # containing the query parameters as an argument.
10
+ #
11
+ class HTTP
12
+ # Base URI for the Reittiopas API service.
13
+ API_BASE_URI = "http://api.reittiopas.fi/public-ytv/fi/api/"
14
+
15
+ # Addressable::URI instance of the API URI with account details set as
16
+ # query parameters.
17
+ attr_reader :api_uri
18
+
19
+ # Create a new Reittiopas::HTTP object.
20
+ #
21
+ # +account+ should be a hash containing +:username+ and +:password+.
22
+ def initialize(account)
23
+ @api_uri = Addressable::URI.parse(API_BASE_URI)
24
+ @api_uri.query_values = {:user => account[:username], :pass => account[:password]}
25
+ end
26
+
27
+ # Send a GET request to the API with account details and +opts+ as query
28
+ # parameters.
29
+ #
30
+ # * +opts+ — A hash containing query parameters. Values are automatically
31
+ # encoded by Addressable::URI.
32
+ def get(opts)
33
+ raise ArgumentError if opts.empty?
34
+ uri = @api_uri.dup
35
+ opts.merge!(opts){ |k,ov| ov.to_s } # Coordinates to string
36
+ uri.query_values = uri.query_values.merge(opts)
37
+ return Net::HTTP.get(uri)
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,87 @@
1
+ class Reittiopas
2
+
3
+ # This class represents a Location.
4
+ class Location
5
+
6
+ # Get the name of the location.
7
+ attr_accessor :name
8
+
9
+ # Get the city of the location.
10
+ attr_accessor :city
11
+
12
+ # Get the type of the location.
13
+ attr_accessor :type
14
+
15
+ # Get coordinates of the location as a Hash containing Coordinates objects.
16
+ attr_accessor :coordinates
17
+
18
+ # Get the street number of the location.
19
+ attr_accessor :number
20
+
21
+ # Create a Location object from Nokogiri::XML::Element object containing
22
+ # location data.
23
+ def self.parse(xml)
24
+ attr = xml.attributes
25
+
26
+ category = xml.get_attr_value('category')
27
+
28
+ loc = case category
29
+ when "street" then Street.new
30
+ when "stop" then Stop.new
31
+ when "poi" then PointOfInterest.new
32
+ else Location.new
33
+ end
34
+
35
+ loc.name = xml.get_attr_value 'name1'
36
+ loc.city = xml.get_attr_value 'city'
37
+ type = xml.get_attr_value 'type'
38
+ code = xml.get_attr_value 'code'
39
+ number = xml.get_attr_value 'number'
40
+ address = xml.get_attr_value 'address'
41
+
42
+ loc.type = type.to_i if type
43
+ loc.code = code.to_i if code
44
+ loc.number = number.to_i if number
45
+ loc.address = address if address
46
+
47
+ coordinates = {}
48
+
49
+ if attr["x"] && attr["y"]
50
+ coordinates[:kkj] = Coordinates::KKJ.new(Hash[*%w(x y).map { |e| [e.to_sym, attr[e].value.to_i] }.flatten])
51
+ end
52
+
53
+ if attr["lat"] && attr["lon"]
54
+ coordinates[:wgs] = Coordinates::WGS.new(Hash[*%w(lat lon).map { |e| [e.to_sym, attr[e].value.to_f] }.flatten])
55
+ end
56
+
57
+ loc.coordinates = coordinates unless coordinates.empty?
58
+
59
+ return loc
60
+ end
61
+
62
+ # Get the name and street number (if applicable) of the location.
63
+ def to_s
64
+ "#{name} #{number}".strip
65
+ end
66
+
67
+ class PointOfInterest < Location
68
+ # Get the code of the point of interest location.
69
+ attr_accessor :code
70
+ end
71
+
72
+ class Stop < Location
73
+ # Get the address of the bus stop.
74
+ #
75
+ # To follow the API's response format, only bus stops have an address. FIXME?
76
+ attr_accessor :address
77
+
78
+ # Get the code of the bus stop.
79
+ attr_accessor :code
80
+ end
81
+
82
+ class Street < Location
83
+ # Get the street number of the location.
84
+ attr_accessor :number
85
+ end
86
+ end
87
+ end
@@ -0,0 +1,15 @@
1
+ # Reittiopas is a Ruby library for accessing the
2
+ # {Reittiopas Developer API}[http://developer.reittiopas.fi/pages/fi/reittiopas-api.php].
3
+ #
4
+ class Reittiopas
5
+ include Geocoding
6
+
7
+ # Instantiate a Reittiopas object.
8
+ #
9
+ # +account+ should be a hash containing +:username+ and +:password+.
10
+ #
11
+ # Reittiopas.new(:username => 'exampleuser', :password => 'lolcat')
12
+ def initialize(account)
13
+ @http = Reittiopas::HTTP.new(account)
14
+ end
15
+ end
@@ -0,0 +1,11 @@
1
+ # Ugly, get rid of
2
+ module Nokogiri #:nodoc: all
3
+ module XML
4
+ class Element
5
+ def get_attr_value(attr)
6
+ # Might be better to just discard empty attributes
7
+ (a = attribute(attr); a && !a.value.empty? ? a.value : nil)
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env ruby
2
+ # File: script/console
3
+ irb = RUBY_PLATFORM =~ /(:?mswin|mingw)/ ? 'irb.bat' : 'irb'
4
+
5
+ libs = " -r irb/completion"
6
+ # Perhaps use a console_lib to store any extra methods I may want available in the cosole
7
+ # libs << " -r #{File.dirname(__FILE__) + '/../lib/console_lib/console_logger.rb'}"
8
+ libs << " -r #{File.dirname(__FILE__) + '/../lib/reittiopas.rb'}"
9
+ puts "Loading reittiopas gem"
10
+ exec "#{irb} #{libs} --simple-prompt"
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+ APP_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..'))
3
+
4
+ begin
5
+ require 'rubigen'
6
+ rescue LoadError
7
+ require 'rubygems'
8
+ require 'rubigen'
9
+ end
10
+ require 'rubigen/scripts/destroy'
11
+
12
+ ARGV.shift if ['--help', '-h'].include?(ARGV[0])
13
+ RubiGen::Base.use_component_sources! [:rubygems, :newgem, :newgem_theme, :test_unit]
14
+ RubiGen::Scripts::Destroy.new.run(ARGV)
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+ APP_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..'))
3
+
4
+ begin
5
+ require 'rubigen'
6
+ rescue LoadError
7
+ require 'rubygems'
8
+ require 'rubigen'
9
+ end
10
+ require 'rubigen/scripts/generate'
11
+
12
+ ARGV.shift if ['--help', '-h'].include?(ARGV[0])
13
+ RubiGen::Base.use_component_sources! [:rubygems, :newgem, :newgem_theme, :test_unit]
14
+ RubiGen::Scripts::Generate.new.run(ARGV)
@@ -0,0 +1,22 @@
1
+ <?xml version="1.0" encoding="ISO-8859-1" ?><MTRXML version="1.0">
2
+ <GEOCODE key="tee">
3
+ <LOC name1="Teeripuisto" number="" city="Helsinki" code="1700" address="" type="3" category="poi" x="2556686" y="6682815" lon="25.02051" lat="60.2528" />
4
+ <LOC name1="Teemuntie" number="" city="Helsinki" code="" address="" type="900" category="street" x="2558052" y="6685202" lon="25.04586" lat="60.27403" />
5
+ <LOC name1="Teerenpelinpolku" number="" city="Helsinki" code="" address="" type="900" category="street" x="2556598" y="6682627" lon="25.01887" lat="60.25113" />
6
+ <LOC name1="Teerentie" number="" city="Kirkkonummi" code="" address="" type="900" category="street" x="2524975" y="6686648" lon="24.44833" lat="60.29037" />
7
+ <LOC name1="Teerikuja" number="" city="Vantaa" code="" address="" type="900" category="street" x="2559103" y="6693697" lon="25.06733" lat="60.35011" />
8
+ <LOC name1="Teerikukonkuja" number="" city="Helsinki" code="" address="" type="900" category="street" x="2556898" y="6683026" lon="25.0244" lat="60.25466" />
9
+ <LOC name1="Teerikukontie" number="" city="Helsinki" code="" address="" type="900" category="street" x="2556907" y="6682892" lon="25.02453" lat="60.25346" />
10
+ <LOC name1="Teerimäentie" number="" city="Kerava" code="" address="" type="900" category="street" x="2560257" y="6698983" lon="25.08981" lat="60.39737" />
11
+ <LOC name1="Teerimäentie" number="" city="Vantaa" code="" address="" type="900" category="street" x="2562514" y="6686983" lon="25.12703" lat="60.28935" />
12
+ <LOC name1="Teeripolku" number="" city="Vantaa" code="" address="" type="900" category="street" x="2559133" y="6693811" lon="25.06791" lat="60.35113" />
13
+ <LOC name1="Teeririnne" number="" city="Vantaa" code="" address="" type="900" category="street" x="2559169" y="6693364" lon="25.06843" lat="60.34711" />
14
+ <LOC name1="Teerisuonkuja" number="" city="Helsinki" code="" address="" type="900" category="street" x="2556995" y="6682667" lon="25.02605" lat="60.25143" />
15
+ <LOC name1="Teerisuontie" number="" city="Helsinki" code="" address="" type="900" category="street" x="2557034" y="6682586" lon="25.02673" lat="60.2507" />
16
+ <LOC name1="Teeritie" number="" city="Vantaa" code="" address="" type="900" category="street" x="2559070" y="6693600" lon="25.06671" lat="60.34924" />
17
+ <LOC name1="Teekkarikylä" number="" city="Espoo" code="2222208" address="Otakaari" type="10" category="stop" x="2546445" y="6675512" lon="24.83393" lat="60.18855" />
18
+ <LOC name1="Teerisuonkuja" number="" city="Helsinki" code="1382186" address="Teerisuontie" type="10" category="stop" x="2556964" y="6682609" lon="25.02547" lat="60.25091" />
19
+ <LOC name1="Teerisuontie" number="" city="Helsinki" code="1382141" address="Teerisuontie" type="10" category="stop" x="2556740" y="6682861" lon="25.0215" lat="60.25321" />
20
+ <LOC name1="Teeritie" number="" city="Vantaa" code="4810204" address="Korsontie" type="10" category="stop" x="2559002" y="6694007" lon="25.06559" lat="60.35291" />
21
+ </GEOCODE>
22
+ </MTRXML>
@@ -0,0 +1,5 @@
1
+ <?xml version="1.0" encoding="ISO-8859-1" ?><MTRXML version="1.0">
2
+ <REVERSE x="2546445" y="6675512">
3
+ <LOC name1="Otakaari" number="9" city="Espoo" />
4
+ </REVERSE>
5
+ </MTRXML>
@@ -0,0 +1,245 @@
1
+ require File.dirname(__FILE__) + '/spec_helper.rb'
2
+
3
+ describe "Reittiopas()" do
4
+ before { @account = {:username => 'foo', :password => 'bar'} }
5
+
6
+ context "when called with an account hash as argument" do
7
+ subject { Reittiopas(@account) }
8
+
9
+ it "should return a Reittiopas object" do
10
+ should be_a_kind_of(Reittiopas)
11
+ end
12
+ end
13
+ end
14
+
15
+ describe Reittiopas do
16
+ before { @account = {:username => 'foo', :password => 'bar'} }
17
+
18
+ context "when initialized with an account" do
19
+ subject { Reittiopas.new(@account) }
20
+
21
+ it { should respond_to(:location) }
22
+ end
23
+
24
+ describe "#location" do
25
+ before { @reittiopas = Reittiopas.new(@account) }
26
+
27
+ context "when given key 'tee' that returns 18 locations from API" do
28
+ before do
29
+ response = File.read(File.dirname(__FILE__) + '/fixtures/key.xml')
30
+ stub_request(:any, /.*key=tee.*/).to_return(:body => response, :status => 200)
31
+ end
32
+
33
+ subject { @reittiopas.location('tee') }
34
+
35
+ it "should return 18 locations in an array" do
36
+ should have(18).items
37
+
38
+ subject.each do |obj|
39
+ obj.should be_a Reittiopas::Location
40
+ end
41
+ end
42
+ end
43
+
44
+ context "when given KKJ coordinates that return one location from API" do
45
+ before do
46
+ response = File.read(File.dirname(__FILE__) + '/fixtures/reverse_geocoding.xml')
47
+ stub_request(:any, /(?:x|y)=\d+&(?:x|y)=\d+/).to_return(:body => response, :status => 200)
48
+ end
49
+
50
+ subject { @reittiopas.location(:x => 2546445, :y => 6675512) }
51
+
52
+ it "should return one result" do
53
+ should have(1).item
54
+ end
55
+
56
+ it "should return a location" do
57
+ subject.first.should be_a Reittiopas::Location
58
+ end
59
+
60
+ it "should return a location with KKJ coordinates" do
61
+ subject.last.coordinates[:kkj].x.should eql 2546445
62
+ subject.last.coordinates[:kkj].y.should eql 6675512
63
+ end
64
+ end
65
+ end
66
+ end
67
+
68
+ describe Reittiopas::HTTP do
69
+ it "should have the proper base API URI" do
70
+ Reittiopas::HTTP::API_BASE_URI.should eql(BASE_URI)
71
+ end
72
+
73
+ before do
74
+ @account = {:username => 'foo', :password => 'bar'}
75
+ @http = Reittiopas::HTTP.new(@account)
76
+ end
77
+
78
+ context "when initialized with an account" do
79
+ subject { Reittiopas::HTTP.new(@account) }
80
+ it { should respond_to(:get) }
81
+
82
+ it "should create an API URI with account details" do
83
+ subject.api_uri.query_values.
84
+ should eql('user' => @account[:username], 'pass' => @account[:password])
85
+ end
86
+ end
87
+
88
+ describe "#get" do
89
+ context "with empty hash as argument" do
90
+ it { lambda { @http.get({}) }.should raise_error(ArgumentError) }
91
+ end
92
+
93
+ context "with proper hash as argument" do
94
+ before do
95
+ @opts = {'key' => 'Keihäänheittäjänkuja 12'}
96
+ @uri = @http.api_uri
97
+ @uri.query_values = @uri.query_values.merge(@opts)
98
+ end
99
+
100
+ it "should create a request" do
101
+ stub_request(:get, Regexp.new(BASE_URI))
102
+ @http.get(@opts)
103
+ request(:get, @uri.to_s).should have_been_made
104
+ end
105
+
106
+ it "should return response body on successful request" do
107
+ stub_request(:get, @uri.to_s).to_return(:body => 'hello', :status => 200)
108
+ @http.get(@opts).should eql('hello')
109
+ end
110
+ end
111
+ end
112
+ end
113
+
114
+ describe Reittiopas::Location do
115
+ it { should respond_to :name }
116
+ it { should respond_to :city }
117
+ it { should respond_to :type }
118
+
119
+ describe "#parse" do
120
+ context "when given LOC" do
121
+ context "example 1" do
122
+ xml = parse_elem '<LOC name1="Sello" number="" city="Espoo" code="2112201" address="Ratsukuja" type="10" category="stop" x="2545011" y="6678850" lon="24.80882" lat="60.21867"/>'
123
+ subject { Reittiopas::Location.parse xml }
124
+
125
+ it { subject.should be_a Reittiopas::Location::Stop }
126
+ it { subject.address.should eql 'Ratsukuja' }
127
+ it { subject.city.should eql 'Espoo' }
128
+ it { subject.name.should eql 'Sello' }
129
+ it { subject.type.should eql 10 }
130
+ it { subject.code.should eql 2112201 }
131
+ it { subject.coordinates[:kkj].x.should eql 2545011 }
132
+ it { subject.coordinates[:kkj].y.should eql 6678850 }
133
+ it { subject.coordinates[:wgs].longitude.should eql 24.80882 }
134
+ it { subject.coordinates[:wgs].latitude.should eql 60.21867 }
135
+ it { subject.to_s.should eql 'Sello' }
136
+ end
137
+
138
+ context "example 2" do
139
+ xml = parse_elem '<LOC name1="Kahisevantie" number="2" city="Espoo" code="" address="" type="900" category="street" x="2541494" y="6680344" lon="24.74568" lat="60.23245"/>'
140
+ subject { Reittiopas::Location.parse xml }
141
+
142
+ it { subject.should be_a Reittiopas::Location::Street }
143
+ it { subject.should_not respond_to :address }
144
+ it { subject.should_not respond_to :code }
145
+ it { subject.city.should eql 'Espoo' }
146
+ it { subject.name.should eql 'Kahisevantie' }
147
+ it { subject.type.should eql 900 }
148
+ it { subject.number.should eql 2 }
149
+ it { subject.coordinates[:kkj].x.should eql 2541494 }
150
+ it { subject.coordinates[:kkj].y.should eql 6680344 }
151
+ it { subject.coordinates[:wgs].longitude.should eql 24.74568 }
152
+ it { subject.coordinates[:wgs].latitude.should eql 60.23245 }
153
+ it { subject.to_s.should eql 'Kahisevantie 2' }
154
+ end
155
+
156
+ context "example 3" do
157
+ xml = parse_elem '<LOC name1="Teeripuisto" number="" city="Helsinki" code="1700" address="" type="3" category="poi" x="2556686" y="6682815" lon="25.02051" lat="60.2528" />'
158
+ subject { Reittiopas::Location.parse xml }
159
+
160
+ it { subject.should be_a Reittiopas::Location::PointOfInterest }
161
+ it { subject.should_not respond_to :address }
162
+ it { subject.city.should eql 'Helsinki' }
163
+ it { subject.name.should eql 'Teeripuisto' }
164
+ it { subject.type.should eql 3 }
165
+ it { subject.coordinates[:kkj].x.should eql 2556686 }
166
+ it { subject.coordinates[:kkj].y.should eql 6682815 }
167
+ it { subject.coordinates[:wgs].longitude.should eql 25.02051 }
168
+ it { subject.coordinates[:wgs].latitude.should eql 60.2528 }
169
+ it { subject.to_s.should eql 'Teeripuisto' }
170
+ end
171
+
172
+ context "example 4" do
173
+ xml = parse_elem '<LOC name1="Otakaari" number="9" city="Espoo" />'
174
+ subject { Reittiopas::Location.parse xml }
175
+
176
+ it { subject.should be_a Reittiopas::Location }
177
+ it { subject.city.should eql 'Espoo' }
178
+ it { subject.name.should eql 'Otakaari' }
179
+ it { subject.number.should eql 9 }
180
+ it { subject.should_not respond_to :address }
181
+ it { subject.should_not respond_to :code }
182
+ it { subject.type.should_not be }
183
+ it { subject.coordinates.should_not be }
184
+ it { subject.to_s.should eql 'Otakaari 9' }
185
+ end
186
+ end
187
+
188
+ context "when given LOC has 'poi' as category" do
189
+ xml = parse_elem '<LOC name1="Teeripuisto" number="" city="Helsinki" code="1700" address="" type="3" category="poi" x="2556686" y="6682815" lon="25.02051" lat="60.2528" />'
190
+ subject { Reittiopas::Location.parse xml }
191
+
192
+ it "should return a Location" do
193
+ should be_a Reittiopas::Location::PointOfInterest
194
+ end
195
+ end
196
+
197
+ context "when given LOC has 'stop' as category" do
198
+ xml = parse_elem '<LOC name1="Teeritie" number="" city="Vantaa" code="4810204" address="Korsontie" type="10" category="stop" x="2559002" y="6694007" lon="25.06559" lat="60.35291" />'
199
+ subject { Reittiopas::Location.parse xml }
200
+
201
+ it "should return a Stop" do
202
+ should be_a Reittiopas::Location::Stop
203
+ end
204
+ end
205
+
206
+ context "when given LOC has 'street' as category" do
207
+ xml = parse_elem '<LOC name1="Kahisevantie" number="2" city="Espoo" code="" address="" type="900" category="street" x="2541494" y="6680344" lon="24.74568" lat="60.23245"/>'
208
+ subject { Reittiopas::Location.parse xml }
209
+
210
+ it "should return a Street" do
211
+ should be_a Reittiopas::Location::Street
212
+ end
213
+ end
214
+ end
215
+ end
216
+
217
+ describe Reittiopas::Location::PointOfInterest do
218
+ it { should respond_to :code }
219
+ end
220
+
221
+ describe Reittiopas::Location::Stop do
222
+ it { should respond_to :address }
223
+ it { should respond_to :code }
224
+ end
225
+
226
+ describe Reittiopas::Location::Street do
227
+ it { should respond_to :number }
228
+ it { should_not respond_to :code }
229
+ end
230
+
231
+ describe Reittiopas::Location::Coordinates::KKJ do
232
+ subject { Reittiopas::Location::Coordinates::KKJ.new(:x => 2541494, :y => 6680344) }
233
+
234
+ it { should respond_to :x }
235
+ it { should respond_to :y }
236
+ end
237
+
238
+ describe Reittiopas::Location::Coordinates::WGS do
239
+ subject { Reittiopas::Location::Coordinates::WGS.new(:lon => 24.74568, :lat => 60.23245) }
240
+
241
+ it { should respond_to :latitude }
242
+ it { should respond_to :longitude }
243
+
244
+ it { subject.to_s.should eql '60.23245, 24.74568' }
245
+ end
@@ -0,0 +1,4 @@
1
+ --colour
2
+ --format specdoc
3
+ --loadby mtime
4
+ --reverse
@@ -0,0 +1,19 @@
1
+ begin
2
+ require 'spec'
3
+ rescue LoadError
4
+ require 'rubygems' unless ENV['NO_RUBYGEMS']
5
+ gem 'rspec'
6
+ require 'spec'
7
+ end
8
+
9
+ $:.unshift(File.dirname(__FILE__) + '/../lib')
10
+ require 'reittiopas'
11
+
12
+ require 'webmock/rspec'
13
+ include WebMock
14
+
15
+ BASE_URI = "http://api.reittiopas.fi/public-ytv/fi/api/"
16
+
17
+ def parse_elem(xml)
18
+ Nokogiri::XML(xml).children[0]
19
+ end
@@ -0,0 +1,38 @@
1
+ begin
2
+ require 'spec'
3
+ rescue LoadError
4
+ require 'rubygems' unless ENV['NO_RUBYGEMS']
5
+ require 'spec'
6
+ end
7
+ begin
8
+ require 'spec/rake/spectask'
9
+ rescue LoadError
10
+ puts <<-EOS
11
+ To use rspec for testing you must install rspec gem:
12
+ gem install rspec
13
+ EOS
14
+ exit(0)
15
+ end
16
+
17
+ desc "Run the specs under spec/models"
18
+ Spec::Rake::SpecTask.new do |t|
19
+ t.spec_opts = ['--options', "spec/spec.opts"]
20
+ t.spec_files = FileList['spec/**/*_spec.rb']
21
+ end
22
+
23
+ namespace :spec do
24
+ desc "Run all examples with RCov"
25
+ Spec::Rake::SpecTask.new(:rcov) do |t|
26
+ t.spec_files = FileList['spec/**/*_spec.rb']
27
+ t.rcov = true
28
+ t.rcov_opts = [
29
+ '--exclude', 'spec'
30
+ ]
31
+ end
32
+
33
+ desc "Browse the code coverage report."
34
+ task :browse => "spec:rcov" do
35
+ require "launchy"
36
+ Launchy::Browser.run("coverage/index.html")
37
+ end
38
+ end
metadata ADDED
@@ -0,0 +1,114 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: reittiopas
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 0
8
+ - 1
9
+ version: 0.0.1
10
+ platform: ruby
11
+ authors:
12
+ - Raine Virta
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2010-04-05 00:00:00 +03:00
18
+ default_executable:
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: webmock
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ">="
26
+ - !ruby/object:Gem::Version
27
+ segments:
28
+ - 0
29
+ version: "0"
30
+ type: :development
31
+ version_requirements: *id001
32
+ - !ruby/object:Gem::Dependency
33
+ name: hoe
34
+ prerelease: false
35
+ requirement: &id002 !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ">="
38
+ - !ruby/object:Gem::Version
39
+ segments:
40
+ - 2
41
+ - 6
42
+ - 0
43
+ version: 2.6.0
44
+ type: :development
45
+ version_requirements: *id002
46
+ description: |-
47
+ Reittiopas is a Ruby library for accessing the {Reittiopas Developer API}[http://developer.reittiopas.fi/pages/fi/reittiopas-api.php].
48
+
49
+ Requires an account to the service that can be requested through {the account request page}[http://developer.reittiopas.fi/pages/fi/accountrequest.php].
50
+ email:
51
+ - raine.virta@gmail.com
52
+ executables: []
53
+
54
+ extensions: []
55
+
56
+ extra_rdoc_files:
57
+ - History.txt
58
+ - Manifest.txt
59
+ - README.rdoc
60
+ files:
61
+ - History.txt
62
+ - Manifest.txt
63
+ - README.rdoc
64
+ - Rakefile
65
+ - deps.rip
66
+ - lib/reittiopas.rb
67
+ - lib/reittiopas/coordinates.rb
68
+ - lib/reittiopas/geocoding.rb
69
+ - lib/reittiopas/http.rb
70
+ - lib/reittiopas/location.rb
71
+ - lib/reittiopas/reittiopas.rb
72
+ - lib/reittiopas/utils.rb
73
+ - script/console
74
+ - script/destroy
75
+ - script/generate
76
+ - spec/fixtures/key.xml
77
+ - spec/fixtures/reverse_geocoding.xml
78
+ - spec/reittiopas_spec.rb
79
+ - spec/spec.opts
80
+ - spec/spec_helper.rb
81
+ - tasks/rspec.rake
82
+ has_rdoc: true
83
+ homepage: http://github.com/raneksi/reittiopas
84
+ licenses: []
85
+
86
+ post_install_message:
87
+ rdoc_options:
88
+ - --main
89
+ - README.rdoc
90
+ require_paths:
91
+ - lib
92
+ required_ruby_version: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ segments:
97
+ - 0
98
+ version: "0"
99
+ required_rubygems_version: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ segments:
104
+ - 0
105
+ version: "0"
106
+ requirements: []
107
+
108
+ rubyforge_project: reittiopas
109
+ rubygems_version: 1.3.6
110
+ signing_key:
111
+ specification_version: 3
112
+ summary: Reittiopas is a Ruby library for accessing the {Reittiopas Developer API}[http://developer.reittiopas.fi/pages/fi/reittiopas-api.php]
113
+ test_files: []
114
+