citibike 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.
- data/.gitignore +19 -0
- data/.rspec +4 -0
- data/.travis.yml +4 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +59 -0
- data/LICENSE +20 -0
- data/LICENSE.txt +22 -0
- data/README.md +121 -0
- data/Rakefile +6 -0
- data/citibike.gemspec +31 -0
- data/lib/citibike.rb +20 -0
- data/lib/citibike/api.rb +82 -0
- data/lib/citibike/apis/branch.rb +11 -0
- data/lib/citibike/apis/helmet.rb +11 -0
- data/lib/citibike/apis/station.rb +83 -0
- data/lib/citibike/client.rb +104 -0
- data/lib/citibike/connection.rb +85 -0
- data/lib/citibike/response.rb +119 -0
- data/lib/citibike/responses/branch.rb +31 -0
- data/lib/citibike/responses/helmet.rb +18 -0
- data/lib/citibike/responses/station.rb +18 -0
- data/lib/citibike/version.rb +5 -0
- data/spec/lib/apis/station_spec.rb +48 -0
- data/spec/lib/citibike_spec.rb +15 -0
- data/spec/lib/client_spec.rb +106 -0
- data/spec/lib/connection_spec.rb +68 -0
- data/spec/lib/response_spec.rb +90 -0
- data/spec/spec_helper.rb +20 -0
- metadata +232 -0
@@ -0,0 +1,106 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Citibike::Client do
|
4
|
+
context "Class Methods" do
|
5
|
+
|
6
|
+
around(:each) do |example|
|
7
|
+
VCR.use_cassette(:client_class, record: :new_episodes) do
|
8
|
+
example.run
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
context ".stations" do
|
13
|
+
it "should load a list of stations" do
|
14
|
+
stats = Citibike::Client.stations
|
15
|
+
|
16
|
+
stats.first.should be_a(Citibike::Station)
|
17
|
+
stats.first.should respond_to(:lat)
|
18
|
+
stats.first.should respond_to(:long)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
context ".helmets" do
|
23
|
+
it "should load a list of helmets" do
|
24
|
+
helms = Citibike::Client.helmets
|
25
|
+
|
26
|
+
helms.first.should be_a(Citibike::Helmet)
|
27
|
+
helms.first.latitude.should_not be_nil
|
28
|
+
helms.first.longitude.should_not be_nil
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
context ".branches" do
|
33
|
+
it "should load a list of branches" do
|
34
|
+
branches = Citibike::Client.branches
|
35
|
+
|
36
|
+
branches.should be_a(Citibike::Responses::Branch)
|
37
|
+
branches.first.should be_a(Citibike::Branch)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
|
43
|
+
context "Instance Methods" do
|
44
|
+
around(:each) do |example|
|
45
|
+
VCR.use_cassette(:client_instance, record: :new_episodes) do
|
46
|
+
example.run
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
let(:client) { Citibike::Client.new }
|
51
|
+
|
52
|
+
let(:unwrapped) { Citibike::Client.new(unwrapped: true)}
|
53
|
+
|
54
|
+
context "#stations" do
|
55
|
+
it "should get back a response object by default" do
|
56
|
+
stats = client.stations
|
57
|
+
|
58
|
+
stats.should be_a(Citibike::Responses::Station)
|
59
|
+
stats.first.should be_a(Citibike::Station)
|
60
|
+
end
|
61
|
+
|
62
|
+
it "should get back an array when unwrapped" do
|
63
|
+
stats = unwrapped.stations
|
64
|
+
|
65
|
+
stats.should be_a(Hash)
|
66
|
+
stats['results'].first.should be_a(Hash)
|
67
|
+
stats['results'].first['id'].should_not be_nil
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
context "#helmets" do
|
72
|
+
it "should get back a response object by default" do
|
73
|
+
stats = client.helmets
|
74
|
+
|
75
|
+
stats.should be_a(Citibike::Responses::Helmet)
|
76
|
+
stats.first.should be_a(Citibike::Helmet)
|
77
|
+
end
|
78
|
+
|
79
|
+
it "should get back an array when unwrapped" do
|
80
|
+
stats = unwrapped.helmets
|
81
|
+
|
82
|
+
stats.should be_a(Hash)
|
83
|
+
stats['results'].first.should be_a(Hash)
|
84
|
+
stats['results'].first['id'].should_not be_nil
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
context "#branches" do
|
89
|
+
it "should get back a response object by default" do
|
90
|
+
stats = client.branches
|
91
|
+
|
92
|
+
stats.should be_a(Citibike::Responses::Branch)
|
93
|
+
stats.first.should be_a(Citibike::Branch)
|
94
|
+
end
|
95
|
+
|
96
|
+
it "should get back an array when unwrapped" do
|
97
|
+
stats = unwrapped.branches
|
98
|
+
|
99
|
+
stats.should be_a(Hash)
|
100
|
+
stats['results'].first.should be_a(Hash)
|
101
|
+
stats['results'].first['id'].should_not be_nil
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
end
|
106
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Citibike::Connection do
|
4
|
+
|
5
|
+
let(:stubs) do
|
6
|
+
Faraday::Adapter::Test::Stubs.new do |stub|
|
7
|
+
stub.get('/test_path.json') { [200, {}, {:a => :b}.to_json] }
|
8
|
+
stub.get('/test_no_format') { [200, {}, {:c => :d}.to_json] }
|
9
|
+
stub.get('/provider_format.xsl') { [200, {}, {:e => :f}.to_json] }
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
it "should append the default format (.json) and parse the json" do
|
14
|
+
conn = Citibike::Connection.new(
|
15
|
+
:adapter => :test,
|
16
|
+
:stubs => stubs,
|
17
|
+
:test => true
|
18
|
+
)
|
19
|
+
result = conn.request(:get, '/test_path')
|
20
|
+
result.should be_a(Hash)
|
21
|
+
|
22
|
+
result['a'].should eql('b')
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should not append the format if format_path is false" do
|
26
|
+
conn = Citibike::Connection.new(
|
27
|
+
:adapter => :test,
|
28
|
+
:stubs => stubs,
|
29
|
+
:format_path => false,
|
30
|
+
:format => :xml,
|
31
|
+
:test => true
|
32
|
+
)
|
33
|
+
|
34
|
+
result = conn.request(:get, '/test_no_format')
|
35
|
+
result.should be_a(Hash)
|
36
|
+
|
37
|
+
result['c'].should eql('d')
|
38
|
+
end
|
39
|
+
|
40
|
+
it "should not append the format if one is already provided" do
|
41
|
+
conn = Citibike::Connection.new(
|
42
|
+
:adapter => :test,
|
43
|
+
:stubs => stubs,
|
44
|
+
:test => true
|
45
|
+
)
|
46
|
+
|
47
|
+
result = conn.request(:get, '/provider_format.xsl')
|
48
|
+
result.should be_a(Hash)
|
49
|
+
|
50
|
+
result['e'].should eql('f')
|
51
|
+
end
|
52
|
+
|
53
|
+
it "should not parse the json if raw is true" do
|
54
|
+
conn = Citibike::Connection.new(
|
55
|
+
:adapter => :test,
|
56
|
+
:stubs => stubs,
|
57
|
+
:raw => true,
|
58
|
+
:test => true
|
59
|
+
)
|
60
|
+
|
61
|
+
result = conn.request(:get, '/test_path')
|
62
|
+
result.should be_a(String)
|
63
|
+
|
64
|
+
result = JSON.parse(result)
|
65
|
+
result['a'].should eql('b')
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
@@ -0,0 +1,90 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "Responses" do
|
4
|
+
|
5
|
+
around(:each) do |example|
|
6
|
+
VCR.use_cassette(:responses, record: :new_episodes) do
|
7
|
+
example.run
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
# Currently only the superclass has actual methods so testing
|
12
|
+
# on just stations is sufficient
|
13
|
+
|
14
|
+
let(:stations) { Citibike::Client.stations }
|
15
|
+
|
16
|
+
it "should provide a success? method" do
|
17
|
+
stations.should be_a_success
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should parse last_update into a time" do
|
21
|
+
stations.last_update.should be_a(Time)
|
22
|
+
end
|
23
|
+
|
24
|
+
it "should be enumerable" do
|
25
|
+
ids = stations.collect(&:id)
|
26
|
+
|
27
|
+
ids.should be_a(Array)
|
28
|
+
ids.first.should be_a(Integer)
|
29
|
+
end
|
30
|
+
|
31
|
+
it "should be able to clone itself on a subset of its data" do
|
32
|
+
size = stations.size
|
33
|
+
actives = stations.select(&:active?)
|
34
|
+
actives.size.should_not eql(size)
|
35
|
+
|
36
|
+
stats2 = stations.clone_with(actives)
|
37
|
+
stats2.size.should eql(actives.size)
|
38
|
+
|
39
|
+
stats2.last_update.should eql(stations.last_update)
|
40
|
+
stats2.object_id.should_not eql(stations.object_id)
|
41
|
+
end
|
42
|
+
|
43
|
+
it "should be able to find another object by id" do
|
44
|
+
ids = stations.first.nearby_station_ids
|
45
|
+
|
46
|
+
stat = stations.find_by_id(ids.first)
|
47
|
+
stat.id.should eql(ids.first)
|
48
|
+
stat.should be_a(Citibike::Station)
|
49
|
+
end
|
50
|
+
|
51
|
+
it "should be able to search for multiple ids at once" do
|
52
|
+
ids = stations[1].nearby_station_ids
|
53
|
+
|
54
|
+
stats = stations.find_by_ids(*ids)
|
55
|
+
stats.collect(&:id).should eql(ids)
|
56
|
+
end
|
57
|
+
|
58
|
+
# This conveniently tests that the code for computing
|
59
|
+
# distance as the crow flies from lat/long works correctly
|
60
|
+
context "Geolocating" do
|
61
|
+
|
62
|
+
it "should be able to find stations in a given radius" do
|
63
|
+
stat = stations.first
|
64
|
+
dists = stat.nearby_station_ids.collect do |i|
|
65
|
+
stat.distance_to_nearby(i)
|
66
|
+
end
|
67
|
+
|
68
|
+
res = stations.all_within(stat.lat, stat.long, dists.max + 0.001)
|
69
|
+
res.count.should eql(stat.nearby_station_ids.size + 1)
|
70
|
+
([stat.id] + stat.nearby_station_ids).sort.should eql(
|
71
|
+
res.collect(&:id).sort
|
72
|
+
)
|
73
|
+
|
74
|
+
end
|
75
|
+
|
76
|
+
it "should be able to find all stations within a given radius of another
|
77
|
+
station" do
|
78
|
+
stat = stations[1]
|
79
|
+
dists = stat.nearby_station_ids.collect do |i|
|
80
|
+
stat.distance_to_nearby(i)
|
81
|
+
end
|
82
|
+
|
83
|
+
res = stations.all_near(stat, dists.max + 0.001)
|
84
|
+
res.count.should eql(stat.nearby_station_ids.size)
|
85
|
+
stat.nearby_station_ids.sort.should eql(res.collect(&:id).sort)
|
86
|
+
end
|
87
|
+
|
88
|
+
end
|
89
|
+
|
90
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'citibike'
|
2
|
+
|
3
|
+
require 'rspec'
|
4
|
+
require 'rspec/autorun'
|
5
|
+
|
6
|
+
require 'vcr'
|
7
|
+
require 'yajl'
|
8
|
+
|
9
|
+
require 'coveralls'
|
10
|
+
Coveralls.wear!
|
11
|
+
|
12
|
+
RSpec.configure do |config|
|
13
|
+
config.mock_with :mocha
|
14
|
+
end
|
15
|
+
|
16
|
+
VCR.configure do |c|
|
17
|
+
c.cassette_library_dir = 'spec/cassettes'
|
18
|
+
c.hook_into :faraday
|
19
|
+
c.allow_http_connections_when_no_cassette = true
|
20
|
+
end
|
metadata
ADDED
@@ -0,0 +1,232 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: citibike
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Ethan Langevin
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-07-23 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: bundler
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '1.3'
|
22
|
+
type: :development
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '1.3'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: rake
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
type: :development
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: rspec
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ! '>='
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
54
|
+
type: :development
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: coveralls
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ! '>='
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
70
|
+
type: :development
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
78
|
+
- !ruby/object:Gem::Dependency
|
79
|
+
name: vcr
|
80
|
+
requirement: !ruby/object:Gem::Requirement
|
81
|
+
none: false
|
82
|
+
requirements:
|
83
|
+
- - ! '>='
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: '0'
|
86
|
+
type: :development
|
87
|
+
prerelease: false
|
88
|
+
version_requirements: !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
90
|
+
requirements:
|
91
|
+
- - ! '>='
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '0'
|
94
|
+
- !ruby/object:Gem::Dependency
|
95
|
+
name: mocha
|
96
|
+
requirement: !ruby/object:Gem::Requirement
|
97
|
+
none: false
|
98
|
+
requirements:
|
99
|
+
- - ! '>='
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
version: '0'
|
102
|
+
type: :development
|
103
|
+
prerelease: false
|
104
|
+
version_requirements: !ruby/object:Gem::Requirement
|
105
|
+
none: false
|
106
|
+
requirements:
|
107
|
+
- - ! '>='
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: '0'
|
110
|
+
- !ruby/object:Gem::Dependency
|
111
|
+
name: faraday
|
112
|
+
requirement: !ruby/object:Gem::Requirement
|
113
|
+
none: false
|
114
|
+
requirements:
|
115
|
+
- - ! '>='
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
type: :runtime
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
none: false
|
122
|
+
requirements:
|
123
|
+
- - ! '>='
|
124
|
+
- !ruby/object:Gem::Version
|
125
|
+
version: '0'
|
126
|
+
- !ruby/object:Gem::Dependency
|
127
|
+
name: faraday_middleware
|
128
|
+
requirement: !ruby/object:Gem::Requirement
|
129
|
+
none: false
|
130
|
+
requirements:
|
131
|
+
- - ! '>='
|
132
|
+
- !ruby/object:Gem::Version
|
133
|
+
version: '0'
|
134
|
+
type: :runtime
|
135
|
+
prerelease: false
|
136
|
+
version_requirements: !ruby/object:Gem::Requirement
|
137
|
+
none: false
|
138
|
+
requirements:
|
139
|
+
- - ! '>='
|
140
|
+
- !ruby/object:Gem::Version
|
141
|
+
version: '0'
|
142
|
+
- !ruby/object:Gem::Dependency
|
143
|
+
name: yajl-ruby
|
144
|
+
requirement: !ruby/object:Gem::Requirement
|
145
|
+
none: false
|
146
|
+
requirements:
|
147
|
+
- - ! '>='
|
148
|
+
- !ruby/object:Gem::Version
|
149
|
+
version: '0'
|
150
|
+
type: :runtime
|
151
|
+
prerelease: false
|
152
|
+
version_requirements: !ruby/object:Gem::Requirement
|
153
|
+
none: false
|
154
|
+
requirements:
|
155
|
+
- - ! '>='
|
156
|
+
- !ruby/object:Gem::Version
|
157
|
+
version: '0'
|
158
|
+
description: Client for the unofficial Citibike API in NYC
|
159
|
+
email:
|
160
|
+
- ejl6266@gmail.com
|
161
|
+
executables: []
|
162
|
+
extensions: []
|
163
|
+
extra_rdoc_files: []
|
164
|
+
files:
|
165
|
+
- .gitignore
|
166
|
+
- .rspec
|
167
|
+
- .travis.yml
|
168
|
+
- Gemfile
|
169
|
+
- Gemfile.lock
|
170
|
+
- LICENSE
|
171
|
+
- LICENSE.txt
|
172
|
+
- README.md
|
173
|
+
- Rakefile
|
174
|
+
- citibike.gemspec
|
175
|
+
- lib/citibike.rb
|
176
|
+
- lib/citibike/api.rb
|
177
|
+
- lib/citibike/apis/branch.rb
|
178
|
+
- lib/citibike/apis/helmet.rb
|
179
|
+
- lib/citibike/apis/station.rb
|
180
|
+
- lib/citibike/client.rb
|
181
|
+
- lib/citibike/connection.rb
|
182
|
+
- lib/citibike/response.rb
|
183
|
+
- lib/citibike/responses/branch.rb
|
184
|
+
- lib/citibike/responses/helmet.rb
|
185
|
+
- lib/citibike/responses/station.rb
|
186
|
+
- lib/citibike/version.rb
|
187
|
+
- spec/cassettes/client_class.yml
|
188
|
+
- spec/lib/apis/station_spec.rb
|
189
|
+
- spec/lib/citibike_spec.rb
|
190
|
+
- spec/lib/client_spec.rb
|
191
|
+
- spec/lib/connection_spec.rb
|
192
|
+
- spec/lib/response_spec.rb
|
193
|
+
- spec/spec_helper.rb
|
194
|
+
homepage: http://github.com/ejlangev/citibike
|
195
|
+
licenses:
|
196
|
+
- MIT
|
197
|
+
post_install_message:
|
198
|
+
rdoc_options: []
|
199
|
+
require_paths:
|
200
|
+
- lib
|
201
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
202
|
+
none: false
|
203
|
+
requirements:
|
204
|
+
- - ! '>='
|
205
|
+
- !ruby/object:Gem::Version
|
206
|
+
version: '0'
|
207
|
+
segments:
|
208
|
+
- 0
|
209
|
+
hash: 1917498095343501861
|
210
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
211
|
+
none: false
|
212
|
+
requirements:
|
213
|
+
- - ! '>='
|
214
|
+
- !ruby/object:Gem::Version
|
215
|
+
version: '0'
|
216
|
+
segments:
|
217
|
+
- 0
|
218
|
+
hash: 1917498095343501861
|
219
|
+
requirements: []
|
220
|
+
rubyforge_project:
|
221
|
+
rubygems_version: 1.8.23
|
222
|
+
signing_key:
|
223
|
+
specification_version: 3
|
224
|
+
summary: Provides an interface for interacting with Citibike NYC data
|
225
|
+
test_files:
|
226
|
+
- spec/cassettes/client_class.yml
|
227
|
+
- spec/lib/apis/station_spec.rb
|
228
|
+
- spec/lib/citibike_spec.rb
|
229
|
+
- spec/lib/client_spec.rb
|
230
|
+
- spec/lib/connection_spec.rb
|
231
|
+
- spec/lib/response_spec.rb
|
232
|
+
- spec/spec_helper.rb
|