Properly test raw writes in Python 3
Previously we were trying to test writing bytes in Python 3 using only native (unicode) string objects. That doesn't test what we thought we were testing. Change-Id: I10a0a38143d7f7d850ab9a7005ad87f5d314c375
This commit is contained in:
parent
92b8277752
commit
cf0b6c03df
tests/unit
@ -12,7 +12,6 @@
|
|||||||
# implied.
|
# implied.
|
||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
import testtools
|
import testtools
|
||||||
import threading
|
import threading
|
||||||
@ -206,10 +205,12 @@ class TestOutputManager(testtools.TestCase):
|
|||||||
u'some raw bytes: \u062A\u062A'.encode('utf-8'))
|
u'some raw bytes: \u062A\u062A'.encode('utf-8'))
|
||||||
|
|
||||||
thread_manager.print_items([
|
thread_manager.print_items([
|
||||||
('key', u'value'),
|
('key', 'value'),
|
||||||
('object', 'O\xcc\x88bject')
|
('object', u'O\u0308bject'),
|
||||||
])
|
])
|
||||||
|
|
||||||
|
thread_manager.print_raw(b'\xffugly\xffraw')
|
||||||
|
|
||||||
# Now we have a thread for error printing and a thread for
|
# Now we have a thread for error printing and a thread for
|
||||||
# normal print messages
|
# normal print messages
|
||||||
self.assertEqual(starting_thread_count + 2,
|
self.assertEqual(starting_thread_count + 2,
|
||||||
@ -220,31 +221,23 @@ class TestOutputManager(testtools.TestCase):
|
|||||||
|
|
||||||
if six.PY3:
|
if six.PY3:
|
||||||
over_the = "over the '\u062a\u062a'\n"
|
over_the = "over the '\u062a\u062a'\n"
|
||||||
# The CaptureStreamBuffer just encodes all bytes written to it by
|
|
||||||
# mapping chr over the byte string to produce a str.
|
|
||||||
raw_bytes = ''.join(
|
|
||||||
map(chr, u'some raw bytes: \u062A\u062A'.encode('utf-8'))
|
|
||||||
)
|
|
||||||
else:
|
else:
|
||||||
over_the = "over the u'\\u062a\\u062a'\n"
|
over_the = "over the u'\\u062a\\u062a'\n"
|
||||||
# We write to the CaptureStream so no decoding is performed
|
# We write to the CaptureStream so no decoding is performed
|
||||||
raw_bytes = 'some raw bytes: \xd8\xaa\xd8\xaa'
|
|
||||||
self.assertEqual(''.join([
|
self.assertEqual(''.join([
|
||||||
'one-argument\n',
|
'one-argument\n',
|
||||||
'one fish, 88 fish\n',
|
'one fish, 88 fish\n',
|
||||||
'some\n', 'where\n',
|
'some\n', 'where\n',
|
||||||
over_the, raw_bytes,
|
over_the,
|
||||||
|
u'some raw bytes: \u062a\u062a',
|
||||||
' key: value\n',
|
' key: value\n',
|
||||||
' object: O\xcc\x88bject\n'
|
u' object: O\u0308bject\n'
|
||||||
]), out_stream.getvalue())
|
]).encode('utf8') + b'\xffugly\xffraw', out_stream.getvalue())
|
||||||
|
|
||||||
first_item = u'I have 99 problems, but a \u062A\u062A is not one\n'
|
|
||||||
if six.PY2:
|
|
||||||
first_item = first_item.encode('utf8')
|
|
||||||
self.assertEqual(''.join([
|
self.assertEqual(''.join([
|
||||||
first_item,
|
u'I have 99 problems, but a \u062A\u062A is not one\n',
|
||||||
'one-error-argument\n',
|
'one-error-argument\n',
|
||||||
'Sometimes\n', '3.1% just\n', 'does not\n', 'work!\n'
|
'Sometimes\n', '3.1% just\n', 'does not\n', 'work!\n'
|
||||||
]), err_stream.getvalue())
|
]), err_stream.getvalue().decode('utf8'))
|
||||||
|
|
||||||
self.assertEqual(3, thread_manager.error_count)
|
self.assertEqual(3, thread_manager.error_count)
|
||||||
|
@ -381,28 +381,27 @@ class MockHttpTest(testtools.TestCase):
|
|||||||
reload_module(c)
|
reload_module(c)
|
||||||
|
|
||||||
|
|
||||||
class CaptureStreamBuffer(object):
|
class CaptureStreamPrinter(object):
|
||||||
"""
|
"""
|
||||||
CaptureStreamBuffer is used for testing raw byte writing for PY3. Anything
|
CaptureStreamPrinter is used for testing unicode writing for PY3. Anything
|
||||||
written here is decoded as utf-8 and written to the parent CaptureStream
|
written here is encoded as utf-8 and written to the parent CaptureStream
|
||||||
"""
|
"""
|
||||||
def __init__(self, captured_stream):
|
def __init__(self, captured_stream):
|
||||||
self._captured_stream = captured_stream
|
self._captured_stream = captured_stream
|
||||||
|
|
||||||
def write(self, bytes_data):
|
def write(self, data):
|
||||||
# No encoding, just convert the raw bytes into a str for testing
|
# No encoding, just convert the raw bytes into a str for testing
|
||||||
# The below call also validates that we have a byte string.
|
# The below call also validates that we have a byte string.
|
||||||
self._captured_stream.write(
|
self._captured_stream.write(
|
||||||
''.join(map(chr, bytes_data))
|
data if isinstance(data, six.binary_type) else data.encode('utf8'))
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class CaptureStream(object):
|
class CaptureStream(object):
|
||||||
|
|
||||||
def __init__(self, stream):
|
def __init__(self, stream):
|
||||||
self.stream = stream
|
self.stream = stream
|
||||||
self._capture = six.StringIO()
|
self._buffer = six.BytesIO()
|
||||||
self._buffer = CaptureStreamBuffer(self)
|
self._capture = CaptureStreamPrinter(self._buffer)
|
||||||
self.streams = [self._capture]
|
self.streams = [self._capture]
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@ -425,11 +424,11 @@ class CaptureStream(object):
|
|||||||
stream.writelines(*args, **kwargs)
|
stream.writelines(*args, **kwargs)
|
||||||
|
|
||||||
def getvalue(self):
|
def getvalue(self):
|
||||||
return self._capture.getvalue()
|
return self._buffer.getvalue()
|
||||||
|
|
||||||
def clear(self):
|
def clear(self):
|
||||||
self._capture.truncate(0)
|
self._buffer.truncate(0)
|
||||||
self._capture.seek(0)
|
self._buffer.seek(0)
|
||||||
|
|
||||||
|
|
||||||
class CaptureOutput(object):
|
class CaptureOutput(object):
|
||||||
@ -467,11 +466,11 @@ class CaptureOutput(object):
|
|||||||
|
|
||||||
@property
|
@property
|
||||||
def out(self):
|
def out(self):
|
||||||
return self._out.getvalue()
|
return self._out.getvalue().decode('utf8')
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def err(self):
|
def err(self):
|
||||||
return self._err.getvalue()
|
return self._err.getvalue().decode('utf8')
|
||||||
|
|
||||||
def clear(self):
|
def clear(self):
|
||||||
self._out.clear()
|
self._out.clear()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user