Permalink
Browse files

Allow customization of Handler method decorator (tornado.web.asynchro…

…nous is just the default)
  • Loading branch information...
1 parent 666ced6 commit f2ac1a8ea2eb77fee1565fbb1e2c546768af59b3 @tatiana committed Mar 28, 2013
Showing with 50 additions and 8 deletions.
  1. +1 −1 setup.py
  2. +46 −6 tests/test_tornado_cors.py
  3. +2 −1 tornado_cors.py → tornado_cors/__init__.py
  4. +1 −0 tornado_cors/custom_decorator.py
View
@@ -13,7 +13,7 @@ def readfile(file_name):
setup(
name='tornado-cors',
- version='0.2.0',
+ version='0.3.0',
keywords='tornado cors',
author='globo.com',
author_email='guilherme.cirne@corp.globo.com',
View
@@ -1,18 +1,33 @@
# -*- coding: utf-8 -*-
-
+import imp
+import functools
from tornado.testing import AsyncHTTPTestCase
from tornado.web import Application, asynchronous, RequestHandler
-from tornado_cors import CorsMixin
+import tornado_cors as cors
+from tornado_cors import custom_decorator
+
+
+passed_by_custom_wrapper = False
+
+
+def custom_wrapper(method):
+ @functools.wraps(method)
+ def wrapper(self, *args, **kwargs):
+ result = method(self, *args, **kwargs)
+ return result
+ global passed_by_custom_wrapper
+ passed_by_custom_wrapper = id(wrapper)
+ return wrapper
class CorsTestCase(AsyncHTTPTestCase):
def test_should_return_headers_with_default_values_in_options_request(self):
self.http_client.fetch(self.get_url('/default'), self.stop, method='OPTIONS')
headers = self.wait().headers
-
+
self.assertNotIn('Access-Control-Allow-Origin', headers)
self.assertNotIn('Access-Control-Allow-Headers', headers)
self.assertEqual(headers['Access-Control-Allow-Methods'], 'PUT, POST, DELETE, OPTIONS')
@@ -36,7 +51,31 @@ def get_app(self):
return Application([(r'/default', DefaultValuesHandler), (r'/custom', CustomValuesHandler)])
-class DefaultValuesHandler(CorsMixin, RequestHandler):
+class CustomWrapperTestCase(AsyncHTTPTestCase):
+
+ def setUp(self):
+ self.original_wrapper = custom_decorator.wrapper
+
+ def tearDown(self):
+ custom_decorator.wrapper = self.original_wrapper
+
+ def test_wrapper_customization(self):
+ # assert default wrapper is being used
+ wrapper_module_name = cors.CorsMixin.options.im_func.func_code.co_filename
+ self.assertFalse(passed_by_custom_wrapper)
+ self.assertTrue(wrapper_module_name.endswith("tornado/web.py"))
+
+ # overwrite using custom wrapper and reload module
+ custom_decorator.wrapper = custom_wrapper
+ imp.reload(cors)
+
+ # assert new wrapper is being used
+ wrapper_module_name = cors.CorsMixin.options.im_func.func_code.co_filename
+ self.assertTrue(passed_by_custom_wrapper)
+ self.assertTrue(wrapper_module_name.endswith("tests/test_tornado_cors.py"))
+
+
+class DefaultValuesHandler(cors.CorsMixin, RequestHandler):
@asynchronous
def post(self):
@@ -50,8 +89,9 @@ def put(self):
def delete(self):
self.finish()
-class CustomValuesHandler(CorsMixin, RequestHandler):
-
+
+class CustomValuesHandler(cors.CorsMixin, RequestHandler):
+
CORS_ORIGIN = '*'
CORS_HEADERS = 'Content-Type'
CORS_METHODS = 'POST'
@@ -5,6 +5,7 @@
import logging
from tornado.web import asynchronous, RequestHandler
+from tornado_cors import custom_decorator
def _get_class_that_defined_method(meth):
@@ -24,7 +25,7 @@ def prepare(self):
if self.CORS_ORIGIN:
self.set_header('Access-Control-Allow-Origin', self.CORS_ORIGIN)
- @asynchronous
+ @custom_decorator.wrapper
def options(self, *args, **kwargs):
if self.CORS_HEADERS:
self.set_header('Access-Control-Allow-Headers', self.CORS_HEADERS)
@@ -0,0 +1 @@
+from tornado.web import asynchronous as wrapper

0 comments on commit f2ac1a8

Please sign in to comment.