[wwwsearch-commits] r32987 - in wwwsearch/mechanize/trunk: mechanize test
jjlee at codespeak.net
jjlee at codespeak.net
Sat Oct 7 14:53:15 CEST 2006
Author: jjlee
Date: Sat Oct 7 14:53:13 2006
New Revision: 32987
Added:
wwwsearch/mechanize/trunk/test/test_browser.doctest
Modified:
wwwsearch/mechanize/trunk/mechanize/_html.py
wwwsearch/mechanize/trunk/mechanize/_mechanize.py
wwwsearch/mechanize/trunk/mechanize/_seek.py
wwwsearch/mechanize/trunk/mechanize/_upgrade.py
wwwsearch/mechanize/trunk/test/test_browser.py
Log:
Fix a bunch of problems with Browser and Factory not handling None responses correctly; Add some tests
Modified: wwwsearch/mechanize/trunk/mechanize/_html.py
==============================================================================
--- wwwsearch/mechanize/trunk/mechanize/_html.py (original)
+++ wwwsearch/mechanize/trunk/mechanize/_html.py Sat Oct 7 14:53:13 2006
@@ -480,8 +480,8 @@
def set_response(self, response):
"""Set response.
- The response must implement the same interface as objects returned by
- urllib2.urlopen().
+ The response must either be None or implement the same interface as
+ objects returned by urllib2.urlopen().
"""
self._response = response
Modified: wwwsearch/mechanize/trunk/mechanize/_mechanize.py
==============================================================================
--- wwwsearch/mechanize/trunk/mechanize/_mechanize.py (original)
+++ wwwsearch/mechanize/trunk/mechanize/_mechanize.py Sat Oct 7 14:53:13 2006
@@ -98,8 +98,6 @@
if history is None:
history = History()
self._history = history
- self.request = self._response = None
- self.form = None
if request_class is None:
if not hasattr(urllib2.Request, "add_unredirected_header"):
@@ -113,6 +111,9 @@
self._factory = factory
self.request_class = request_class
+ self.request = None
+ self.set_response(None)
+
UserAgent.__init__(self) # do this last to avoid __getattr__ problems
def close(self):
@@ -208,15 +209,23 @@
return copy.copy(self._response)
def set_response(self, response):
- """Replace current response with (a copy of) response."""
+ """Replace current response with (a copy of) response.
+
+ response may be None.
+ """
# sanity check, necessary but far from sufficient
- if not (hasattr(response, "info") and hasattr(response, "geturl") and
- hasattr(response, "read")):
+ if not (response is None or
+ (hasattr(response, "info") and hasattr(response, "geturl") and
+ hasattr(response, "read")
+ )
+ ):
raise ValueError("not a response object")
self.form = None
- self._response = _upgrade.upgrade_response(response)
- self._factory.set_response(self._response)
+ if response is not None:
+ response = _upgrade.upgrade_response(response)
+ self._response = response
+ self._factory.set_response(response)
def geturl(self):
"""Get URL of current document."""
Modified: wwwsearch/mechanize/trunk/mechanize/_seek.py
==============================================================================
--- wwwsearch/mechanize/trunk/mechanize/_seek.py (original)
+++ wwwsearch/mechanize/trunk/mechanize/_seek.py Sat Oct 7 14:53:13 2006
@@ -6,6 +6,6 @@
"""Make responses seekable."""
def any_response(self, request, response):
- if not hasattr(response, "seek"):
+ if response is not None and not hasattr(response, "seek"):
return response_seek_wrapper(response)
return response
Modified: wwwsearch/mechanize/trunk/mechanize/_upgrade.py
==============================================================================
--- wwwsearch/mechanize/trunk/mechanize/_upgrade.py (original)
+++ wwwsearch/mechanize/trunk/mechanize/_upgrade.py Sat Oct 7 14:53:13 2006
@@ -27,6 +27,7 @@
# upgrade responses to be .close()able without becoming unusable
handler_order = 0 # before anything else
def any_response(self, request, response):
- if not hasattr(response, 'closeable_response'):
+ if (response is not None and
+ not hasattr(response, 'closeable_response')):
response = upgrade_response(response)
return response
Added: wwwsearch/mechanize/trunk/test/test_browser.doctest
==============================================================================
--- (empty file)
+++ wwwsearch/mechanize/trunk/test/test_browser.doctest Sat Oct 7 14:53:13 2006
@@ -0,0 +1,32 @@
+>>> from test_browser import TestBrowser, TestBrowser2
+
+Warn early about some mistakes setting a response object
+
+>>> import StringIO
+>>> br = TestBrowser()
+>>> br.set_response("blah")
+Traceback (most recent call last):
+...
+ValueError: not a response object
+>>> br.set_response(StringIO.StringIO())
+Traceback (most recent call last):
+...
+ValueError: not a response object
+
+
+.open() without an appropriate scheme handler should fail with
+URLError
+
+>>> br = TestBrowser2()
+>>> br.open("http://example.com")
+Traceback (most recent call last):
+...
+URLError: <urlopen error unknown url type: http>
+
+Reload after failed .open() should fail due to failure to open, not
+with BrowserStateError
+
+>>> br.reload()
+Traceback (most recent call last):
+...
+URLError: <urlopen error unknown url type: http>
Modified: wwwsearch/mechanize/trunk/test/test_browser.py
==============================================================================
--- wwwsearch/mechanize/trunk/test/test_browser.py (original)
+++ wwwsearch/mechanize/trunk/test/test_browser.py Sat Oct 7 14:53:13 2006
@@ -105,6 +105,15 @@
default_others = []
default_schemes = []
+class TestBrowser2(mechanize.Browser):
+ # XXX better name!
+ # As TestBrowser, this is neutered so doesn't know about protocol handling,
+ # but still knows what to do with unknown schemes, etc., because
+ # UserAgent's default_others list is left intact, including classes like
+ # UnknownHandler
+ default_features = ["_seek"]
+ default_schemes = []
+
class BrowserTests(TestCase):
@@ -328,17 +337,44 @@
url = "http://example.com/"
b = TestBrowser()
- b.add_handler(make_mock_handler()([("http_open", MockResponse(url, "", {}))]))
+
+ self.assert_(b.response() is None)
+
+ # To open a relative reference (often called a "relative URL"), you
+ # have to have already opened a URL for it "to be relative to".
+ self.assertRaises(mechanize.BrowserStateError, b.open, "relative_ref")
+
+ # we can still clear the history even if we've not visited any URL
+ b.clear_history()
+
+ # most methods raise BrowserStateError...
+ def test_state_error(method_names):
+ for attr in method_names:
+ method = getattr(b, attr)
+ #print attr
+ self.assertRaises(mechanize.BrowserStateError, method)
+ self.assertRaises(mechanize.BrowserStateError, b.select_form,
+ name="blah")
+ self.assertRaises(mechanize.BrowserStateError, b.find_link,
+ name="blah")
+ # ...if not visiting a URL...
+ test_state_error(("geturl reload back viewing_html encoding "
+ "click links forms title select_form".split()))
+ self.assertRaises(mechanize.BrowserStateError, b.set_cookie, "foo=bar")
+ self.assertRaises(mechanize.BrowserStateError, b.submit, nr=0)
+ self.assertRaises(mechanize.BrowserStateError, b.click_link, nr=0)
+ self.assertRaises(mechanize.BrowserStateError, b.follow_link, nr=0)
+ self.assertRaises(mechanize.BrowserStateError, b.find_link, nr=0)
+ # ...and lots do so if visiting a non-HTML URL
+ b.add_handler(make_mock_handler()(
+ [("http_open", MockResponse(url, "", {}))]))
r = b.open(url)
self.assert_(not b.viewing_html())
- self.assertRaises(mechanize.BrowserStateError, b.links)
- self.assertRaises(mechanize.BrowserStateError, b.forms)
- self.assertRaises(mechanize.BrowserStateError, b.title)
- self.assertRaises(mechanize.BrowserStateError, b.select_form)
- self.assertRaises(mechanize.BrowserStateError, b.select_form,
- name="blah")
- self.assertRaises(mechanize.BrowserStateError, b.find_link,
- name="blah")
+ test_state_error("click links forms title select_form".split())
+ self.assertRaises(mechanize.BrowserStateError, b.submit, nr=0)
+ self.assertRaises(mechanize.BrowserStateError, b.click_link, nr=0)
+ self.assertRaises(mechanize.BrowserStateError, b.follow_link, nr=0)
+ self.assertRaises(mechanize.BrowserStateError, b.find_link, nr=0)
b = TestBrowser()
r = MockResponse(url,
More information about the wwwsearch-commits
mailing list