fix: Achieve 100% code coverage across all environments
Python 3 was just shy of 100%. Getting it up there required some slight modifications to the way messages are logged to wsgi.errors, but this should not break any apps.
This commit is contained in:
@@ -19,8 +19,9 @@ limitations under the License.
|
||||
import re
|
||||
from functools import wraps
|
||||
|
||||
from falcon import responders, HTTP_METHODS
|
||||
import six
|
||||
|
||||
from falcon import responders, HTTP_METHODS
|
||||
import falcon.status_codes as status
|
||||
|
||||
|
||||
@@ -100,7 +101,8 @@ def get_body(resp):
|
||||
resp: Instance of falcon.Response
|
||||
|
||||
Returns:
|
||||
* If resp.body is not None, returns [resp.body], encoded as UTF-8.
|
||||
* If resp.body is not None, returns [resp.body], encoded as UTF-8 if
|
||||
it is a Unicode string. Bytestrings are returned as-is.
|
||||
* If resp.data is not None, returns [resp.data]
|
||||
* If resp.stream is not None, returns resp.stream
|
||||
* Otherwise, returns []
|
||||
@@ -110,9 +112,9 @@ def get_body(resp):
|
||||
body = resp.body
|
||||
|
||||
if body is not None:
|
||||
try:
|
||||
if isinstance(body, six.text_type):
|
||||
return [body.encode('utf-8')]
|
||||
except UnicodeDecodeError:
|
||||
else:
|
||||
return [body]
|
||||
|
||||
elif resp.data is not None:
|
||||
|
||||
@@ -21,7 +21,7 @@ import sys
|
||||
|
||||
if sys.version_info < (2, 7): # pragma: no cover
|
||||
from ordereddict import OrderedDict
|
||||
else:
|
||||
else: # pragma: no cover
|
||||
from collections import OrderedDict
|
||||
|
||||
|
||||
|
||||
@@ -24,8 +24,8 @@ from falcon.exceptions import HTTPBadRequest
|
||||
from falcon import util
|
||||
from falcon import request_helpers as helpers
|
||||
|
||||
DEFAULT_ERROR_LOG_FORMAT = ('{0:%Y-%m-%d %H:%M:%S} [FALCON] [ERROR]'
|
||||
' {1} {2}?{3} => {4}\n')
|
||||
DEFAULT_ERROR_LOG_FORMAT = (u'{0:%Y-%m-%d %H:%M:%S} [FALCON] [ERROR]'
|
||||
u' {1} {2}?{3} => ')
|
||||
|
||||
|
||||
class InvalidHeaderValueError(HTTPBadRequest):
|
||||
@@ -106,29 +106,32 @@ class Request(object):
|
||||
|
||||
self._headers = helpers.parse_headers(env)
|
||||
|
||||
def log_error(self, message):
|
||||
def log_error(self, message): # pragma: no cover
|
||||
"""Log an error to wsgi.error
|
||||
|
||||
Prepends timestamp and request info to message, and writes the
|
||||
result out to the WSGI server's error stream (wsgi.error).
|
||||
|
||||
Args:
|
||||
message: A string describing the problem. If a byte-string and
|
||||
running under Python 2, the string is assumed to be encoded
|
||||
as UTF-8.
|
||||
message: A string describing the problem. If a byte-string it is
|
||||
simply written out as-is. Unicode strings will be converted
|
||||
to UTF-8.
|
||||
|
||||
"""
|
||||
|
||||
if not six.PY3 and isinstance(message, unicode):
|
||||
message = message.encode('utf-8')
|
||||
|
||||
log_line = (
|
||||
DEFAULT_ERROR_LOG_FORMAT.
|
||||
format(datetime.now(), self.method, self.path,
|
||||
self.query_string, message)
|
||||
format(datetime.now(), self.method, self.path, self.query_string)
|
||||
)
|
||||
|
||||
self._wsgierrors.write(log_line)
|
||||
if six.PY3:
|
||||
self._wsgierrors.write(log_line + message + '\n')
|
||||
else:
|
||||
if isinstance(message, unicode):
|
||||
message = message.encode('utf-8')
|
||||
|
||||
self._wsgierrors.write(log_line.encode('utf-8'))
|
||||
self._wsgierrors.write(message + '\n')
|
||||
|
||||
@property
|
||||
def client_accepts_json(self):
|
||||
|
||||
@@ -101,17 +101,14 @@ class TestHelloWorld(testing.TestBase):
|
||||
self.assertEquals(resp.body, self.resource.sample_unicode)
|
||||
self.assertEquals(body, [self.resource.sample_utf8])
|
||||
|
||||
if not six.PY3:
|
||||
# On Python 3, strings are always Unicode,
|
||||
# so only perform this test under Python 2.
|
||||
def test_body_bytes(self):
|
||||
body = self.simulate_request('/bytes')
|
||||
resp = self.bytes_resource.resp
|
||||
def test_body_bytes(self):
|
||||
body = self.simulate_request('/bytes')
|
||||
resp = self.bytes_resource.resp
|
||||
|
||||
self.assertEquals(self.srmock.status, self.resource.sample_status)
|
||||
self.assertEquals(resp.status, self.resource.sample_status)
|
||||
self.assertEquals(resp.body, self.resource.sample_utf8)
|
||||
self.assertEquals(body, [self.resource.sample_utf8])
|
||||
self.assertEquals(self.srmock.status, self.resource.sample_status)
|
||||
self.assertEquals(resp.status, self.resource.sample_status)
|
||||
self.assertEquals(resp.body, self.resource.sample_utf8)
|
||||
self.assertEquals(body, [self.resource.sample_utf8])
|
||||
|
||||
def test_data(self):
|
||||
body = self.simulate_request('/data')
|
||||
|
||||
@@ -5,11 +5,6 @@ import six
|
||||
|
||||
unicode_message = u'Unicode: \x80'
|
||||
|
||||
if six.PY3:
|
||||
str_message = 'Unicode all the way: \x80'
|
||||
else:
|
||||
str_message = 'UTF-8: \xc2\x80'
|
||||
|
||||
|
||||
class LoggerResource:
|
||||
|
||||
@@ -17,7 +12,7 @@ class LoggerResource:
|
||||
req.log_error(unicode_message)
|
||||
|
||||
def on_head(self, req, resp):
|
||||
req.log_error(str_message)
|
||||
req.log_error(unicode_message.encode('utf-8'))
|
||||
|
||||
|
||||
class TestWSGIError(testing.TestBase):
|
||||
@@ -38,19 +33,19 @@ class TestWSGIError(testing.TestBase):
|
||||
# with undefined encoding, so do the encoding manually.
|
||||
self.wsgierrors = self.wsgierrors_buffer
|
||||
|
||||
def test_responder_logged_unicode(self):
|
||||
def test_responder_logged_bytestring(self):
|
||||
self.simulate_request('/logger', wsgierrors=self.wsgierrors)
|
||||
|
||||
log = self.wsgierrors_buffer.getvalue()
|
||||
|
||||
self.assertIn(unicode_message.encode('utf-8'), log)
|
||||
|
||||
def test_responder_logged_str(self):
|
||||
def test_responder_logged_unicode(self):
|
||||
if six.PY3:
|
||||
self.skipTest('Test only applies to Python 2')
|
||||
|
||||
self.simulate_request('/logger', wsgierrors=self.wsgierrors,
|
||||
method='HEAD')
|
||||
|
||||
log = self.wsgierrors_buffer.getvalue()
|
||||
|
||||
if six.PY3:
|
||||
self.assertIn(str_message.encode('utf-8'), log)
|
||||
else:
|
||||
self.assertIn(str_message, log)
|
||||
self.assertIn(unicode_message, log.decode('utf-8'))
|
||||
|
||||
Reference in New Issue
Block a user