Refactoring tests
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -32,4 +32,6 @@ nosetests.xml
|
||||
# Idea
|
||||
.idea
|
||||
|
||||
# System
|
||||
.DS_Store
|
||||
|
||||
|
||||
@@ -12,18 +12,21 @@ class Api:
|
||||
|
||||
def __call__(self, environ, start_response):
|
||||
# PERF: Use literal constructor for dicts
|
||||
ctx, req, resp = {}, {}, {}
|
||||
# PERF: Don't use multi-assignment
|
||||
ctx = {}
|
||||
req = {}
|
||||
resp = {}
|
||||
|
||||
# TODO: What other things does req need?
|
||||
req['path'] = path = environ['PATH_INFO']
|
||||
|
||||
|
||||
# TODO
|
||||
# TODO
|
||||
# ctx.update(global_ctx_for_route)
|
||||
|
||||
# PERF: Use try...except blocks when errors are rare (otherwise use in)
|
||||
# PERF: Use try...except blocks when the key usually exists
|
||||
try:
|
||||
# TODO: Figure out a way to use codegen to make a state machine,
|
||||
# TODO: Figure out a way to use codegen to make a state machine,
|
||||
# may have to in order to support URI templates.
|
||||
handler = self.routes[path]
|
||||
except KeyError:
|
||||
@@ -42,7 +45,7 @@ class Api:
|
||||
pass
|
||||
|
||||
# PERF: Can't predict ratio of empty body to nonempty, so use
|
||||
# "in" which is a good all-around performer.
|
||||
# "in" which is a good all-around performer.
|
||||
return [resp['body']] if 'body' in resp else []
|
||||
|
||||
def add_route(self, uri_template, handler):
|
||||
|
||||
@@ -1,9 +1,14 @@
|
||||
import inspect
|
||||
import testtools
|
||||
|
||||
import falcon
|
||||
|
||||
class StartResponseMock:
|
||||
def __init__(self):
|
||||
self._called = 0
|
||||
self.status = None
|
||||
self.headers = None
|
||||
|
||||
|
||||
def __call__(self, status, headers):
|
||||
self._called += 1
|
||||
self.status = status
|
||||
@@ -12,6 +17,20 @@ class StartResponseMock:
|
||||
def call_count(self):
|
||||
return self._called
|
||||
|
||||
class TestSuite(testtools.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(TestSuite, self).setUp()
|
||||
self.api = falcon.Api()
|
||||
self.srmock = StartResponseMock()
|
||||
self.test_route = '/' + self.getUniqueString()
|
||||
|
||||
prepare = getattr(self, 'prepare', None)
|
||||
if hasattr(prepare, '__call__'):
|
||||
prepare()
|
||||
|
||||
def _simulate_request(self, path):
|
||||
self.api(create_environ(path), self.srmock)
|
||||
|
||||
def create_environ(path='/', query_string=''):
|
||||
return {
|
||||
|
||||
@@ -23,21 +23,11 @@ class RequestHandler:
|
||||
resp['status'] = falcon.HTTP_200
|
||||
resp['body'] = self.sample_body
|
||||
|
||||
class TestHeaders(testtools.TestCase):
|
||||
|
||||
# TODO: Figure out a way to DRY this statement - maybe via subclassing
|
||||
def setUp(self):
|
||||
super(TestHeaders, self).setUp()
|
||||
self.api = falcon.Api()
|
||||
self.srmock = helpers.StartResponseMock()
|
||||
self.test_route = '/' + self.getUniqueString()
|
||||
class TestHeaders(helpers.TestSuite):
|
||||
|
||||
def prepare(self):
|
||||
self.on_hello = RequestHandler()
|
||||
self.api.add_route(self.test_route, self.on_hello)
|
||||
|
||||
|
||||
def test_auto_headers(self):
|
||||
# TODO: Figure out a way to DRY this statement
|
||||
self.api(helpers.create_environ(self.test_route), self.srmock)
|
||||
|
||||
pass
|
||||
self._simulate_request(self.test_route)
|
||||
|
||||
@@ -20,28 +20,22 @@ class HelloRequestHandler:
|
||||
resp['body'] = self.sample_body
|
||||
|
||||
|
||||
class TestHelloWorld(testtools.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(TestHelloWorld, self).setUp()
|
||||
self.api = falcon.Api()
|
||||
self.start_resp = helpers.StartResponseMock()
|
||||
self.test_route = '/hello'
|
||||
class TestHelloWorld(helpers.TestSuite):
|
||||
|
||||
def prepare(self):
|
||||
self.on_hello = HelloRequestHandler()
|
||||
self.api.add_route(self.test_route, self.on_hello)
|
||||
|
||||
def test_hello_route_negative(self):
|
||||
bogus_route = self.test_route + 'x'
|
||||
self.api(helpers.create_environ(bogus_route), self.start_resp)
|
||||
self._simulate_request(bogus_route)
|
||||
|
||||
# Ensure the request was NOT routed to on_hello
|
||||
self.assertFalse(self.on_hello.called)
|
||||
self.assertThat(self.start_resp.status, Equals(falcon.HTTP_404))
|
||||
self.assertThat(self.srmock.status, Equals(falcon.HTTP_404))
|
||||
|
||||
def test_hello_route(self):
|
||||
# Simulate a request to the attached route
|
||||
self.api(helpers.create_environ(self.test_route), self.start_resp)
|
||||
self._simulate_request(self.test_route)
|
||||
resp = self.on_hello.resp
|
||||
|
||||
self.assertTrue('status' in resp)
|
||||
@@ -49,20 +43,3 @@ class TestHelloWorld(testtools.TestCase):
|
||||
|
||||
self.assertTrue('body' in resp)
|
||||
self.assertThat(resp['body'], Equals(self.on_hello.sample_body))
|
||||
|
||||
# TODO: Test compiling routes, throwing on invalid routes (such as missing initial forward slash or non-ascii)
|
||||
# TODO: Test setting the body to a stream, rather than a string (and content-length set to chunked?)
|
||||
# TODO: Test custom error handlers - customizing error document at least
|
||||
# TODO: Test async middleware ala rproxy
|
||||
# TODO: Test setting different routes for different verbs
|
||||
# TODO: Test throwing an exception from within a handler
|
||||
# TODO: Test neglecting to set a body
|
||||
# TODO: Test neglecting to set a status
|
||||
# TODO: Test passing bad arguments to add_route
|
||||
# TODO: Test other kinds of routes - empty, root, multiple levels
|
||||
# TODO: Test URI-template parsing (precompile)
|
||||
# TODO: Test passing a shared dict to each mock call (e.g., db connections, config)
|
||||
# ...and that it is passed to the request handler correctly
|
||||
# TODO: Test pre/post filters
|
||||
# TODO: Test error handling with standard response (for all error classes?)
|
||||
pass
|
||||
|
||||
17
test/todo.md
Normal file
17
test/todo.md
Normal file
@@ -0,0 +1,17 @@
|
||||
|
||||
* Test sending/receiving various status codes
|
||||
* Test compiling routes, throwing on invalid routes (such as missing initial forward slash or non-ascii)
|
||||
* Test setting the body to a stream, rather than a string (and content-length set to chunked?)
|
||||
* Test custom error handlers - customizing error document at least
|
||||
* Test async middleware ala rproxy
|
||||
* Test setting different routes for different verbs
|
||||
* Test throwing an exception from within a handler
|
||||
* Test neglecting to set a body
|
||||
* Test neglecting to set a status
|
||||
* Test passing bad arguments to add_route
|
||||
* Test other kinds of routes - empty, root, multiple levels
|
||||
* Test URI-template parsing (precompile)
|
||||
* Test passing a shared dict to each mock call (e.g., db connections, config)...and that it is passed to the request handler correctly
|
||||
* Test pre/post filters
|
||||
* Test error handling with standard response (for all error classes?)
|
||||
|
||||
Reference in New Issue
Block a user