metra_schedule 0.2.1 → 0.2.1.2
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +65 -5
- data/Rakefile +11 -2
- data/lib/metra.rb +1 -1
- data/lib/metra/cacher.rb +2 -1
- data/lib/metra/classmethods.rb +1 -1
- data/lib/metra/line.rb +81 -35
- data/lib/metra/parser.rb +1 -0
- data/lib/metra/train.rb +63 -2
- data/test/functional/test_all_filters.rb +22 -0
- data/test/integration/test_line_integration.rb +12 -0
- data/test/test_helper.rb +19 -0
- data/test/{test_cacher.rb → unit/test_cacher.rb} +3 -6
- data/test/{test_line.rb → unit/test_line.rb} +70 -11
- data/test/{test_metra.rb → unit/test_metra.rb} +1 -2
- data/test/{test_parser.rb → unit/test_parser.rb} +11 -3
- data/test/{test_stop.rb → unit/test_stop.rb} +1 -2
- data/test/unit/test_train.rb +154 -0
- metadata +11 -8
- data/test/test_train.rb +0 -65
data/README.rdoc
CHANGED
@@ -25,9 +25,7 @@ How to use metra_schedule
|
|
25
25
|
|
26
26
|
=== Setup
|
27
27
|
|
28
|
-
|
29
|
-
|
30
|
-
sudo gem install metra_schedule
|
28
|
+
gem install metra_schedule -s http://gemcutter.org
|
31
29
|
|
32
30
|
=== Using
|
33
31
|
|
@@ -47,11 +45,14 @@ Make sure you have the gemcutter repository on your gem list and:
|
|
47
45
|
line.inbound.saturday.from(:barrington).to(:ogilve).trains
|
48
46
|
|
49
47
|
# All sunday/holiday outbound trains that start at Arlington Heights after 12:30PM and stop at Park Ridge
|
50
|
-
line.outbound.holiday.from(:arlington_heights).at(Time.parse('12:30PM')).to(:park_ridge)
|
48
|
+
line.outbound.holiday.from(:arlington_heights).at(Time.parse('12:30PM')).to(:park_ridge).trains
|
49
|
+
|
50
|
+
# All inbound trains on December 30th 2009
|
51
|
+
line.inbound.on(Date.parse("December 30th 2009")).trains
|
51
52
|
|
52
53
|
= Trains
|
53
54
|
|
54
|
-
|
55
|
+
=== Instance variables:
|
55
56
|
|
56
57
|
train.train_num :: Metra train number.
|
57
58
|
train.stops :: An array of all Stop objects. Contains the stop name and what time the train will arrive at that stop
|
@@ -59,6 +60,65 @@ train.schedule :: Symbol representing the day the train runs. Either :weekday, :
|
|
59
60
|
train.direction :: Symbol representing the train direction. Either :inbound or :outbound
|
60
61
|
train.bike_limit :: Maximum number of bikes per train. nil if no limit.
|
61
62
|
|
63
|
+
=== Instance methods:
|
64
|
+
|
65
|
+
train.my_travel_time :: Travel time in minutes of your trip. Assumes you specified Line#from and Line#to when you built your query
|
66
|
+
train.print_my_travel_time :: Same as above, but in human readable form EG - "1 hour 2 minutes"
|
67
|
+
train.has_stop?(stop) :: Takes a station name symbol and determines whether this train has that stop
|
68
|
+
train.in_time?(station, time) :: Takes a station name symbol and time. Returns true if the time is before the time the train reaches that stop
|
69
|
+
|
70
|
+
|
71
|
+
= Stops
|
72
|
+
|
73
|
+
Stored inside each train.
|
74
|
+
|
75
|
+
=== Instance variables:
|
76
|
+
|
77
|
+
stop.station :: Symbol representing the station name
|
78
|
+
stop.time :: Time object with the time the train stops there
|
79
|
+
|
80
|
+
=== Instance methods:
|
81
|
+
|
82
|
+
stop.in_time?(time) :: True if time is less than stop.time
|
83
|
+
|
84
|
+
=== Class methods:
|
85
|
+
|
86
|
+
Stop.pretty_print(station) :: Converts the station symbol to something human readable - EG: :irving_park becomes "Irving Park"
|
87
|
+
|
88
|
+
= Lines
|
89
|
+
|
90
|
+
=== Instance variables:
|
91
|
+
|
92
|
+
line.line_key :: Symbol of the line name
|
93
|
+
line.name :: Human readable line name EG - "Union Pacific Northwest"
|
94
|
+
line.url :: Url that the parser scrapes from.
|
95
|
+
line.dir :: Symbol representing selected line direction. :outbound or :inbound. Set with Line#outbound Line#inbound or deduced using Line#from and Line#to or by current time of day using Line#deduce_direction_by_time
|
96
|
+
line.sched :: Symbol representing selected line schedule. :weekday, :saturday or :sunday. Set with Line#weekday, Line#saturday Line#sunday Line#on(date) or Line#deduce_schedule
|
97
|
+
line.start :: Symbol representing starting station name. EG - :clyborn. Set with Line#from
|
98
|
+
line.destination :: Symbol representing destanation station name. EG - :ogilve. Set with Line#to
|
99
|
+
line.time :: Time object representing the time you'd like to depart. Used to filter down lines. Set with Line#at
|
100
|
+
|
101
|
+
|
102
|
+
=== Instance methods:
|
103
|
+
|
104
|
+
line.load_schedule :: Load cached engine data from Marshaled cache dir (~/.metra_schedule) or if not available, fetch from the Metra website, parse and cache it
|
105
|
+
line.trains :: Takes in all the other parameters you specified and returns only the trains that meet the criteria you specfied
|
106
|
+
line.from(station) :: Set your starting station
|
107
|
+
line.to(station) :: Set your destination station
|
108
|
+
line.direction(dir) :: Set the line direction. :outbound or :inbound
|
109
|
+
line.outbound :: Same as line.direction(:outbound)
|
110
|
+
line.inbound :: Same as line.direction(:inbound)
|
111
|
+
line.deduce_direction :: Infers line direction if you specified Line#from and Line#to
|
112
|
+
line.deduce_direction_by_time :: Infers line direction based on the system clocks time of day. Before noon it sets to inbound, after noon it assumes outbound
|
113
|
+
line.schedule(sched) :: Sets the line schedule. Either :weekday :saturday or :sunday
|
114
|
+
line.weekday :: Same as line.direction(:weekday)
|
115
|
+
line.saturday :: Same as line.direction(:saturday)
|
116
|
+
line.sunday :: Same as line.direction(:sunday)
|
117
|
+
line.holiday :: Same as line.direction(:sunday)
|
118
|
+
line.on(date) :: Sets schedule using the date you specified
|
119
|
+
line.deduce_schedule :: Same as on(Date.today)
|
120
|
+
line.at(time) :: Sets line time. Specifying this will only display trains that appear at your starting station (specified with Line#from) before the given time
|
121
|
+
|
62
122
|
= Line Data
|
63
123
|
|
64
124
|
Current supported lines:
|
data/Rakefile
CHANGED
@@ -4,11 +4,20 @@ require 'rake/testtask'
|
|
4
4
|
task :default => [:test]
|
5
5
|
|
6
6
|
desc "Run unit tests (functionals fail on win32)"
|
7
|
-
task :test => [:test_units]
|
7
|
+
task :test => [:test_units, :test_functionals]
|
8
8
|
|
9
9
|
desc "Run just the unit tests"
|
10
10
|
Rake::TestTask.new(:test_units) do |t|
|
11
|
-
t.test_files = FileList['test/test*.rb']
|
11
|
+
t.test_files = FileList['test/unit/test*.rb']
|
12
12
|
t.warning = false
|
13
13
|
end
|
14
14
|
|
15
|
+
Rake::TestTask.new(:test_functionals) do |t|
|
16
|
+
t.test_files = FileList['test/functional/test*.rb']
|
17
|
+
t.warning = false
|
18
|
+
end
|
19
|
+
|
20
|
+
Rake::TestTask.new(:test_integrations) do |t|
|
21
|
+
t.test_files = FileList['test/integration/test*.rb']
|
22
|
+
t.warning = false
|
23
|
+
end
|
data/lib/metra.rb
CHANGED
data/lib/metra/cacher.rb
CHANGED
@@ -45,7 +45,8 @@ module MetraSchedule
|
|
45
45
|
|
46
46
|
def persist_line(line)
|
47
47
|
create_cache_dir_if_not_exists
|
48
|
-
|
48
|
+
return false unless line.engines
|
49
|
+
true if File.open(File.join(@cache_dir, line.line_key.to_s), 'w') {|f| Marshal.dump(line.engines, f)}
|
49
50
|
end
|
50
51
|
|
51
52
|
def retrieve_line(line)
|
data/lib/metra/classmethods.rb
CHANGED
data/lib/metra/line.rb
CHANGED
@@ -4,6 +4,7 @@ module MetraSchedule
|
|
4
4
|
class Line
|
5
5
|
include MetraSchedule::TrainData
|
6
6
|
|
7
|
+
attr_reader :cacher, :cache_dir
|
7
8
|
attr_reader :line_key, :name, :url, :dir, :sched, :start, :destination, :time
|
8
9
|
attr_accessor :engines
|
9
10
|
|
@@ -14,14 +15,20 @@ module MetraSchedule
|
|
14
15
|
@line_key = line_name
|
15
16
|
@name = LINES[line_name][:name]
|
16
17
|
@url = LINES[line_name][:url]
|
18
|
+
@filters = [filter_by_stop, filter_by_start, filter_by_direction, filter_by_schedule, inject_my_times]
|
19
|
+
end
|
20
|
+
|
21
|
+
def config(args)
|
22
|
+
@cacher = args[:cacher] if args.has_key?(:cacher)
|
23
|
+
@cache_dir = args[:cache_dir] if args.has_key?(:cache_dir)
|
17
24
|
end
|
18
25
|
|
19
26
|
def load_schedule
|
20
|
-
|
21
|
-
unless
|
27
|
+
cached_engines = MetraSchedule::Cacher.load_from_cache(self)
|
28
|
+
unless cached_engines
|
22
29
|
update_schedule
|
23
30
|
else
|
24
|
-
@engines =
|
31
|
+
@engines = cached_engines
|
25
32
|
end
|
26
33
|
end
|
27
34
|
|
@@ -89,6 +96,10 @@ module MetraSchedule
|
|
89
96
|
schedule(:holiday)
|
90
97
|
end
|
91
98
|
|
99
|
+
def deduce_schedule
|
100
|
+
on(Date.today)
|
101
|
+
end
|
102
|
+
|
92
103
|
def set_station(start_or_destination, station)
|
93
104
|
unless start_or_destination == :start or start_or_destination == :destination
|
94
105
|
raise ArgumentError.new "First argument must be either :start or :destination"
|
@@ -108,65 +119,100 @@ module MetraSchedule
|
|
108
119
|
end
|
109
120
|
|
110
121
|
def at(time)
|
111
|
-
|
112
|
-
@time = Time.parse(time)
|
113
|
-
|
114
|
-
|
122
|
+
if time.is_a?(String)
|
123
|
+
@time = Time.parse(time)
|
124
|
+
elsif time.is_a?(Time)
|
125
|
+
@time = time
|
126
|
+
else
|
127
|
+
raise ArgumentError.new "Time must be either a valid time object, or a string that parses to one"
|
115
128
|
end
|
116
129
|
self
|
117
130
|
end
|
118
131
|
|
132
|
+
def on(date)
|
133
|
+
raise ArgumentError.new "Argument must be a date object!" unless date.is_a?(Date)
|
134
|
+
@sched = :weekday if (1..5).include?(date.cwday)
|
135
|
+
@sched = :saturday if date.cwday == 6
|
136
|
+
@sched = :sunday if date.cwday == 7
|
137
|
+
self
|
138
|
+
end
|
139
|
+
|
119
140
|
def deduce_direction_by_time
|
120
|
-
|
121
|
-
|
141
|
+
before_noon = Time.now < Time.parse("12:00PM")
|
142
|
+
after_noon = Time.now > Time.parse("12:00PM")
|
143
|
+
after_midnight_until_two = (Time.now >= Time.parse("12:00AM") and Time.now < Time.parse("2:00AM"))
|
144
|
+
if after_noon or after_midnight_until_two
|
145
|
+
@dir = :outbound
|
146
|
+
elsif before_noon
|
147
|
+
@dir = :inbound
|
148
|
+
else
|
149
|
+
@dir = :inbound
|
150
|
+
end
|
122
151
|
self
|
123
152
|
end
|
124
153
|
|
154
|
+
def find_train_by_train_num(train_num)
|
155
|
+
@engines.find {|e| e.train_num == train_num}
|
156
|
+
end
|
157
|
+
|
125
158
|
def trains
|
126
159
|
return [] unless engines
|
127
|
-
engines
|
128
|
-
filter_by_stop.include?(engine) and \
|
129
|
-
filter_by_start.include?(engine) and \
|
130
|
-
filter_by_direction.include?(engine) and \
|
131
|
-
filter_by_schedule.include?(engine)
|
132
|
-
end
|
160
|
+
@filters.inject(engines) { |e, fun| fun.call(e) }.sort
|
133
161
|
end
|
134
162
|
|
135
163
|
private
|
136
164
|
|
165
|
+
def inject_my_times
|
166
|
+
lambda do |engines|
|
167
|
+
return engines unless @start and @destination
|
168
|
+
engines.each do |engine|
|
169
|
+
engine.my_departure = engine.departure_and_arrival(@start, @destination)[:departure]
|
170
|
+
engine.my_arrival = engine.departure_and_arrival(@start, @destination)[:arrival]
|
171
|
+
end
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
137
175
|
def filter_by_stop
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
176
|
+
lambda do |engines|
|
177
|
+
if @start and not @destination
|
178
|
+
engines.find_all { |e| e.has_stop?(@start) }
|
179
|
+
elsif @destination and not @start
|
180
|
+
engines.find_all { |e| e.has_stop?(@destination) }
|
181
|
+
elsif @start and @destination
|
182
|
+
engines.find_all { |e| e.has_stop?(@start) and e.has_stop?(@destination)}
|
183
|
+
else
|
184
|
+
engines
|
185
|
+
end
|
146
186
|
end
|
147
187
|
end
|
148
188
|
|
149
189
|
def filter_by_start
|
150
|
-
|
151
|
-
|
152
|
-
|
190
|
+
lambda do |engines|
|
191
|
+
return engines unless @time and @start
|
192
|
+
engines.find_all do |engine|
|
193
|
+
engine.in_time?(@start, @time)
|
194
|
+
end
|
153
195
|
end
|
154
196
|
end
|
155
197
|
|
156
198
|
def filter_by_direction
|
157
|
-
|
158
|
-
|
159
|
-
|
199
|
+
lambda do |engines|
|
200
|
+
return engines if deduce_direction == :unknown
|
201
|
+
engines.find_all do |engine|
|
202
|
+
engine.direction == deduce_direction
|
203
|
+
end
|
160
204
|
end
|
161
205
|
end
|
162
206
|
|
163
207
|
def filter_by_schedule
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
208
|
+
lambda do |engines|
|
209
|
+
return engines unless @sched
|
210
|
+
engines.find_all do |engine|
|
211
|
+
if @sched == :holiday or @sched == :sunday
|
212
|
+
engine.schedule == :sunday or engine.schedule == :holiday
|
213
|
+
else
|
214
|
+
engine.schedule == @sched
|
215
|
+
end
|
170
216
|
end
|
171
217
|
end
|
172
218
|
end
|
data/lib/metra/parser.rb
CHANGED
@@ -66,6 +66,7 @@ module MetraSchedule
|
|
66
66
|
|
67
67
|
def make_stop(node, station_num, direction)
|
68
68
|
node_text = node.text
|
69
|
+
node_text = node_text[0..-2] if node_text[-1] == "x"
|
69
70
|
return nil if node_text == "– "
|
70
71
|
time = Time.parse(node_text + am_or_pm(node))
|
71
72
|
if direction == :inbound
|
data/lib/metra/train.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
module MetraSchedule
|
2
2
|
class Train
|
3
3
|
attr_reader :train_num, :schedule, :bike_limit, :direction, :stops
|
4
|
+
attr_accessor :my_departure, :my_arrival # Injected when the line is filtered
|
4
5
|
|
5
6
|
def initialize(options={})
|
6
7
|
unless options.empty?
|
@@ -18,8 +19,18 @@ module MetraSchedule
|
|
18
19
|
end
|
19
20
|
|
20
21
|
def in_time?(station, time)
|
21
|
-
|
22
|
-
|
22
|
+
stop_time = stops.find {|s| s.station == station}.time
|
23
|
+
if (stop_time.hour == time.hour)
|
24
|
+
if (stop_time.min > time.min)
|
25
|
+
return true
|
26
|
+
else
|
27
|
+
return false
|
28
|
+
end
|
29
|
+
elsif (stop_time.hour > time.hour)
|
30
|
+
return true
|
31
|
+
else
|
32
|
+
return false
|
33
|
+
end
|
23
34
|
end
|
24
35
|
|
25
36
|
def departure_and_arrival(start, destination)
|
@@ -28,5 +39,55 @@ module MetraSchedule
|
|
28
39
|
{:departure => departure, :arrival => arrival}
|
29
40
|
end
|
30
41
|
|
42
|
+
def my_travel_time
|
43
|
+
return nil unless @my_departure and @my_arrival
|
44
|
+
minutes = (@my_arrival.to_i - @my_departure.to_i) / 60
|
45
|
+
return minutes if minutes > 0
|
46
|
+
return minutes + 1440 if minutes < 0
|
47
|
+
end
|
48
|
+
|
49
|
+
def print_my_travel_time
|
50
|
+
if my_travel_time
|
51
|
+
"#{print_my_travel_hours} #{print_my_travel_minutes}".strip
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def <=>(other)
|
56
|
+
if my_departure
|
57
|
+
return 1 if self.my_departure > other.my_departure
|
58
|
+
return -1 if self.my_departure < other.my_departure
|
59
|
+
return 0 if self.my_departure == other.my_departure
|
60
|
+
elsif @stops.first and other.stops.first
|
61
|
+
return 1 if @stops.first.time > other.stops.first.time
|
62
|
+
return -1 if @stops.first.time < other.stops.first.time
|
63
|
+
return 0 if @stops.first.time == other.stops.first.time
|
64
|
+
else
|
65
|
+
0
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
private
|
70
|
+
|
71
|
+
def my_travel_hours
|
72
|
+
(my_travel_time / 60.0).floor
|
73
|
+
end
|
74
|
+
|
75
|
+
def my_travel_minutes
|
76
|
+
my_travel_time - (60 * my_travel_hours)
|
77
|
+
end
|
78
|
+
|
79
|
+
def print_my_travel_hours
|
80
|
+
return nil if my_travel_hours == 0
|
81
|
+
return "#{my_travel_hours} hour" if my_travel_hours == 1
|
82
|
+
return "#{my_travel_hours} hours" if my_travel_hours > 1
|
83
|
+
end
|
84
|
+
|
85
|
+
def print_my_travel_minutes
|
86
|
+
return nil if my_travel_minutes == 0
|
87
|
+
return "#{my_travel_minutes} minute" if my_travel_minutes == 1
|
88
|
+
return "#{my_travel_minutes} minutes" if my_travel_minutes > 1
|
89
|
+
end
|
90
|
+
|
91
|
+
|
31
92
|
end
|
32
93
|
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), "../", "test_helper.rb")
|
2
|
+
|
3
|
+
class TestLine < Test::Unit::TestCase
|
4
|
+
include MetraSchedule::TrainData
|
5
|
+
|
6
|
+
def up_nw_stub
|
7
|
+
f = File.open(File.join(File.dirname(__FILE__), '../fixture/UP_NW.html'), 'r')
|
8
|
+
parser = MetraSchedule::Parser.new f
|
9
|
+
parser.line = LINES[:up_nw]
|
10
|
+
line = Metra.new.line(:up_nw)
|
11
|
+
line.engines = parser.scrape
|
12
|
+
line
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_all_filters
|
16
|
+
line = up_nw_stub.from(:ogilve).to(:barrington).at(Time.parse("11:29PM")).on(Date.parse("Dec 27 2009"))
|
17
|
+
assert_equal(1, line.trains.count)
|
18
|
+
line = up_nw_stub.from(:ogilve).to(:barrington).at(Time.parse("3:00AM")).on(Date.parse("Dec 27 2009"))
|
19
|
+
assert_equal(7, line.trains.count)
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), "../", "test_helper.rb")
|
2
|
+
|
3
|
+
class TestLine < Test::Unit::TestCase
|
4
|
+
|
5
|
+
def test_load_schedule
|
6
|
+
cleanup_cache_dir
|
7
|
+
line = Metra.new.line(:up_nw).outbound
|
8
|
+
line.load_schedule
|
9
|
+
assert_not_nil(line.trains)
|
10
|
+
end
|
11
|
+
|
12
|
+
end
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'date'
|
2
|
+
require 'time'
|
3
|
+
require 'test/unit'
|
4
|
+
require 'fileutils'
|
5
|
+
|
6
|
+
require File.join(File.dirname(__FILE__), "timecop", "lib", "timecop")
|
7
|
+
require File.join(File.dirname(__FILE__), "../lib", "metra")
|
8
|
+
|
9
|
+
module TestUnit
|
10
|
+
module TestHelper
|
11
|
+
|
12
|
+
def cleanup_cache_dir
|
13
|
+
FileUtils.rmtree(MetraSchedule::Cacher.new.cache_dir)
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
Test::Unit::TestCase.send(:include, TestUnit::TestHelper)
|
@@ -1,7 +1,4 @@
|
|
1
|
-
require
|
2
|
-
require 'fileutils'
|
3
|
-
|
4
|
-
require File.join(File.dirname(__FILE__), "../lib", "metra")
|
1
|
+
require File.join(File.dirname(__FILE__), "../", "test_helper.rb")
|
5
2
|
|
6
3
|
class TestLine < Test::Unit::TestCase
|
7
4
|
|
@@ -56,7 +53,7 @@ class TestLine < Test::Unit::TestCase
|
|
56
53
|
line.engines = [train1, train2, train3]
|
57
54
|
|
58
55
|
assert_equal(true, c.persist_line(line))
|
59
|
-
assert_equal(line.engines.count, c.retrieve_line(line).
|
56
|
+
assert_equal(line.engines.count, c.retrieve_line(line).count)
|
60
57
|
cleanup_dir
|
61
58
|
end
|
62
59
|
|
@@ -75,7 +72,7 @@ class TestLine < Test::Unit::TestCase
|
|
75
72
|
line.engines = [train1, train2, train3]
|
76
73
|
|
77
74
|
assert_equal(true, MetraSchedule::Cacher.store_to_cache(line))
|
78
|
-
assert_equal(c.retrieve_line(line).
|
75
|
+
assert_equal(c.retrieve_line(line).count, MetraSchedule::Cacher.load_from_cache(line).count)
|
79
76
|
cleanup_dir
|
80
77
|
end
|
81
78
|
|
@@ -1,16 +1,7 @@
|
|
1
|
-
require
|
2
|
-
require File.join(File.dirname(__FILE__), "../lib", "metra")
|
3
|
-
require File.join(File.dirname(__FILE__), "timecop", "lib", "timecop")
|
1
|
+
require File.join(File.dirname(__FILE__), "../", "test_helper.rb")
|
4
2
|
|
5
3
|
class TestLine < Test::Unit::TestCase
|
6
4
|
|
7
|
-
# INTEGRATION:
|
8
|
-
# def test_update_schedule
|
9
|
-
# line = Metra.new.line(:up_nw).outbound
|
10
|
-
# line.update_schedule
|
11
|
-
# assert_not_nil(line.trains)
|
12
|
-
# end
|
13
|
-
|
14
5
|
def test_initialize_with_line_name
|
15
6
|
assert_nothing_raised do
|
16
7
|
Metra.new.line(:up_nw)
|
@@ -26,6 +17,13 @@ class TestLine < Test::Unit::TestCase
|
|
26
17
|
end
|
27
18
|
end
|
28
19
|
|
20
|
+
def test_cache_params
|
21
|
+
line = Metra.new.line(:up_nw)
|
22
|
+
line.config :cacher => :tokyo, :cache_dir => '/home/blake/.metra_scheudule'
|
23
|
+
assert_equal(:tokyo, line.cacher)
|
24
|
+
assert_equal('/home/blake/.metra_scheudule', line.cache_dir)
|
25
|
+
end
|
26
|
+
|
29
27
|
def test_has_name_and_url
|
30
28
|
line = Metra.new.line(:up_nw)
|
31
29
|
assert_equal("Union Pacific Northwest", line.name)
|
@@ -131,10 +129,11 @@ class TestLine < Test::Unit::TestCase
|
|
131
129
|
line = Metra.new.line(:up_nw)
|
132
130
|
test_time = "12:30PM"
|
133
131
|
assert_nothing_raised do
|
134
|
-
line.at(test_time)
|
135
132
|
line.at(Time.now)
|
133
|
+
line.at(test_time)
|
136
134
|
end
|
137
135
|
assert_equal(line.time, Time.parse(test_time))
|
136
|
+
line.at(Time.parse("12:30PM"))
|
138
137
|
assert_raises ArgumentError do
|
139
138
|
line.at(:bloopybloop)
|
140
139
|
end
|
@@ -147,6 +146,20 @@ class TestLine < Test::Unit::TestCase
|
|
147
146
|
assert_equal(:inbound, line.from(:barrington).to(:ogilve).deduce_direction)
|
148
147
|
end
|
149
148
|
|
149
|
+
def test_trains_sorted_by_departure_time
|
150
|
+
line = Metra.new.line(:up_nw)
|
151
|
+
|
152
|
+
stop1 = MetraSchedule::Stop.new :station => :barrington, :time => Time.parse('12:30')
|
153
|
+
stop2 = MetraSchedule::Stop.new :station => :barrington, :time => Time.parse('12:40')
|
154
|
+
stop3 = MetraSchedule::Stop.new :station => :ogilve, :time => Time.parse('13:30')
|
155
|
+
train1 = MetraSchedule::Train.new :stops => [stop1, stop3], :direction => :outbound, :schedule => :weekday
|
156
|
+
train2 = MetraSchedule::Train.new :stops => [stop2, stop3], :direction => :outbound, :schedule => :weekday
|
157
|
+
line.engines = [train2, train1]
|
158
|
+
|
159
|
+
valid_trains = line.outbound.trains
|
160
|
+
assert_equal([train1, train2], valid_trains)
|
161
|
+
end
|
162
|
+
|
150
163
|
def test_trains_filter_by_station
|
151
164
|
line = Metra.new.line(:up_nw)
|
152
165
|
|
@@ -262,4 +275,50 @@ class TestLine < Test::Unit::TestCase
|
|
262
275
|
assert_equal(:outbound, line.dir)
|
263
276
|
end
|
264
277
|
|
278
|
+
def test_deduce_direction_by_time_after_midnight
|
279
|
+
Timecop.freeze(Time.parse("12:01AM"))
|
280
|
+
line = Metra.new.line(:up_nw).deduce_direction_by_time
|
281
|
+
assert_equal(:outbound, line.dir)
|
282
|
+
end
|
283
|
+
|
284
|
+
def test_deduce_direction_by_time_at_midnight
|
285
|
+
Timecop.freeze(Time.parse("12:00AM"))
|
286
|
+
line = Metra.new.line(:up_nw).deduce_direction_by_time
|
287
|
+
assert_equal(:outbound, line.dir)
|
288
|
+
end
|
289
|
+
|
290
|
+
def test_deduce_direction_by_time_at_3AM
|
291
|
+
Timecop.freeze(Time.parse("3:00AM"))
|
292
|
+
line = Metra.new.line(:up_nw).deduce_direction_by_time
|
293
|
+
assert_equal(:inbound, line.dir)
|
294
|
+
end
|
295
|
+
|
296
|
+
def test_on
|
297
|
+
line = Metra.new.line(:up_nw)
|
298
|
+
assert_equal(:weekday, line.on(Date.civil(2009, 12, 29)).sched)
|
299
|
+
assert_equal(:saturday, line.on(Date.civil(2009, 12, 26)).sched)
|
300
|
+
assert_equal(:sunday, line.on(Date.civil(2009, 12, 27)).sched)
|
301
|
+
|
302
|
+
assert_raises ArgumentError do
|
303
|
+
line.on("blah")
|
304
|
+
end
|
305
|
+
end
|
306
|
+
|
307
|
+
def test_deduce_schedule
|
308
|
+
line = Metra.new.line(:up_nw)
|
309
|
+
Timecop.freeze(2009, 12, 27)
|
310
|
+
assert_equal(:sunday, line.deduce_schedule.sched)
|
311
|
+
end
|
312
|
+
|
313
|
+
def test_find_train_by_train_num
|
314
|
+
line = Metra.new.line(:up_nw)
|
315
|
+
stop1 = MetraSchedule::Stop.new :station => :barrington, :time => Time.parse('12:30')
|
316
|
+
stop2 = MetraSchedule::Stop.new :station => :ogilve, :time => Time.parse('13:30')
|
317
|
+
train1 = MetraSchedule::Train.new :train_num => 642, :direction => :inbound, :stops => [stop1, stop2], :schedule => :weekday
|
318
|
+
train2 = MetraSchedule::Train.new :train_num => 631, :direction => :outbound, :stops => [stop1, stop2], :schedule => :holiday
|
319
|
+
line.engines = [train1, train2]
|
320
|
+
|
321
|
+
assert_equal(train1, line.find_train_by_train_num(642))
|
322
|
+
end
|
323
|
+
|
265
324
|
end
|
@@ -1,11 +1,10 @@
|
|
1
|
-
require
|
2
|
-
require File.join(File.dirname(__FILE__), "../lib", "metra")
|
1
|
+
require File.join(File.dirname(__FILE__), "../", "test_helper.rb")
|
3
2
|
|
4
3
|
class TestLine < Test::Unit::TestCase
|
5
4
|
include MetraSchedule::TrainData
|
6
5
|
|
7
6
|
def up_nw_stub
|
8
|
-
f = File.open(File.join(File.dirname(__FILE__), 'fixture/UP_NW.html'), 'r')
|
7
|
+
f = File.open(File.join(File.dirname(__FILE__), '../fixture/UP_NW.html'), 'r')
|
9
8
|
parser = MetraSchedule::Parser.new f
|
10
9
|
parser.line = LINES[:up_nw]
|
11
10
|
parser.scrape
|
@@ -93,6 +92,15 @@ class TestLine < Test::Unit::TestCase
|
|
93
92
|
assert_equal(expected.time, p.make_stop(node, 19, :inbound).time)
|
94
93
|
end
|
95
94
|
|
95
|
+
def test_make_stop_pm_express
|
96
|
+
p = up_nw_stub
|
97
|
+
|
98
|
+
node = p.tables[3][:tables][1].xpath("tbody[2]/tr/td[5]")[0]
|
99
|
+
expected = MetraSchedule::Stop.new :station => :clyborn, :time => Time.parse("5:29PM")
|
100
|
+
assert_equal(expected.station, p.make_stop(node, 1, :outbound).station)
|
101
|
+
assert_equal(expected.time, p.make_stop(node, 1, :outbound).time)
|
102
|
+
end
|
103
|
+
|
96
104
|
def test_find_stops
|
97
105
|
p = up_nw_stub
|
98
106
|
|
@@ -0,0 +1,154 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), "../", "test_helper.rb")
|
2
|
+
|
3
|
+
class TestLine < Test::Unit::TestCase
|
4
|
+
|
5
|
+
def test_initialize_empty_options
|
6
|
+
assert_nothing_raised do
|
7
|
+
t = MetraSchedule::Train.new
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
def test_initialize_one_option
|
12
|
+
assert_nothing_raised do
|
13
|
+
@@t = MetraSchedule::Train.new :train_num => 651
|
14
|
+
end
|
15
|
+
assert_equal(651, @@t.train_num)
|
16
|
+
end
|
17
|
+
|
18
|
+
def test_initialize_two_options
|
19
|
+
assert_nothing_raised do
|
20
|
+
@@t = MetraSchedule::Train.new :train_num => 651, :bike_limit => 12
|
21
|
+
end
|
22
|
+
assert_equal(651, @@t.train_num)
|
23
|
+
assert_equal(12, @@t.bike_limit)
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_initialize_all_options
|
27
|
+
stop = MetraSchedule::Stop.new :station => :barrington, :time => Time.now
|
28
|
+
assert_nothing_raised do
|
29
|
+
@@t = MetraSchedule::Train.new :train_num => 651, :bike_limit => 12, :schedule => :weekday, :direction => :outbound, :stops => [stop]
|
30
|
+
end
|
31
|
+
assert_equal(651, @@t.train_num)
|
32
|
+
assert_equal(12, @@t.bike_limit)
|
33
|
+
assert_equal(:weekday, @@t.schedule)
|
34
|
+
assert_equal(:outbound, @@t.direction)
|
35
|
+
assert_equal([stop], @@t.stops)
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_has_stop?
|
39
|
+
stop = MetraSchedule::Stop.new :station => :barrington, :time => Time.now
|
40
|
+
@@t = MetraSchedule::Train.new :train_num => 651, :bike_limit => 12, :schedule => :weekday, :direction => :outbound, :stops => [stop]
|
41
|
+
assert_equal(true, @@t.has_stop?(:barrington))
|
42
|
+
assert_equal(false, @@t.has_stop?(:arlington_park))
|
43
|
+
end
|
44
|
+
|
45
|
+
def test_in_time?
|
46
|
+
stop1 = MetraSchedule::Stop.new :station => :barrington, :time => Time.parse("12:30PM")
|
47
|
+
stop2 = MetraSchedule::Stop.new :station => :arlington_heights, :time => Time.parse("12:40PM")
|
48
|
+
@@t = MetraSchedule::Train.new :train_num => 651, :bike_limit => 12, :schedule => :weekday, :direction => :inbound, :stops => [stop1, stop2]
|
49
|
+
assert_equal(true, @@t.in_time?(:arlington_heights, Time.parse("12:35PM")))
|
50
|
+
assert_equal(false, @@t.in_time?(:barrington, Time.parse("12:35PM")))
|
51
|
+
end
|
52
|
+
|
53
|
+
def test_in_time_same_time_next_day
|
54
|
+
stop1 = MetraSchedule::Stop.new :station => :barrington, :time => Time.parse("12:30PM")
|
55
|
+
stop2 = MetraSchedule::Stop.new :station => :arlington_heights, :time => Time.parse("12:40PM")
|
56
|
+
@@t = MetraSchedule::Train.new :train_num => 651, :bike_limit => 12, :schedule => :weekday, :direction => :inbound, :stops => [stop1, stop2]
|
57
|
+
tomorrow = Time.parse("12:35PM") + (60 * 60 * 24)
|
58
|
+
assert_equal(true, @@t.in_time?(:arlington_heights, tomorrow))
|
59
|
+
assert_equal(false, @@t.in_time?(:barrington, tomorrow))
|
60
|
+
end
|
61
|
+
|
62
|
+
def test_departure_and_arrival
|
63
|
+
stop1 = MetraSchedule::Stop.new :station => :barrington, :time => Time.parse("12:30")
|
64
|
+
stop2 = MetraSchedule::Stop.new :station => :arlington_heights, :time => Time.parse("12:40")
|
65
|
+
@@t = MetraSchedule::Train.new :train_num => 651, :bike_limit => 12, :schedule => :weekday, :direction => :inbound, :stops => [stop1, stop2]
|
66
|
+
|
67
|
+
l = Metra.new.line(:up_nw)
|
68
|
+
l.engines = [@@t]
|
69
|
+
train = l.trains.first
|
70
|
+
assert_equal({:departure => Time.parse("12:30"), :arrival => Time.parse("12:40")}, train.departure_and_arrival(:barrington, :arlington_heights))
|
71
|
+
end
|
72
|
+
|
73
|
+
def test_my_departure_and_my_arrival
|
74
|
+
stop1 = MetraSchedule::Stop.new :station => :barrington, :time => Time.parse("12:30")
|
75
|
+
stop2 = MetraSchedule::Stop.new :station => :arlington_heights, :time => Time.parse("12:40")
|
76
|
+
@@t = MetraSchedule::Train.new :train_num => 651, :bike_limit => 12, :schedule => :weekday, :direction => :inbound, :stops => [stop1, stop2]
|
77
|
+
|
78
|
+
l = Metra.new.line(:up_nw).from(:barrington).to(:arlington_heights)
|
79
|
+
l.engines = [@@t]
|
80
|
+
train = l.trains.first
|
81
|
+
assert_equal(Time.parse("12:30"), train.my_departure)
|
82
|
+
assert_equal(Time.parse("12:40"), train.my_arrival)
|
83
|
+
end
|
84
|
+
|
85
|
+
def test_my_departure_and_my_arrival_with_no_start_or_destination
|
86
|
+
stop1 = MetraSchedule::Stop.new :station => :barrington, :time => Time.parse("12:30")
|
87
|
+
stop2 = MetraSchedule::Stop.new :station => :arlington_heights, :time => Time.parse("12:40")
|
88
|
+
@@t = MetraSchedule::Train.new :train_num => 651, :bike_limit => 12, :schedule => :weekday, :direction => :inbound, :stops => [stop1, stop2]
|
89
|
+
|
90
|
+
l = Metra.new.line(:up_nw)
|
91
|
+
l.engines = [@@t]
|
92
|
+
train = l.trains.first
|
93
|
+
assert_equal(nil, train.my_departure)
|
94
|
+
assert_equal(nil, train.my_arrival)
|
95
|
+
end
|
96
|
+
|
97
|
+
def test_my_travel_time
|
98
|
+
train = MetraSchedule::Train.new :train_num => 651, :bike_limit => 12, :schedule => :weekday, :direction => :inbound
|
99
|
+
train.my_departure = Time.parse("12:30PM")
|
100
|
+
train.my_arrival = Time.parse("1:30PM")
|
101
|
+
assert_equal(60, train.my_travel_time)
|
102
|
+
end
|
103
|
+
|
104
|
+
def test_my_travel_time_nil
|
105
|
+
train = MetraSchedule::Train.new :train_num => 651, :bike_limit => 12, :schedule => :weekday, :direction => :inbound
|
106
|
+
assert_equal(nil, train.my_travel_time)
|
107
|
+
end
|
108
|
+
|
109
|
+
def test_my_travel_time_one_day_into_next
|
110
|
+
train = MetraSchedule::Train.new :train_num => 651, :bike_limit => 12, :schedule => :weekday, :direction => :inbound
|
111
|
+
train.my_departure = Time.parse("11:30PM")
|
112
|
+
train.my_arrival = Time.parse("12:30AM")
|
113
|
+
assert_equal(60, train.my_travel_time)
|
114
|
+
|
115
|
+
train.my_arrival = Time.parse("1:30AM")
|
116
|
+
assert_equal(120, train.my_travel_time)
|
117
|
+
end
|
118
|
+
|
119
|
+
def test_print_my_travel_time_minutes
|
120
|
+
train = MetraSchedule::Train.new :train_num => 651, :bike_limit => 12, :schedule => :weekday, :direction => :inbound
|
121
|
+
train.my_departure = Time.parse("12:30PM")
|
122
|
+
train.my_arrival = Time.parse("1:29PM")
|
123
|
+
assert_equal("59 minutes", train.print_my_travel_time)
|
124
|
+
end
|
125
|
+
|
126
|
+
def test_print_my_travel_time_one_hour
|
127
|
+
train = MetraSchedule::Train.new :train_num => 651, :bike_limit => 12, :schedule => :weekday, :direction => :inbound
|
128
|
+
train.my_departure = Time.parse("12:30PM")
|
129
|
+
train.my_arrival = Time.parse("1:30PM")
|
130
|
+
assert_equal("1 hour", train.print_my_travel_time)
|
131
|
+
end
|
132
|
+
|
133
|
+
def test_print_my_travel_time_one_hour_and_minutes
|
134
|
+
train = MetraSchedule::Train.new :train_num => 651, :bike_limit => 12, :schedule => :weekday, :direction => :inbound
|
135
|
+
train.my_departure = Time.parse("12:30PM")
|
136
|
+
train.my_arrival = Time.parse("1:35PM")
|
137
|
+
assert_equal("1 hour 5 minutes", train.print_my_travel_time)
|
138
|
+
end
|
139
|
+
|
140
|
+
def test_print_my_travel_time_two_hours
|
141
|
+
train = MetraSchedule::Train.new :train_num => 651, :bike_limit => 12, :schedule => :weekday, :direction => :inbound
|
142
|
+
train.my_departure = Time.parse("12:30PM")
|
143
|
+
train.my_arrival = Time.parse("2:30PM")
|
144
|
+
assert_equal("2 hours", train.print_my_travel_time)
|
145
|
+
end
|
146
|
+
|
147
|
+
def test_print_my_travel_time_two_hours_and_minutes
|
148
|
+
train = MetraSchedule::Train.new :train_num => 651, :bike_limit => 12, :schedule => :weekday, :direction => :inbound
|
149
|
+
train.my_departure = Time.parse("12:30PM")
|
150
|
+
train.my_arrival = Time.parse("2:35PM")
|
151
|
+
assert_equal("2 hours 5 minutes", train.print_my_travel_time)
|
152
|
+
end
|
153
|
+
|
154
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: metra_schedule
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.1
|
4
|
+
version: 0.2.1.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Blake Smith
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-12-
|
12
|
+
date: 2009-12-31 00:00:00 -06:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -42,13 +42,16 @@ files:
|
|
42
42
|
- lib/metra/stop.rb
|
43
43
|
- lib/metra/train.rb
|
44
44
|
- lib/metra/train_data.rb
|
45
|
+
- test/test_helper.rb
|
45
46
|
- test/fixture/UP_NW.html
|
46
|
-
- test/test_cacher.rb
|
47
|
-
- test/test_line.rb
|
48
|
-
- test/test_metra.rb
|
49
|
-
- test/test_parser.rb
|
50
|
-
- test/test_stop.rb
|
51
|
-
- test/test_train.rb
|
47
|
+
- test/unit/test_cacher.rb
|
48
|
+
- test/unit/test_line.rb
|
49
|
+
- test/unit/test_metra.rb
|
50
|
+
- test/unit/test_parser.rb
|
51
|
+
- test/unit/test_stop.rb
|
52
|
+
- test/unit/test_train.rb
|
53
|
+
- test/functional/test_all_filters.rb
|
54
|
+
- test/integration/test_line_integration.rb
|
52
55
|
has_rdoc: true
|
53
56
|
homepage: http://github.com/blakesmith/metra_schedule
|
54
57
|
licenses: []
|
data/test/test_train.rb
DELETED
@@ -1,65 +0,0 @@
|
|
1
|
-
require 'test/unit'
|
2
|
-
require File.join(File.dirname(__FILE__), "../lib", "metra")
|
3
|
-
|
4
|
-
class TestLine < Test::Unit::TestCase
|
5
|
-
|
6
|
-
def test_initialize_empty_options
|
7
|
-
assert_nothing_raised do
|
8
|
-
t = MetraSchedule::Train.new
|
9
|
-
end
|
10
|
-
end
|
11
|
-
|
12
|
-
def test_initialize_one_option
|
13
|
-
assert_nothing_raised do
|
14
|
-
@@t = MetraSchedule::Train.new :train_num => 651
|
15
|
-
end
|
16
|
-
assert_equal(651, @@t.train_num)
|
17
|
-
end
|
18
|
-
|
19
|
-
def test_initialize_two_options
|
20
|
-
assert_nothing_raised do
|
21
|
-
@@t = MetraSchedule::Train.new :train_num => 651, :bike_limit => 12
|
22
|
-
end
|
23
|
-
assert_equal(651, @@t.train_num)
|
24
|
-
assert_equal(12, @@t.bike_limit)
|
25
|
-
end
|
26
|
-
|
27
|
-
def test_initialize_all_options
|
28
|
-
stop = MetraSchedule::Stop.new :station => :barrington, :time => Time.now
|
29
|
-
assert_nothing_raised do
|
30
|
-
@@t = MetraSchedule::Train.new :train_num => 651, :bike_limit => 12, :schedule => :weekday, :direction => :outbound, :stops => [stop]
|
31
|
-
end
|
32
|
-
assert_equal(651, @@t.train_num)
|
33
|
-
assert_equal(12, @@t.bike_limit)
|
34
|
-
assert_equal(:weekday, @@t.schedule)
|
35
|
-
assert_equal(:outbound, @@t.direction)
|
36
|
-
assert_equal([stop], @@t.stops)
|
37
|
-
end
|
38
|
-
|
39
|
-
def test_has_stop?
|
40
|
-
stop = MetraSchedule::Stop.new :station => :barrington, :time => Time.now
|
41
|
-
@@t = MetraSchedule::Train.new :train_num => 651, :bike_limit => 12, :schedule => :weekday, :direction => :outbound, :stops => [stop]
|
42
|
-
assert_equal(true, @@t.has_stop?(:barrington))
|
43
|
-
assert_equal(false, @@t.has_stop?(:arlington_park))
|
44
|
-
end
|
45
|
-
|
46
|
-
def test_in_time?
|
47
|
-
stop1 = MetraSchedule::Stop.new :station => :barrington, :time => Time.parse("12:30")
|
48
|
-
stop2 = MetraSchedule::Stop.new :station => :arlington_heights, :time => Time.parse("12:40")
|
49
|
-
@@t = MetraSchedule::Train.new :train_num => 651, :bike_limit => 12, :schedule => :weekday, :direction => :inbound, :stops => [stop1, stop2]
|
50
|
-
assert_equal(true, @@t.in_time?(:arlington_heights, Time.parse("12:35")))
|
51
|
-
assert_equal(false, @@t.in_time?(:barrington, Time.parse("12:35")))
|
52
|
-
end
|
53
|
-
|
54
|
-
def test_departure_and_arrival
|
55
|
-
stop1 = MetraSchedule::Stop.new :station => :barrington, :time => Time.parse("12:30")
|
56
|
-
stop2 = MetraSchedule::Stop.new :station => :arlington_heights, :time => Time.parse("12:40")
|
57
|
-
@@t = MetraSchedule::Train.new :train_num => 651, :bike_limit => 12, :schedule => :weekday, :direction => :inbound, :stops => [stop1, stop2]
|
58
|
-
|
59
|
-
l = Metra.new.line(:up_nw)
|
60
|
-
l.engines = [@@t]
|
61
|
-
train = l.trains.first
|
62
|
-
assert_equal({:departure => Time.parse("12:30"), :arrival => Time.parse("12:40")}, train.departure_and_arrival(:barrington, :arlington_heights))
|
63
|
-
end
|
64
|
-
|
65
|
-
end
|