metra_schedule 0.2.1 → 0.2.1.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/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
|