Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Create TestWSGI class for testing mod_genshi apps.

The TestWSGI class sub classes from unittest.TestCase. Each sub class
will have a new mod_genshi application created for testing.
  • Loading branch information...
commit 0c586250a77dd37b87bf8e9c7e26595708187e63 1 parent b0de482
Aaron Iles authored
View
97 mod_genshi/wsgitest.py
@@ -0,0 +1,97 @@
+try:
+ import unittest2 as unittest
+except ImportError:
+ import unittest
+
+import string
+
+import webob
+
+import mod_genshi.wsgi
+
+__all__ = ['TestWSGI']
+
+
+class TestWSGIType(type):
+ """Base type for TestWSGI
+
+ To allow sub classes to define a setUpClass method, this type meta class
+ will rename the setUpClass method on sub classes to a unique name that
+ is called by the setUpClass method of TestWSGI.
+ """
+
+ @staticmethod
+ def unused_name(suffix, names):
+ """Create new, unique name with a given suffix."""
+ for letter in string.letters:
+ name = "_{0}_{1}".format(letter, suffix)
+ if name not in names:
+ break
+ return name
+
+ @classmethod
+ def rename_method(meta, method, classdict):
+ """Rename class method to new, unique name with same suffix."""
+ if method in classdict:
+ function = classdict[method]
+ name = meta.unused_name(method, set(classdict.keys()))
+ del classdict[method]
+ classdict[name] = function
+
+ def __new__(meta, classname, bases, classdict):
+ if classname != 'TestWSGI':
+ meta.rename_method('setUpClass', classdict)
+ meta.rename_method('tearDownClass', classdict)
+ return type.__new__(meta, classname, bases, classdict)
+
+
+class TestWSGI(unittest.TestCase):
+ """Subclass of unittest.TestCase for WSGI application testing.
+
+ This class also provides the following methods.
+
+ - get_request(url), create a new WSGI request object for URL.
+ - get_response(request), generate the application response for request.
+
+ Each sub class of this class will have an APPLICATION attribute. This is a
+ new mod_genshi WSGI application. The base directory of the application
+ will default to the current directory. This can be over ridden by creating
+ a new BASE class attribute.
+
+ Sub classes may define a setUpClass and tearDownClass.
+ """
+
+ __metaclass__ = TestWSGIType
+
+ @classmethod
+ def _call_suffixes(cls, suffix):
+ for name in dir(cls):
+ if not name.endswith(suffix) or name == suffix:
+ continue
+ attr = getattr(cls, name)
+ if not hasattr(attr, '__call__'):
+ continue
+ attr()
+
+ @classmethod
+ def setUpClass(cls):
+ """Create a new mod_genshi WSGI application."""
+ if not hasattr(cls, 'BASE'):
+ cls.BASE = '.'
+ cls.APPLICATION = mod_genshi.wsgi.WSGI(cls.BASE)
+ cls._call_suffixes('setUpClass')
+
+ @classmethod
+ def tearDownClass(cls):
+ """Shutdown the mod_genshi WSGI application."""
+ if hasattr(cls, 'APPLICATION'):
+ del cls.APPLICATION
+ cls._call_suffixes('tearDownClass')
+
+ def get_request(self, url):
+ """Create a new WSGI request object from the given URL."""
+ return webob.Request.blank(url)
+
+ def get_response(self, request):
+ """Generate a WSGI response for the given request."""
+ return request.get_response(self.APPLICATION)
View
62 tests/test_requests.py
@@ -1,81 +1,71 @@
import os
import sys
-import unittest2
+import mod_genshi.wsgitest
-from webob import Request
-import mod_genshi.wsgi
+class TestRequests(mod_genshi.wsgitest.TestWSGI):
-class TestRequests(unittest2.TestCase):
-
- @classmethod
- def setUpClass(cls):
- cls.App = mod_genshi.wsgi.WSGI('tests/app')
-
- @classmethod
- def tearDownClass(cls):
- if hasattr(cls, 'App'):
- del cls.App
+ BASE = 'tests/app'
def test_hello_world_html(self):
path = 'templates/hello_world.html'
- with open(os.path.join(self.App.config.base, path), 'rt') as template:
+ with open(os.path.join(self.BASE, path), 'rt') as template:
content = template.read()
- request = Request.blank(path)
- response = request.get_response(self.App)
+ request = self.get_request(path)
+ response = self.get_response(request)
self.assertEqual(response.status_int, 200)
self.assertEqual(response.content_type, 'text/html')
self.assertEqual(response.body, content)
def test_hello_world_text(self):
path = 'templates/hello_world.txt'
- with open(os.path.join(self.App.config.base, path), 'rt') as template:
+ with open(os.path.join(self.BASE, path), 'rt') as template:
content = template.read()
- request = Request.blank(path)
- response = request.get_response(self.App)
+ request = self.get_request(path)
+ response = self.get_response(request)
self.assertEqual(response.status_int, 200)
self.assertEqual(response.content_type, 'text/plain')
self.assertEqual(response.body, content)
def test_static_file(self):
path = 'static/logo.png'
- with open(os.path.join(self.App.config.base, path), 'rb') as template:
+ with open(os.path.join(self.BASE, path), 'rb') as template:
content = template.read()
- request = Request.blank(path)
- response = request.get_response(self.App)
+ request = self.get_request(path)
+ response = self.get_response(request)
self.assertEqual(response.status_int, 200)
self.assertEqual(response.content_type, 'image/png')
self.assertEqual(response.body, content)
def test_forbidden(self):
path = 'static/passwd'
- request = Request.blank(path)
- response = request.get_response(self.App)
+ request = self.get_request(path)
+ response = self.get_response(request)
self.assertEqual(response.status_int, 403)
def test_not_found_generic(self):
path = 'static/_does_not_exist_'
- request = Request.blank(path)
- response = request.get_response(self.App)
+ request = self.get_request(path)
+ response = self.get_response(request)
self.assertEqual(response.status_int, 403)
def test_not_found_template(self):
path = 'templates/_does_not_exist_.html'
- request = Request.blank(path)
- response = request.get_response(self.App)
+ request = self.get_request(path)
+ response = self.get_response(request)
self.assertEqual(response.status_int, 404)
def test_not_found_static(self):
path = 'static/_does_not_exist_.png'
- request = Request.blank(path)
- response = request.get_response(self.App)
+ request = self.get_request(path)
+ response = self.get_response(request)
self.assertEqual(response.status_int, 404)
def test_server_error(self):
path = 'templates/invalid.html'
- request = Request.blank(path)
- response = request.get_response(self.App)
+ request = self.get_request(path)
+ response = self.get_response(request)
self.assertEqual(response.status_int, 500)
def test_reload_python(self):
@@ -88,12 +78,12 @@ def set_counter():
# initialise
set_counter()
# request one
- request = Request.blank(path)
- request.get_response(self.App)
+ request = self.get_request(path)
+ self.get_response(request)
self.assertEqual(sys.modules['python.counter'].value, 2)
# initiate reload
os.utime(code, None)
# request two
- request = Request.blank(path)
- request.get_response(self.App)
+ request = self.get_request(path)
+ self.get_response(request)
self.assertEqual(sys.modules['python.counter'].value, 1)
View
12 tests/test_server.py
@@ -6,9 +6,7 @@
class TestBrowserCommnd(unittest2.TestCase):
- @classmethod
- def setUpClass(cls):
- cls.url = "http://{0}:8000".format(socket.gethostname())
+ URL = "http://{0}:8000".format(socket.gethostname())
def test_nothing(self):
opts = parse_command_line([])
@@ -18,23 +16,23 @@ def test_nothing(self):
def test_current_window(self):
opts = parse_command_line(['-b'])
cmd = open_browser_cmd(opts)
- self.assertEqual(cmd.args, (self.url,))
+ self.assertEqual(cmd.args, (self.URL,))
self.assertEqual(cmd.keywords, {'new': 0, 'autoraise': False})
def test_raise_current_window(self):
opts = parse_command_line(['-b', '-r'])
cmd = open_browser_cmd(opts)
- self.assertEqual(cmd.args, (self.url,))
+ self.assertEqual(cmd.args, (self.URL,))
self.assertEqual(cmd.keywords, {'new': 0, 'autoraise': True})
def test_new_window(self):
opts = parse_command_line(['-w'])
cmd = open_browser_cmd(opts)
- self.assertEqual(cmd.args, (self.url,))
+ self.assertEqual(cmd.args, (self.URL,))
self.assertEqual(cmd.keywords, {'new': 1, 'autoraise': False})
def test_new_tab(self):
opts = parse_command_line(['-t', '-r'])
cmd = open_browser_cmd(opts)
- self.assertEqual(cmd.args, (self.url,))
+ self.assertEqual(cmd.args, (self.URL,))
self.assertEqual(cmd.keywords, {'new': 2, 'autoraise': True})
View
41 tests/test_wsgi.py
@@ -1,12 +1,13 @@
import os
import sys
-import unittest2
-
import mod_genshi.wsgi
+import mod_genshi.wsgitest
+
+class ModGenshiApp(mod_genshi.wsgitest.TestWSGI):
-class ModGenshiApp(object):
+ BASE = 'tests/app'
Markup = mod_genshi.wsgi.MarkupTemplate
Text = mod_genshi.wsgi.NewTextTemplate
@@ -14,26 +15,20 @@ class ModGenshiApp(object):
@classmethod
def setUpClass(cls):
- cls.App = mod_genshi.wsgi.WSGI('tests/app')
- cls.body = cls.App._body
- cls.cwd = cls.App.config.templatedir
- cls.get_path = cls.App._get_basic_path
- cls.get_style = cls.App._get_template_style
- cls.is_blocked = cls.App._is_path_blocked
- cls.is_static = cls.App._is_static_path_blocked
- cls.set_headers = cls.App._headers
-
- @classmethod
- def tearDownClass(cls):
- if hasattr(cls, 'App'):
- del cls.App
+ cls.body = cls.APPLICATION._body
+ cls.cwd = cls.APPLICATION.config.templatedir
+ cls.get_path = cls.APPLICATION._get_basic_path
+ cls.get_style = cls.APPLICATION._get_template_style
+ cls.is_blocked = cls.APPLICATION._is_path_blocked
+ cls.is_static = cls.APPLICATION._is_static_path_blocked
+ cls.set_headers = cls.APPLICATION._headers
def setUp(self):
self.request = mod_genshi.wsgi.Request({})
self.response = mod_genshi.wsgi.Response()
-class TestTemplatePath(ModGenshiApp, unittest2.TestCase):
+class TestTemplatePath(ModGenshiApp):
def test_empty_path(self):
self.assertEqual(self.get_path(''), 'index.html')
@@ -54,7 +49,7 @@ def test_trailing_slash(self):
self.assertEqual(self.get_path('a/'), 'a/index.html')
-class TestStyle(ModGenshiApp, unittest2.TestCase):
+class TestStyle(ModGenshiApp):
def test_htm(self):
self.assertIs(self.get_style('file.htm'), self.Markup)
@@ -81,7 +76,7 @@ def test_unknown(self):
self.assertIs(self.get_style('file.xxx'), None)
-class TestSecurity(ModGenshiApp, unittest2.TestCase):
+class TestSecurity(ModGenshiApp):
def test_index(self):
path = 'index.html'
@@ -116,7 +111,7 @@ def test_static_file(self):
self.assertRaises(self.HTTPForbidden, self.is_static, path)
-class TestHeaders(ModGenshiApp, unittest2.TestCase):
+class TestHeaders(ModGenshiApp):
def test_default(self):
self.set_headers('', self.response)
@@ -143,17 +138,17 @@ def test_gz(self):
self.assertEqual(self.response.status_code, 200)
-class TestBody(ModGenshiApp, unittest2.TestCase):
+class TestBody(ModGenshiApp):
def test_hello_world_txt(self):
path = 'templates/hello_world.txt'
- content = open(os.path.join(self.App.config.base, path), 'rt').read()
+ content = open(os.path.join(self.BASE, path), 'rt').read()
self.body(path, self.Text, self.request, self.response)
self.assertEqual(self.response.body, content)
def test_hello_world_html(self):
path = 'templates/hello_world.html'
- content = open(os.path.join(self.App.config.base, path), 'rt').read()
+ content = open(os.path.join(self.BASE, path), 'rt').read()
self.body(path, self.Markup, self.request, self.response)
self.assertEqual(self.response.body, content)
Please sign in to comment.
Something went wrong with that request. Please try again.