mitchellh-rubyuw 0.6.1 → 0.6.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.markdown CHANGED
@@ -46,4 +46,35 @@ The following is a quick and simple example:
46
46
  myuw.login("netid", "password") or raise("Login Failed!")
47
47
 
48
48
  # Get SLN information
49
- sln_info = myuw.sln(14153)
49
+ sln_info = myuw.sln(14153)
50
+
51
+ # Get user course schedule
52
+ schedule = myuw.schedule.schedule
53
+
54
+ ## Testing
55
+
56
+ RubyUW includes a comprehensive test suite included both live and
57
+ mocked testing. Mocked testing uses "mocked" HTML pages and a lot
58
+ of object stubbing to simulate a real environment and to force
59
+ certain events to occur (such as strange HTML in a request) in order
60
+ to completely test the library. Mock testing can be run straight
61
+ "out of the box" via a rake task:
62
+
63
+ rake test:run_mock
64
+
65
+ RubyUW also includes "live" testing which uses a real UW NetID and
66
+ password to conduct live tests. To run this, see test/password.rb.sample
67
+ and modify it to include your credentials, then save it as password.rb.
68
+ Following this, run another rake task:
69
+
70
+ rake test:run_live
71
+
72
+ Note: Live testing is very very slow. On my machine with the current
73
+ suite it takes about a minute to run all the tests (though this is
74
+ highly dependent on your internet connection).
75
+
76
+ Note: Also, live testing DOES NOT test registration since that actually
77
+ affects your MyUW account in a significant way. To test registration,
78
+ run the registration test directly:
79
+
80
+ cd test/live && ruby registration_test.rb
data/Rakefile CHANGED
@@ -15,11 +15,6 @@ rescue LoadError
15
15
  end
16
16
 
17
17
  def run_tests(files)
18
- require File.join(File.dirname(__FILE__), 'lib', 'myuw')
19
- require 'test/unit'
20
- require "contest"
21
- require "stories"
22
- require "mocha"
23
18
  files.each { |f| require f }
24
19
  end
25
20
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.6.1
1
+ 0.6.2
data/lib/myuw/sln.rb CHANGED
@@ -36,6 +36,9 @@ class MyUW
36
36
  # Request the actual page
37
37
  page = get_sln_page
38
38
 
39
+ # Check if the time is not available
40
+ check_time_schedule_closed page
41
+
39
42
  # Get the actual course information
40
43
  get_course_info page
41
44
  get_enrollment_info page
@@ -72,48 +75,51 @@ class MyUW
72
75
  # Gets the basic SLN info (the top table in the
73
76
  # current status page)
74
77
  def get_course_info(page)
78
+ data_keys = [nil, :course, :section, :type, :credits, :title]
75
79
  info_nodes = page.search("//table[@border=1 and @cellpadding=3]//tr[@rowspan=1]//td")
76
- raise InvalidPageError.new(page, "Could not extract course info for SLN.") if info_nodes.empty?
77
-
78
- data_order = [nil, :course, :section, :type, :credits, :title]
79
- info_nodes.each_with_index do |node, i|
80
- if i < data_order.length then
81
- data_key = data_order[i]
82
-
83
- unless data_key.nil?
84
- @data ||= {}
85
- @data[data_key] = node.inner_text.strip.gsub("\302\240", "")
86
- end
87
- end
88
- end
80
+ raise InvalidPageError.new(page, "Could not extract course info for SLN.") unless extract_info(data_keys, info_nodes)
89
81
  end
90
82
 
91
83
  # Gets the enrollment information for an SLN such
92
84
  # as current enrollment, space available, etc.
93
85
  def get_enrollment_info(page)
86
+ data_keys = [:current_enrollment, :limit_enrollment, :room_capacity, :space_available, :status]
94
87
  info_nodes = page.search("//table[@border=1 and @cellpadding=3]//tr[count(td)=5]//td")
95
- raise InvalidPageError.new(page, "Could not extract enrollment info for SLN.") if info_nodes.empty?
88
+ raise InvalidPageError.new(page, "Could not extract enrollment info for SLN.") unless extract_info(data_keys, info_nodes)
89
+ end
90
+
91
+ # Gets the notes for a course
92
+ def get_course_notes(page)
93
+ data_keys = [:notes]
94
+ info_nodes = page.search("//table[@border=1 and @cellpadding=3]//tr[count(td)=1]//preceding-sibling::tr[count(th)=1]//following-sibling::tr//td")
95
+ raise InvalidPageError.new(page, "Could not find course notes information.") unless extract_info(data_keys, info_nodes)
96
+ end
97
+
98
+ # Extracts course information from each node and
99
+ # stores it as the proper key in the @data variable
100
+ def extract_info(keys, nodes)
101
+ return false if nodes.empty?
96
102
 
97
- data_order = [:current_enrollment, :limit_enrollment, :room_capacity, :space_available, :status]
98
- info_nodes.each_with_index do |node, i|
99
- if i < data_order.length then
100
- data_key = data_order[i]
103
+ nodes.each_with_index do |node, i|
104
+ # Make sure we have keys left still
105
+ if i < keys.length then
106
+ data_key = keys[i]
101
107
 
108
+ # If the key is nil, we skip this node
102
109
  unless data_key.nil?
103
110
  @data ||= {}
104
111
  @data[data_key] = node.inner_text.strip.gsub("\302\240", "")
105
112
  end
106
113
  end
107
114
  end
115
+
116
+ true
108
117
  end
109
118
 
110
- # Gets the notes for a course
111
- def get_course_notes(page)
112
- info_nodes = page.search("//table[@border=1 and @cellpadding=3]//tr[count(td)=1]//preceding-sibling::tr[count(th)=1]//following-sibling::tr//td")
113
- raise InvalidPageError.new(page, "Could not find course notes information.") if info_nodes.empty?
114
-
115
- @data ||= {}
116
- @data[:notes] = info_nodes[0].inner_text.strip
119
+ # Checks if the time schedule system is closed and if
120
+ # so, raises an exception
121
+ def check_time_schedule_closed(page)
122
+ raise TimeScheduleClosedError.new if page.uri.to_s == "http://www.washington.edu/students/timeschd/nots.html"
117
123
  end
118
124
  end
119
125
 
@@ -121,4 +127,5 @@ class MyUW
121
127
  # Exceptions
122
128
  class InvalidSLNError < StandardError; end
123
129
  class RequestSLNTooSoonError < StandardError; end
130
+ class TimeScheduleClosedError < StandardError; end
124
131
  end
data/rubyuw.gemspec CHANGED
@@ -2,11 +2,11 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = %q{rubyuw}
5
- s.version = "0.6.1"
5
+ s.version = "0.6.2"
6
6
 
7
7
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
8
8
  s.authors = ["Mitchell Hashimoto"]
9
- s.date = %q{2009-06-29}
9
+ s.date = %q{2009-07-02}
10
10
  s.description = %q{TODO}
11
11
  s.email = %q{mitchell.hashimoto@gmail.com}
12
12
  s.extra_rdoc_files = [
@@ -1,3 +1,5 @@
1
+ require File.join(File.dirname(__FILE__), 'test_helper')
2
+
1
3
  class MyUWTest < Test::Unit::TestCase
2
4
  context "initializing a MyUW object" do
3
5
  setup do
@@ -65,25 +65,118 @@ class MockedSlnTest < Test::Unit::TestCase
65
65
  should "raise an InvalidPageError if it can't find the course info" do
66
66
  fixture_page = @browser.get(path_to_html("sln_no_course_info"))
67
67
 
68
- assert_raise MyUW::InvalidPageError do
68
+ e = assert_raise MyUW::InvalidPageError do
69
69
  @sln.get_course_info(fixture_page)
70
70
  end
71
+
72
+ assert !e.page.nil?
71
73
  end
72
74
 
73
75
  should "raise an InvalidPageError if it can't find the enrollment info" do
74
76
  fixture_page = @browser.get(path_to_html("sln_no_enrollment_info"))
75
77
 
76
- assert_raise MyUW::InvalidPageError do
78
+ e = assert_raise MyUW::InvalidPageError do
77
79
  @sln.get_enrollment_info(fixture_page)
78
80
  end
81
+
82
+ assert !e.page.nil?
79
83
  end
80
84
 
81
85
  should "raise an InvalidPageError if it can't find the course notes" do
82
86
  fixture_page = @browser.get(path_to_html("sln_no_course_notes"))
83
87
 
84
- assert_raise MyUW::InvalidPageError do
88
+ e = assert_raise MyUW::InvalidPageError do
85
89
  @sln.get_course_notes(fixture_page)
86
90
  end
91
+
92
+ assert !e.page.nil?
93
+ end
94
+
95
+ should "raise a TimeScheduleClosedError if the time schedule system is closed" do
96
+ fixture_page = mock()
97
+ fixture_page.stubs(:uri).returns("http://www.washington.edu/students/timeschd/nots.html")
98
+ fixture_page.stubs(:body).returns("")
99
+ @browser.expects(:get).returns(fixture_page)
100
+
101
+ assert_raise MyUW::TimeScheduleClosedError do
102
+ @sln.course
103
+ end
104
+ end
105
+
106
+ should "not raise a TimeScheduleClosedError if the URI doesn't match" do
107
+ fixture_page = @browser.get(path_to_html("sln_status"))
108
+ @browser.expects(:get).returns(fixture_page)
109
+
110
+ assert_nothing_raised do
111
+ @sln.course
112
+ end
113
+ end
114
+ end
115
+
116
+ context "extract info from nodes" do
117
+ setup do
118
+ @myuw = MyUW.new
119
+ @sln = @myuw.sln("123456", "AUT+2009")
120
+
121
+ @keys = [:foo, :bar, :baz]
122
+ @values = [
123
+ stub(:inner_text => "vfoo"),
124
+ stub(:inner_text => "vbar"),
125
+ stub(:inner_text => "vbaz")
126
+ ]
127
+
128
+ @long_values = @values.dup
129
+ @long_values.push(stub(:inner_text => "vbad"))
130
+
131
+ @nil_keys = @keys.dup
132
+ @nil_keys.push(nil)
133
+ @nil_keys.push(:bang)
134
+
135
+ @nil_values = @long_values.dup
136
+ @nil_values.push(stub(:inner_text => "vbang"))
137
+ end
138
+
139
+ should "return false if there are no nodes" do
140
+ assert !@sln.extract_info(@keys, [])
141
+ end
142
+
143
+ should "return true if everything is good" do
144
+ assert @sln.extract_info(@keys, @values)
145
+ end
146
+
147
+ should "only extract as long as there are keys left" do
148
+ assert @sln.extract_info(@keys, @long_values)
149
+ assert_equal @keys.length, @sln.data.length
150
+
151
+ # It shouldn't get the 4th long value since there are only 3 keys
152
+ @sln.data.each { |k,v| assert_not_equal @long_values[@keys.length].inner_text, v }
153
+ end
154
+
155
+ should "extract values and associate them with proper keys" do
156
+ assert @sln.extract_info(@keys, @values)
157
+ assert_equal @keys.length, @sln.data.length
158
+
159
+ @sln.data.each do |k,v|
160
+ assert @keys.include?(k)
161
+ assert_equal @values[@keys.index(k)].inner_text, v
162
+ end
163
+ end
164
+
165
+ should "not store values associated with nil keys" do
166
+ assert @sln.extract_info(@nil_keys, @nil_values)
167
+ assert_equal (@nil_keys.length - 1), @sln.data.length
168
+
169
+ @nil_keys.each_index do |i|
170
+ key = @nil_keys[i]
171
+
172
+ # If the key is nil, it should NOT store the value
173
+ # at that index, otherwise it should
174
+ if key.nil?
175
+ assert !@sln.data.has_value?(@nil_values[i].inner_text)
176
+ else
177
+ assert_equal @nil_values[i].inner_text, @sln.data[key]
178
+ end
179
+ end
87
180
  end
88
181
  end
89
182
  end
@@ -1,3 +1,9 @@
1
+ require File.join(File.dirname(__FILE__), '..', '..', 'lib', 'myuw')
2
+ require 'test/unit'
3
+ require "contest"
4
+ require "stories"
5
+ require "mocha"
6
+
1
7
  class Test::Unit::TestCase
2
8
  def path_to_html(html)
3
9
  "file://" + File.join(File.dirname(__FILE__), 'fixture_pages', "#{html}.html")
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mitchellh-rubyuw
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.1
4
+ version: 0.6.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mitchell Hashimoto
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-06-29 00:00:00 -07:00
12
+ date: 2009-07-02 00:00:00 -07:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency