reittiopas 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/History.txt CHANGED
@@ -1,4 +1,4 @@
1
- === 0.0.1 2010-03-29
1
+ === 0.0.1 2010-04-05
2
2
 
3
3
  * 1 major enhancement:
4
4
  * Initial release
data/Manifest.txt CHANGED
@@ -2,9 +2,9 @@ History.txt
2
2
  Manifest.txt
3
3
  README.rdoc
4
4
  Rakefile
5
- deps.rip
6
5
  lib/reittiopas.rb
7
6
  lib/reittiopas/coordinates.rb
7
+ lib/reittiopas/exceptions.rb
8
8
  lib/reittiopas/geocoding.rb
9
9
  lib/reittiopas/http.rb
10
10
  lib/reittiopas/location.rb
@@ -14,8 +14,10 @@ script/console
14
14
  script/destroy
15
15
  script/generate
16
16
  spec/fixtures/key.xml
17
+ spec/fixtures/no_access
17
18
  spec/fixtures/reverse_geocoding.xml
18
19
  spec/reittiopas_spec.rb
19
20
  spec/spec.opts
20
21
  spec/spec_helper.rb
22
+ tasks/rdoc.rake
21
23
  tasks/rspec.rake
data/README.rdoc CHANGED
@@ -1,6 +1,7 @@
1
1
  = Reittiopas
2
2
 
3
3
  * {Documentation at Github}[http://raneksi.github.com/reittiopas/]
4
+ * {Specifications}[http://raneksi.github.com/reittiopas/specdoc]
4
5
 
5
6
  == DESCRIPTION:
6
7
 
@@ -27,11 +28,27 @@ Search for a location by KKJ[http://fi.wikipedia.org/wiki/Kartastokoordinaattij%
27
28
  puts "#{location}, #{location.city}"
28
29
  Otakaari 9, Espoo
29
30
 
31
+ == INSTALLATION:
32
+
33
+ gem install reittiopas
34
+
35
+ or for the latest git:
36
+
37
+ git clone git://github.com/raneksi/reittiopas.git
38
+ cd reittiopas
39
+ rake newb
40
+ rake install_gem
41
+
30
42
  == REQUIREMENTS:
31
43
 
32
44
  * Nokogiri[http://nokogiri.org/]
33
45
  * Addressable[http://github.com/sporkmonger/addressable]
34
46
 
47
+ == TODO:
48
+
49
+ * Support for determining the closest stop within radius
50
+ * Routing
51
+
35
52
  == LICENSE:
36
53
 
37
54
  (The MIT License)
data/Rakefile CHANGED
@@ -2,33 +2,26 @@ require 'rubygems'
2
2
  gem 'hoe', '>= 2.1.0'
3
3
  require 'hoe'
4
4
  require 'fileutils'
5
- require './lib/reittiopas'
6
5
 
7
6
  Hoe.plugin :newgem
8
7
 
9
8
  $hoe = Hoe.spec 'reittiopas' do
10
9
  developer 'Raine Virta', 'raine.virta@gmail.com'
11
- self.rubyforge_name = self.name
10
+ self.rubyforge_name = self.name
12
11
 
13
12
  %w{ addressable nokogiri }.each do |dep|
14
- self.extra_dev_deps << [dep, '>= 0']
13
+ self.extra_deps << [dep, '>= 0']
15
14
  end
16
15
 
17
16
  self.url = "http://github.com/raneksi/reittiopas"
18
- self.extra_dev_deps = [['webmock', ">= 0"]]
17
+ self.extra_dev_deps = [
18
+ ['webmock', ">= 0.9.1"],
19
+ ['rspec', ">= 0"],
20
+ ['darkfish-rdoc', ">= 0"]
21
+ ]
19
22
  self.readme_file = "README.rdoc"
20
23
  self.extra_rdoc_files = FileList['*.rdoc']
21
24
  end
22
25
 
23
26
  require 'newgem/tasks'
24
27
  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
data/lib/reittiopas.rb CHANGED
@@ -1,13 +1,13 @@
1
- $:.unshift(File.dirname(__FILE__)) unless
2
- $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
3
-
4
- require 'rubygems'
5
1
  require 'uri'
6
2
  require 'cgi'
7
3
  require 'net/http'
8
4
  require 'nokogiri'
9
5
  require 'addressable/uri'
10
6
 
7
+ $:.unshift(File.dirname(__FILE__)) unless
8
+ $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
9
+
10
+ require 'reittiopas/exceptions'
11
11
  require 'reittiopas/utils'
12
12
  require 'reittiopas/coordinates'
13
13
  require 'reittiopas/location'
@@ -17,7 +17,7 @@ require 'reittiopas/http'
17
17
 
18
18
  class Reittiopas
19
19
  # The version of Reittiopas you are using.
20
- VERSION = "0.0.1"
20
+ VERSION = "0.0.2"
21
21
  end
22
22
 
23
23
  # Shorter way for Reittiopas instance creation.
@@ -0,0 +1,4 @@
1
+ class Reittiopas
2
+ class AccessError < ::StandardError
3
+ end
4
+ end
@@ -6,9 +6,11 @@ module Geocoding
6
6
 
7
7
  # Send a geocode location query to the API.
8
8
  # Both geocoding, and reverse geocoding data is accessed through this method.
9
- #
10
9
  # Returns results as an array containing Reittiopas::Location objects.
11
10
  #
11
+ # [opts] Either a keyword string, or a hash containing KKJ coordinates
12
+ # presented as rectangular grid coordinates.
13
+ #
12
14
  # === Examples:
13
15
  # * Search for location by keyword _tee_.
14
16
  # reittiopas.location('tee')
@@ -20,6 +22,7 @@ module Geocoding
20
22
  params = if opts.is_a? String
21
23
  {:key => opts}
22
24
  elsif opts.is_a? Hash
25
+ opts.assert_required_and_valid_keys :x, :y
23
26
  opts
24
27
  end
25
28
 
@@ -28,6 +31,8 @@ module Geocoding
28
31
 
29
32
  private
30
33
  # Parse XML received from a geocoding API query.
34
+ #
35
+ # [xml] Raw XML received from API.
31
36
  def parse(xml, opts)
32
37
  doc = Nokogiri::XML(xml)
33
38
 
@@ -18,7 +18,8 @@ class HTTP
18
18
 
19
19
  # Create a new Reittiopas::HTTP object.
20
20
  #
21
- # +account+ should be a hash containing +:username+ and +:password+.
21
+ # [account] A hash containing the keys +:username+ and +:password+ with
22
+ # their respective values.
22
23
  def initialize(account)
23
24
  @api_uri = Addressable::URI.parse(API_BASE_URI)
24
25
  @api_uri.query_values = {:user => account[:username], :pass => account[:password]}
@@ -27,14 +28,23 @@ class HTTP
27
28
  # Send a GET request to the API with account details and +opts+ as query
28
29
  # parameters.
29
30
  #
30
- # * +opts+ A hash containing query parameters. Values are automatically
31
- # encoded by Addressable::URI.
31
+ # [opts] A hash containing query parameters. Values are automatically
32
+ # encoded by Addressable::URI.
32
33
  def get(opts)
33
34
  raise ArgumentError if opts.empty?
34
35
  uri = @api_uri.dup
35
36
  opts.merge!(opts){ |k,ov| ov.to_s } # Coordinates to string
36
37
  uri.query_values = uri.query_values.merge(opts)
37
- return Net::HTTP.get(uri)
38
+
39
+ # TODO ugly workaround until addressable's author updates the game
40
+ body = Net::HTTP.get(URI.parse(uri.to_s))
41
+
42
+ # API responses with 200 OK in case of invalid account, so...
43
+ if body =~ /No rights to access API./
44
+ raise AccessError, 'Most likely due to invalid account details'
45
+ end
46
+
47
+ body
38
48
  end
39
49
  end
40
50
  end
@@ -3,13 +3,15 @@
3
3
  #
4
4
  class Reittiopas
5
5
  include Geocoding
6
-
6
+
7
7
  # Instantiate a Reittiopas object.
8
8
  #
9
- # +account+ should be a hash containing +:username+ and +:password+.
9
+ # [account] A hash containing the keys +:username+ and +:password+ with
10
+ # their respective values.
10
11
  #
11
12
  # Reittiopas.new(:username => 'exampleuser', :password => 'lolcat')
12
13
  def initialize(account)
14
+ account.assert_required_and_valid_keys :username, :password
13
15
  @http = Reittiopas::HTTP.new(account)
14
16
  end
15
17
  end
@@ -9,3 +9,34 @@ class Element
9
9
  end
10
10
  end
11
11
  end
12
+
13
+ class Hash
14
+ # Raise ArgumentError if the hash has keys other than +keys+.
15
+ def assert_valid_keys(*valid_keys)
16
+ unknown_keys = keys - [valid_keys].flatten
17
+ raise(ArgumentError, "Unknown key(s): #{unknown_keys.join(", ")}") unless unknown_keys.empty?
18
+ end
19
+
20
+ # Raise ArgumentError if the hash is missing required keys.
21
+ def assert_required_keys(*required_keys)
22
+ missing_keys = [required_keys].flatten - keys
23
+ raise(ArgumentError, "Missing required key(s) in the argument hash: #{missing_keys.join(", ")}") unless missing_keys.empty?
24
+ end
25
+
26
+ # Both assert_valid_keys and assert_required_keys combined.
27
+ #
28
+ # Expect certain keys and none else.
29
+ def assert_required_and_valid_keys(*keys)
30
+ assert_valid_keys(keys)
31
+ assert_required_keys(keys)
32
+ end
33
+
34
+ def assert_valid_values(hash)
35
+ self.each do |key, value|
36
+ next unless hash[key]
37
+ unless value.to_s =~ hash[key]
38
+ raise(ArgumentError, "Invalid value for #{key}: #{value.inspect}")
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,8 @@
1
+ HTTP/1.1 200 OK
2
+ Date: Wed, 07 Apr 2010 13:33:08 GMT
3
+ Server: Apache/2
4
+ X-Powered-By: PHP/5.2.6-1+lenny8
5
+ Content-Length: 27
6
+ Content-Type: text/html; charset=iso-8859-1
7
+
8
+ No rights to access API.<P>
@@ -15,6 +15,20 @@ end
15
15
  describe Reittiopas do
16
16
  before { @account = {:username => 'foo', :password => 'bar'} }
17
17
 
18
+ context "when initializing with missing arguments" do
19
+ it "should raise ArgumentError if password is missing" do
20
+ lambda do
21
+ Reittiopas.new(:username => 'foo')
22
+ end.should raise_error ArgumentError
23
+ end
24
+
25
+ it "should raise ArgumentError if username is missing" do
26
+ lambda do
27
+ Reittiopas.new(:password => 'foo')
28
+ end.should raise_error ArgumentError
29
+ end
30
+ end
31
+
18
32
  context "when initialized with an account" do
19
33
  subject { Reittiopas.new(@account) }
20
34
 
@@ -86,6 +100,17 @@ describe Reittiopas::HTTP do
86
100
  end
87
101
 
88
102
  describe "#get" do
103
+ context "when making a request with invalid account details" do
104
+ before do
105
+ no_access_response = File.open(File.dirname(__FILE__) + '/fixtures/no_access')
106
+ stub_request(:get, Regexp.new(BASE_URI)).to_return(no_access_response)
107
+ end
108
+
109
+ it "should raise AccessError" do
110
+ lambda { @http.get(:foo => 'bar') }.should raise_error(Reittiopas::AccessError)
111
+ end
112
+ end
113
+
89
114
  context "with empty hash as argument" do
90
115
  it { lambda { @http.get({}) }.should raise_error(ArgumentError) }
91
116
  end
@@ -240,6 +265,38 @@ describe Reittiopas::Location::Coordinates::WGS do
240
265
 
241
266
  it { should respond_to :latitude }
242
267
  it { should respond_to :longitude }
243
-
268
+
244
269
  it { subject.to_s.should eql '60.23245, 24.74568' }
245
270
  end
271
+
272
+ describe Hash do
273
+ describe "#assert_valid_keys" do
274
+ context "when invalid keys are found" do
275
+ it "should raise ArgumentError when invalid keys are found" do
276
+ lambda do
277
+ { :name => "Rob", :years => "28" }.assert_valid_keys :name, :age
278
+ end.should raise_error(ArgumentError, "Unknown key(s): years")
279
+ end
280
+ end
281
+ end
282
+
283
+ describe "#assert_required_keys" do
284
+ context "when required keys are missing" do
285
+ it "should raise ArgumentError" do
286
+ lambda do
287
+ { :name => "Rob", :years => "28" }.assert_required_keys :weight
288
+ end.should raise_error(ArgumentError, "Missing required key(s) in the argument hash: weight")
289
+ end
290
+ end
291
+ end
292
+
293
+ describe "#assert_required_and_valid_keys" do
294
+ context "when invalid keys are found and required keys are missing" do
295
+ it "should raise ArgumentError" do
296
+ lambda do
297
+ { :name => "Rob"}.assert_required_and_valid_keys :weight
298
+ end.should raise_error(ArgumentError)
299
+ end
300
+ end
301
+ end
302
+ end
data/spec/spec_helper.rb CHANGED
@@ -16,4 +16,4 @@ BASE_URI = "http://api.reittiopas.fi/public-ytv/fi/api/"
16
16
 
17
17
  def parse_elem(xml)
18
18
  Nokogiri::XML(xml).children[0]
19
- end
19
+ end
data/tasks/rdoc.rake ADDED
@@ -0,0 +1,8 @@
1
+ namespace :docs do
2
+ desc "Publish rdoc to Github pages"
3
+ task :publish => "docs" do
4
+ sh 'cp doc/README_rdoc.html doc/index.html'
5
+ sh 'cp -R doc/* .gh_pages/'
6
+ sh 'cd .gh_pages; git add .; git commit -m "Update docs"; git push origin gh-pages'
7
+ end
8
+ end
data/tasks/rspec.rake CHANGED
@@ -29,10 +29,22 @@ namespace :spec do
29
29
  '--exclude', 'spec'
30
30
  ]
31
31
  end
32
-
32
+
33
33
  desc "Browse the code coverage report."
34
34
  task :browse => "spec:rcov" do
35
35
  require "launchy"
36
36
  Launchy::Browser.run("coverage/index.html")
37
37
  end
38
- end
38
+
39
+ desc "Generate HTML Specdocs for all specs"
40
+ Spec::Rake::SpecTask.new(:specdoc) do |t|
41
+ specdoc_path = File.expand_path(File.join(File.dirname(__FILE__), '..', 'specdoc'))
42
+ Dir.mkdir(specdoc_path) if !File.exist?(specdoc_path)
43
+
44
+ output_file = File.join(specdoc_path, 'index.html')
45
+ t.libs = %w[lib spec]
46
+ t.spec_files = FileList['spec/**/*_spec.rb']
47
+ t.spec_opts = ["--format", "\"html:#{output_file}\"", "--diff"]
48
+ t.fail_on_error = false
49
+ end
50
+ end
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 0
8
- - 1
9
- version: 0.0.1
8
+ - 2
9
+ version: 0.0.2
10
10
  platform: ruby
11
11
  authors:
12
12
  - Raine Virta
@@ -14,11 +14,11 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-04-05 00:00:00 +03:00
17
+ date: 2010-04-22 00:00:00 +03:00
18
18
  default_executable:
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
21
- name: webmock
21
+ name: addressable
22
22
  prerelease: false
23
23
  requirement: &id001 !ruby/object:Gem::Requirement
24
24
  requirements:
@@ -27,12 +27,62 @@ dependencies:
27
27
  segments:
28
28
  - 0
29
29
  version: "0"
30
- type: :development
30
+ type: :runtime
31
31
  version_requirements: *id001
32
32
  - !ruby/object:Gem::Dependency
33
- name: hoe
33
+ name: nokogiri
34
34
  prerelease: false
35
35
  requirement: &id002 !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ">="
38
+ - !ruby/object:Gem::Version
39
+ segments:
40
+ - 0
41
+ version: "0"
42
+ type: :runtime
43
+ version_requirements: *id002
44
+ - !ruby/object:Gem::Dependency
45
+ name: webmock
46
+ prerelease: false
47
+ requirement: &id003 !ruby/object:Gem::Requirement
48
+ requirements:
49
+ - - ">="
50
+ - !ruby/object:Gem::Version
51
+ segments:
52
+ - 0
53
+ - 9
54
+ - 1
55
+ version: 0.9.1
56
+ type: :development
57
+ version_requirements: *id003
58
+ - !ruby/object:Gem::Dependency
59
+ name: rspec
60
+ prerelease: false
61
+ requirement: &id004 !ruby/object:Gem::Requirement
62
+ requirements:
63
+ - - ">="
64
+ - !ruby/object:Gem::Version
65
+ segments:
66
+ - 0
67
+ version: "0"
68
+ type: :development
69
+ version_requirements: *id004
70
+ - !ruby/object:Gem::Dependency
71
+ name: darkfish-rdoc
72
+ prerelease: false
73
+ requirement: &id005 !ruby/object:Gem::Requirement
74
+ requirements:
75
+ - - ">="
76
+ - !ruby/object:Gem::Version
77
+ segments:
78
+ - 0
79
+ version: "0"
80
+ type: :development
81
+ version_requirements: *id005
82
+ - !ruby/object:Gem::Dependency
83
+ name: hoe
84
+ prerelease: false
85
+ requirement: &id006 !ruby/object:Gem::Requirement
36
86
  requirements:
37
87
  - - ">="
38
88
  - !ruby/object:Gem::Version
@@ -42,7 +92,7 @@ dependencies:
42
92
  - 0
43
93
  version: 2.6.0
44
94
  type: :development
45
- version_requirements: *id002
95
+ version_requirements: *id006
46
96
  description: |-
47
97
  Reittiopas is a Ruby library for accessing the {Reittiopas Developer API}[http://developer.reittiopas.fi/pages/fi/reittiopas-api.php].
48
98
 
@@ -62,9 +112,9 @@ files:
62
112
  - Manifest.txt
63
113
  - README.rdoc
64
114
  - Rakefile
65
- - deps.rip
66
115
  - lib/reittiopas.rb
67
116
  - lib/reittiopas/coordinates.rb
117
+ - lib/reittiopas/exceptions.rb
68
118
  - lib/reittiopas/geocoding.rb
69
119
  - lib/reittiopas/http.rb
70
120
  - lib/reittiopas/location.rb
@@ -74,10 +124,12 @@ files:
74
124
  - script/destroy
75
125
  - script/generate
76
126
  - spec/fixtures/key.xml
127
+ - spec/fixtures/no_access
77
128
  - spec/fixtures/reverse_geocoding.xml
78
129
  - spec/reittiopas_spec.rb
79
130
  - spec/spec.opts
80
131
  - spec/spec_helper.rb
132
+ - tasks/rdoc.rake
81
133
  - tasks/rspec.rake
82
134
  has_rdoc: true
83
135
  homepage: http://github.com/raneksi/reittiopas
data/deps.rip DELETED
@@ -1 +0,0 @@
1
- http://github.com/sporkmonger/addressable.git