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 CHANGED
@@ -25,9 +25,7 @@ How to use metra_schedule
25
25
 
26
26
  === Setup
27
27
 
28
- Make sure you have the gemcutter repository on your gem list and:
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
- Each train has the following variables that can be accessed:
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
@@ -6,5 +6,5 @@ require File.join(File.dirname(__FILE__), 'metra', 'parser')
6
6
  require File.join(File.dirname(__FILE__), 'metra', 'cacher')
7
7
 
8
8
  class Metra
9
- include MetraSchedule::ClassMethods
9
+ include MetraSchedule::InstanceMethods
10
10
  end
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
- true if File.open(File.join(@cache_dir, line.line_key.to_s), 'w') {|f| Marshal.dump(line, f)}
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)
@@ -1,5 +1,5 @@
1
1
  module MetraSchedule
2
- module ClassMethods
2
+ module InstanceMethods
3
3
 
4
4
  def line(line_name)
5
5
  MetraSchedule::Line.new(line_name)
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
- cached_line = MetraSchedule::Cacher.load_from_cache(self)
21
- unless cached_line
27
+ cached_engines = MetraSchedule::Cacher.load_from_cache(self)
28
+ unless cached_engines
22
29
  update_schedule
23
30
  else
24
- @engines = cached_line.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
- begin
112
- @time = Time.parse(time)
113
- rescue
114
- raise ArgumentError.new "Time must be a valid time object" unless time.is_a?(Time)
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
- @dir = :inbound if Time.now < Time.parse("12:00PM")
121
- @dir = :outbound if Time.now > Time.parse("12:00PM")
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.find_all do |engine|
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
- if @start and not @destination
139
- engines.find_all { |e| e.has_stop?(@start) }
140
- elsif @destination and not @start
141
- engines.find_all { |e| e.has_stop?(@destination) }
142
- elsif @start and @destination
143
- engines.find_all { |e| e.has_stop?(@start) and e.has_stop?(@destination)}
144
- else
145
- engines
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
- return engines if not @time or not @start
151
- engines.find_all do |engine|
152
- engine.in_time?(@start, @time)
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
- return engines if deduce_direction == :unknown
158
- engines.find_all do |engine|
159
- engine.direction == deduce_direction
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
- return engines if not @sched
165
- engines.find_all do |engine|
166
- if @sched == :holiday or @sched == :sunday
167
- engine.schedule == :sunday or engine.schedule == :holiday
168
- else
169
- engine.schedule == @sched
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
- return true if stops.find {|s| s.station == station}.time > time
22
- false
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
@@ -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 'test/unit'
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).engines.count)
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).engines.count, MetraSchedule::Cacher.load_from_cache(line).engines.count)
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 'test/unit'
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,5 +1,4 @@
1
- require 'test/unit'
2
- require File.join(File.dirname(__FILE__), "../lib", "metra")
1
+ require File.join(File.dirname(__FILE__), "../", "test_helper.rb")
3
2
 
4
3
  class TestMetra < Test::Unit::TestCase
5
4
  def test_metra_init
@@ -1,11 +1,10 @@
1
- require 'test/unit'
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
 
@@ -1,5 +1,4 @@
1
- require 'test/unit'
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
 
@@ -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-24 00:00:00 -06:00
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