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 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