diff options
| author | Robert Collins <robertc@robertcollins.net> | 2013-03-03 22:28:51 +1300 |
|---|---|---|
| committer | Robert Collins <robertc@robertcollins.net> | 2013-03-03 22:28:51 +1300 |
| commit | b1d5d5881f378273ce0dc8d8301d4ba25bcd4988 (patch) | |
| tree | 5731c7f2a9f000a5c6aa6784311dd901146dd1a6 /python | |
| parent | 1565f398b5520f45be1852c3d8a8ffdcf8dccfe2 (diff) | |
| download | subunit-git-b1d5d5881f378273ce0dc8d8301d4ba25bcd4988.tar.gz | |
Port existing filters to v2.
Diffstat (limited to 'python')
| -rw-r--r-- | python/subunit/__init__.py | 98 | ||||
| -rw-r--r-- | python/subunit/filters.py | 59 | ||||
| -rw-r--r-- | python/subunit/tests/test_subunit_tags.py | 61 | ||||
| -rw-r--r-- | python/subunit/tests/test_tap2subunit.py | 374 |
4 files changed, 287 insertions, 305 deletions
diff --git a/python/subunit/__init__.py b/python/subunit/__init__.py index ced5b4a..ad749ff 100644 --- a/python/subunit/__init__.py +++ b/python/subunit/__init__.py @@ -143,7 +143,7 @@ try: except ImportError: raise ImportError ("testtools.testresult.real does not contain " "_StringException, check your version.") -from testtools import testresult +from testtools import testresult, CopyStreamResult from subunit import chunked, details, iso8601, test_results from subunit.v2 import ByteStreamToStreamResult, StreamResultToBytes @@ -993,44 +993,51 @@ def run_isolated(klass, self, result): return result -def TAP2SubUnit(tap, subunit): +def TAP2SubUnit(tap, output_stream): """Filter a TAP pipe into a subunit pipe. - :param tap: A tap pipe/stream/file object. + This should be invoked once per TAP script, as TAP scripts get + mapped to a single runnable case with multiple components. + + :param tap: A tap pipe/stream/file object - should emit unicode strings. :param subunit: A pipe/stream/file object to write subunit results to. :return: The exit code to exit with. """ + output = StreamResultToBytes(output_stream) + UTF8_TEXT = 'text/plain; charset=UTF8' BEFORE_PLAN = 0 AFTER_PLAN = 1 SKIP_STREAM = 2 state = BEFORE_PLAN plan_start = 1 plan_stop = 0 - def _skipped_test(subunit, plan_start): - # Some tests were skipped. - subunit.write('test test %d\n' % plan_start) - subunit.write('error test %d [\n' % plan_start) - subunit.write('test missing from TAP output\n') - subunit.write(']\n') - return plan_start + 1 # Test data for the next test to emit test_name = None log = [] result = None + def missing_test(plan_start): + output.status(test_id='test %d' % plan_start, + test_status='fail', runnable=False, + mime_type=UTF8_TEXT, eof=True, file_name="tap meta", + file_bytes=b"test missing from TAP output") def _emit_test(): "write out a test" if test_name is None: return - subunit.write("test %s\n" % test_name) - if not log: - subunit.write("%s %s\n" % (result, test_name)) - else: - subunit.write("%s %s [\n" % (result, test_name)) if log: - for line in log: - subunit.write("%s\n" % line) - subunit.write("]\n") + log_bytes = b'\n'.join(log_line.encode('utf8') for log_line in log) + mime_type = UTF8_TEXT + file_name = 'tap comment' + eof = True + else: + log_bytes = None + mime_type = None + file_name = None + eof = True del log[:] + output.status(test_id=test_name, test_status=result, + file_bytes=log_bytes, mime_type=mime_type, eof=eof, + file_name=file_name, runnable=False) for line in tap: if state == BEFORE_PLAN: match = re.match("(\d+)\.\.(\d+)\s*(?:\#\s+(.*))?\n", line) @@ -1041,10 +1048,9 @@ def TAP2SubUnit(tap, subunit): if plan_start > plan_stop and plan_stop == 0: # skipped file state = SKIP_STREAM - subunit.write("test file skip\n") - subunit.write("skip file skip [\n") - subunit.write("%s\n" % comment) - subunit.write("]\n") + output.status(test_id='file skip', test_status='skip', + file_bytes=comment.encode('utf8'), eof=True, + file_name='tap comment') continue # not a plan line, or have seen one before match = re.match("(ok|not ok)(?:\s+(\d+)?)?(?:\s+([^#]*[^#\s]+)\s*)?(?:\s+#\s+(TODO|SKIP|skip|todo)(?:\s+(.*))?)?\n", line) @@ -1055,7 +1061,7 @@ def TAP2SubUnit(tap, subunit): if status == 'ok': result = 'success' else: - result = "failure" + result = "fail" if description is None: description = '' else: @@ -1070,7 +1076,8 @@ def TAP2SubUnit(tap, subunit): if number is not None: number = int(number) while plan_start < number: - plan_start = _skipped_test(subunit, plan_start) + missing_test(plan_start) + plan_start += 1 test_name = "test %d%s" % (plan_start, description) plan_start += 1 continue @@ -1083,18 +1090,21 @@ def TAP2SubUnit(tap, subunit): extra = ' %s' % reason _emit_test() test_name = "Bail out!%s" % extra - result = "error" + result = "fail" state = SKIP_STREAM continue match = re.match("\#.*\n", line) if match: log.append(line[:-1]) continue - subunit.write(line) + # Should look at buffering status and binding this to the prior result. + output.status(file_bytes=line.encode('utf8'), file_name='stdout', + mime_type=UTF8_TEXT) _emit_test() while plan_start <= plan_stop: # record missed tests - plan_start = _skipped_test(subunit, plan_start) + missing_test(plan_start) + plan_start += 1 return 0 @@ -1122,24 +1132,21 @@ def tag_stream(original, filtered, tags): :return: 0 """ new_tags, gone_tags = tags_to_new_gone(tags) - def write_tags(new_tags, gone_tags): - if new_tags or gone_tags: - filtered.write("tags: " + ' '.join(new_tags)) - if gone_tags: - for tag in gone_tags: - filtered.write("-" + tag) - filtered.write("\n") - write_tags(new_tags, gone_tags) - # TODO: use the protocol parser and thus don't mangle test comments. - for line in original: - if line.startswith("tags:"): - line_tags = line[5:].split() - line_new, line_gone = tags_to_new_gone(line_tags) - line_new = line_new - gone_tags - line_gone = line_gone - new_tags - write_tags(line_new, line_gone) - else: - filtered.write(line) + source = ByteStreamToStreamResult(original, non_subunit_name='stdout') + class Tagger(CopyStreamResult): + def status(self, **kwargs): + tags = kwargs.get('test_tags') + if not tags: + tags = set() + tags.update(new_tags) + tags.difference_update(gone_tags) + if tags: + kwargs['test_tags'] = tags + else: + kwargs['test_tags'] = None + super(Tagger, self).status(**kwargs) + output = Tagger([StreamResultToBytes(filtered)]) + source.run(output) return 0 @@ -1292,6 +1299,7 @@ def make_stream_binary(stream): _make_binary_on_windows(fileno) return _unwrap_text(stream) + def _make_binary_on_windows(fileno): """Win32 mangles \r\n to \n and that breaks streams. See bug lp:505078.""" if sys.platform == "win32": diff --git a/python/subunit/filters.py b/python/subunit/filters.py index be3b6b8..bc9ddef 100644 --- a/python/subunit/filters.py +++ b/python/subunit/filters.py @@ -17,12 +17,14 @@ from optparse import OptionParser import sys -from testtools import StreamResultRouter +from extras import safe_hasattr +from testtools import CopyStreamResult, StreamResult, StreamResultRouter from subunit import ( DiscardStream, ProtocolTestCase, ByteStreamToStreamResult, StreamResultToBytes, ) +from subunit.test_results import CatFiles def make_options(description): @@ -36,12 +38,13 @@ def make_options(description): help="Send the output to this path rather than stdout.") parser.add_option( "-f", "--forward", action="store_true", default=False, - help="Forward subunit stream on stdout.") + help="Forward subunit stream on stdout. When set, received " + "non-subunit output will be encapsulated in subunit.") return parser def run_tests_from_stream(input_stream, result, passthrough_stream=None, - forward_stream=None, protocol_version=1): + forward_stream=None, protocol_version=1, passthrough_subunit=True): """Run tests from a subunit input stream through 'result'. Non-test events - top level file attachments - are expected to be @@ -57,32 +60,48 @@ def run_tests_from_stream(input_stream, result, passthrough_stream=None, sent to this stream. If not provided, uses the ``TestProtocolServer`` default, which is ``sys.stdout``. :param forward_stream: All subunit input received will be forwarded - to this stream. If not provided, uses the ``TestProtocolServer`` - default, which is to not forward any input. + to this stream. If not provided, uses the ``TestProtocolServer`` + default, which is to not forward any input. Do not set this when + transforming the stream - items would be double-reported. :param protocol_version: What version of the subunit protocol to expect. + :param passthrough_subunit: If True, passthrough should be as subunit + otherwise unwrap it. Only has effect when forward_stream is None. + (when forwarding as subunit non-subunit input is always turned into + subunit) """ - orig_result = None if 1==protocol_version: test = ProtocolTestCase( input_stream, passthrough=passthrough_stream, forward=forward_stream) elif 2==protocol_version: - if passthrough_stream is not None: - # As the StreamToExtendedDecorator discards non-test events - # we merely have to copy them IFF they are requested. - passthrough_result = StreamResultToBytes(passthrough_stream) - orig_result = result + # In all cases we encapsulate unknown inputs. + if forward_stream is not None: + # Send events to forward_stream as subunit. + forward_result = StreamResultToBytes(forward_stream) + # If we're passing non-subunit through, copy: + if passthrough_stream is None: + # Not passing non-test events - split them off to nothing. + router = StreamResultRouter(forward_result) + router.map(StreamResult(), 'test_id', test_id=None) + result = CopyStreamResult([router, result]) + else: + # otherwise, copy all events to forward_result + result = CopyStreamResult([forward_result, result]) + elif passthrough_stream is not None: + if not passthrough_subunit: + # Route non-test events to passthrough_stream, unwrapping them for + # display. + passthrough_result = CatFiles(passthrough_stream) + else: + passthrough_result = StreamResultToBytes(passthrough_stream) result = StreamResultRouter(result) result.map(passthrough_result, 'test_id', test_id=None) - orig_result.startTestRun() test = ByteStreamToStreamResult(input_stream, non_subunit_name='stdout') else: raise Exception("Unknown protocol version.") result.startTestRun() test.run(result) - if orig_result is not None: - orig_result.stopTestRun() result.stopTestRun() @@ -114,8 +133,10 @@ def filter_by_result(result_factory, output_path, passthrough, forward, if forward: forward_stream = sys.stdout - else: + elif 1==protocol_version: forward_stream = DiscardStream() + else: + forward_stream = None if output_path is None: output_to = sys.stdout @@ -133,7 +154,8 @@ def filter_by_result(result_factory, output_path, passthrough, forward, return result -def run_filter_script(result_factory, description, post_run_hook=None): +def run_filter_script(result_factory, description, post_run_hook=None, + protocol_version=1): """Main function for simple subunit filter scripts. Many subunit filter scripts take a stream of subunit input and use a @@ -146,14 +168,17 @@ def run_filter_script(result_factory, description, post_run_hook=None): :param result_factory: A callable that takes an output stream and returns a test result that outputs to that stream. :param description: A description of the filter script. + :param protocol_version: What protocol version to consume/emit. """ parser = make_options(description) (options, args) = parser.parse_args() result = filter_by_result( result_factory, options.output_to, not options.no_passthrough, - options.forward) + options.forward, protocol_version=protocol_version) if post_run_hook: post_run_hook(result) + if not safe_hasattr(result, 'wasSuccessful'): + result = result.decorated if result.wasSuccessful(): sys.exit(0) else: diff --git a/python/subunit/tests/test_subunit_tags.py b/python/subunit/tests/test_subunit_tags.py index c98506a..e8d8c3a 100644 --- a/python/subunit/tests/test_subunit_tags.py +++ b/python/subunit/tests/test_subunit_tags.py @@ -16,10 +16,9 @@ """Tests for subunit.tag_stream.""" +from io import BytesIO import unittest -from testtools.compat import StringIO - import subunit import subunit.test_results @@ -27,40 +26,42 @@ import subunit.test_results class TestSubUnitTags(unittest.TestCase): def setUp(self): - self.original = StringIO() - self.filtered = StringIO() + self.original = BytesIO() + self.filtered = BytesIO() def test_add_tag(self): - self.original.write("tags: foo\n") - self.original.write("test: test\n") - self.original.write("tags: bar -quux\n") - self.original.write("success: test\n") + reference = BytesIO() + stream = subunit.StreamResultToBytes(reference) + stream.status( + test_id='test', test_status='inprogress', test_tags=set(['quux', 'foo'])) + stream.status( + test_id='test', test_status='success', test_tags=set(['bar', 'quux', 'foo'])) + stream = subunit.StreamResultToBytes(self.original) + stream.status( + test_id='test', test_status='inprogress', test_tags=set(['foo'])) + stream.status( + test_id='test', test_status='success', test_tags=set(['foo', 'bar'])) self.original.seek(0) - result = subunit.tag_stream(self.original, self.filtered, ["quux"]) - self.assertEqual([ - "tags: quux", - "tags: foo", - "test: test", - "tags: bar", - "success: test", - ], - self.filtered.getvalue().splitlines()) + self.assertEqual( + 0, subunit.tag_stream(self.original, self.filtered, ["quux"])) + self.assertEqual(reference.getvalue(), self.filtered.getvalue()) def test_remove_tag(self): - self.original.write("tags: foo\n") - self.original.write("test: test\n") - self.original.write("tags: bar -quux\n") - self.original.write("success: test\n") + reference = BytesIO() + stream = subunit.StreamResultToBytes(reference) + stream.status( + test_id='test', test_status='inprogress', test_tags=set(['foo'])) + stream.status( + test_id='test', test_status='success', test_tags=set(['foo'])) + stream = subunit.StreamResultToBytes(self.original) + stream.status( + test_id='test', test_status='inprogress', test_tags=set(['foo'])) + stream.status( + test_id='test', test_status='success', test_tags=set(['foo', 'bar'])) self.original.seek(0) - result = subunit.tag_stream(self.original, self.filtered, ["-bar"]) - self.assertEqual([ - "tags: -bar", - "tags: foo", - "test: test", - "tags: -quux", - "success: test", - ], - self.filtered.getvalue().splitlines()) + self.assertEqual( + 0, subunit.tag_stream(self.original, self.filtered, ["-bar"])) + self.assertEqual(reference.getvalue(), self.filtered.getvalue()) def test_suite(): diff --git a/python/subunit/tests/test_tap2subunit.py b/python/subunit/tests/test_tap2subunit.py index 11bc191..f689946 100644 --- a/python/subunit/tests/test_tap2subunit.py +++ b/python/subunit/tests/test_tap2subunit.py @@ -16,14 +16,19 @@ """Tests for TAP2SubUnit.""" +from io import BytesIO, StringIO import unittest -from testtools.compat import StringIO +from testtools import TestCase +from testtools.compat import _u +from testtools.testresult.doubles import StreamResult import subunit +UTF8_TEXT = 'text/plain; charset=UTF8' -class TestTAP2SubUnit(unittest.TestCase): + +class TestTAP2SubUnit(TestCase): """Tests for TAP2SubUnit. These tests test TAP string data in, and subunit string data out. @@ -34,24 +39,21 @@ class TestTAP2SubUnit(unittest.TestCase): """ def setUp(self): + super(TestTAP2SubUnit, self).setUp() self.tap = StringIO() - self.subunit = StringIO() + self.subunit = BytesIO() def test_skip_entire_file(self): # A file # 1..- # Skipped: comment # results in a single skipped test. - self.tap.write("1..0 # Skipped: entire file skipped\n") + self.tap.write(_u("1..0 # Skipped: entire file skipped\n")) self.tap.seek(0) result = subunit.TAP2SubUnit(self.tap, self.subunit) self.assertEqual(0, result) - self.assertEqual([ - "test file skip", - "skip file skip [", - "Skipped: entire file skipped", - "]", - ], - self.subunit.getvalue().splitlines()) + self.check_events([('status', 'file skip', 'skip', None, True, + 'tap comment', b'Skipped: entire file skipped', True, None, None, + None)]) def test_ok_test_pass(self): # A file @@ -59,164 +61,128 @@ class TestTAP2SubUnit(unittest.TestCase): # results in a passed test with name 'test 1' (a synthetic name as tap # does not require named fixtures - it is the first test in the tap # stream). - self.tap.write("ok\n") + self.tap.write(_u("ok\n")) self.tap.seek(0) result = subunit.TAP2SubUnit(self.tap, self.subunit) self.assertEqual(0, result) - self.assertEqual([ - "test test 1", - "success test 1", - ], - self.subunit.getvalue().splitlines()) + self.check_events([('status', 'test 1', 'success', None, False, None, + None, True, None, None, None)]) def test_ok_test_number_pass(self): # A file # ok 1 # results in a passed test with name 'test 1' - self.tap.write("ok 1\n") + self.tap.write(_u("ok 1\n")) self.tap.seek(0) result = subunit.TAP2SubUnit(self.tap, self.subunit) self.assertEqual(0, result) - self.assertEqual([ - "test test 1", - "success test 1", - ], - self.subunit.getvalue().splitlines()) + self.check_events([('status', 'test 1', 'success', None, False, None, + None, True, None, None, None)]) def test_ok_test_number_description_pass(self): # A file # ok 1 - There is a description # results in a passed test with name 'test 1 - There is a description' - self.tap.write("ok 1 - There is a description\n") + self.tap.write(_u("ok 1 - There is a description\n")) self.tap.seek(0) result = subunit.TAP2SubUnit(self.tap, self.subunit) self.assertEqual(0, result) - self.assertEqual([ - "test test 1 - There is a description", - "success test 1 - There is a description", - ], - self.subunit.getvalue().splitlines()) + self.check_events([('status', 'test 1 - There is a description', + 'success', None, False, None, None, True, None, None, None)]) def test_ok_test_description_pass(self): # A file # ok There is a description # results in a passed test with name 'test 1 There is a description' - self.tap.write("ok There is a description\n") + self.tap.write(_u("ok There is a description\n")) self.tap.seek(0) result = subunit.TAP2SubUnit(self.tap, self.subunit) self.assertEqual(0, result) - self.assertEqual([ - "test test 1 There is a description", - "success test 1 There is a description", - ], - self.subunit.getvalue().splitlines()) + self.check_events([('status', 'test 1 There is a description', + 'success', None, False, None, None, True, None, None, None)]) def test_ok_SKIP_skip(self): # A file # ok # SKIP # results in a skkip test with name 'test 1' - self.tap.write("ok # SKIP\n") + self.tap.write(_u("ok # SKIP\n")) self.tap.seek(0) result = subunit.TAP2SubUnit(self.tap, self.subunit) self.assertEqual(0, result) - self.assertEqual([ - "test test 1", - "skip test 1", - ], - self.subunit.getvalue().splitlines()) + self.check_events([('status', 'test 1', 'skip', None, False, None, + None, True, None, None, None)]) def test_ok_skip_number_comment_lowercase(self): - self.tap.write("ok 1 # skip no samba environment available, skipping compilation\n") + self.tap.write(_u("ok 1 # skip no samba environment available, skipping compilation\n")) self.tap.seek(0) result = subunit.TAP2SubUnit(self.tap, self.subunit) self.assertEqual(0, result) - self.assertEqual([ - "test test 1", - "skip test 1 [", - "no samba environment available, skipping compilation", - "]" - ], - self.subunit.getvalue().splitlines()) + self.check_events([('status', 'test 1', 'skip', None, False, 'tap comment', + b'no samba environment available, skipping compilation', True, + 'text/plain; charset=UTF8', None, None)]) def test_ok_number_description_SKIP_skip_comment(self): # A file # ok 1 foo # SKIP Not done yet # results in a skip test with name 'test 1 foo' and a log of # Not done yet - self.tap.write("ok 1 foo # SKIP Not done yet\n") + self.tap.write(_u("ok 1 foo # SKIP Not done yet\n")) self.tap.seek(0) result = subunit.TAP2SubUnit(self.tap, self.subunit) self.assertEqual(0, result) - self.assertEqual([ - "test test 1 foo", - "skip test 1 foo [", - "Not done yet", - "]", - ], - self.subunit.getvalue().splitlines()) + self.check_events([('status', 'test 1 foo', 'skip', None, False, + 'tap comment', b'Not done yet', True, 'text/plain; charset=UTF8', + None, None)]) def test_ok_SKIP_skip_comment(self): # A file # ok # SKIP Not done yet # results in a skip test with name 'test 1' and a log of Not done yet - self.tap.write("ok # SKIP Not done yet\n") + self.tap.write(_u("ok # SKIP Not done yet\n")) self.tap.seek(0) result = subunit.TAP2SubUnit(self.tap, self.subunit) self.assertEqual(0, result) - self.assertEqual([ - "test test 1", - "skip test 1 [", - "Not done yet", - "]", - ], - self.subunit.getvalue().splitlines()) + self.check_events([('status', 'test 1', 'skip', None, False, + 'tap comment', b'Not done yet', True, 'text/plain; charset=UTF8', + None, None)]) def test_ok_TODO_xfail(self): # A file # ok # TODO # results in a xfail test with name 'test 1' - self.tap.write("ok # TODO\n") + self.tap.write(_u("ok # TODO\n")) self.tap.seek(0) result = subunit.TAP2SubUnit(self.tap, self.subunit) self.assertEqual(0, result) - self.assertEqual([ - "test test 1", - "xfail test 1", - ], - self.subunit.getvalue().splitlines()) + self.check_events([('status', 'test 1', 'xfail', None, False, None, + None, True, None, None, None)]) def test_ok_TODO_xfail_comment(self): # A file # ok # TODO Not done yet # results in a xfail test with name 'test 1' and a log of Not done yet - self.tap.write("ok # TODO Not done yet\n") + self.tap.write(_u("ok # TODO Not done yet\n")) self.tap.seek(0) result = subunit.TAP2SubUnit(self.tap, self.subunit) self.assertEqual(0, result) - self.assertEqual([ - "test test 1", - "xfail test 1 [", - "Not done yet", - "]", - ], - self.subunit.getvalue().splitlines()) + self.check_events([('status', 'test 1', 'xfail', None, False, + 'tap comment', b'Not done yet', True, 'text/plain; charset=UTF8', + None, None)]) def test_bail_out_errors(self): # A file with line in it # Bail out! COMMENT # is treated as an error - self.tap.write("ok 1 foo\n") - self.tap.write("Bail out! Lifejacket engaged\n") + self.tap.write(_u("ok 1 foo\n")) + self.tap.write(_u("Bail out! Lifejacket engaged\n")) self.tap.seek(0) result = subunit.TAP2SubUnit(self.tap, self.subunit) self.assertEqual(0, result) - self.assertEqual([ - "test test 1 foo", - "success test 1 foo", - "test Bail out! Lifejacket engaged", - "error Bail out! Lifejacket engaged", - ], - self.subunit.getvalue().splitlines()) + self.check_events([ + ('status', 'test 1 foo', 'success', None, False, None, None, True, + None, None, None), + ('status', 'Bail out! Lifejacket engaged', 'fail', None, False, + None, None, True, None, None, None)]) def test_missing_test_at_end_with_plan_adds_error(self): # A file @@ -224,23 +190,20 @@ class TestTAP2SubUnit(unittest.TestCase): # ok first test # not ok third test # results in three tests, with the third being created - self.tap.write('1..3\n') - self.tap.write('ok first test\n') - self.tap.write('not ok second test\n') + self.tap.write(_u('1..3\n')) + self.tap.write(_u('ok first test\n')) + self.tap.write(_u('not ok second test\n')) self.tap.seek(0) result = subunit.TAP2SubUnit(self.tap, self.subunit) self.assertEqual(0, result) - self.assertEqual([ - 'test test 1 first test', - 'success test 1 first test', - 'test test 2 second test', - 'failure test 2 second test', - 'test test 3', - 'error test 3 [', - 'test missing from TAP output', - ']', - ], - self.subunit.getvalue().splitlines()) + self.check_events([ + ('status', 'test 1 first test', 'success', None, False, None, + None, True, None, None, None), + ('status', 'test 2 second test', 'fail', None, False, None, None, + True, None, None, None), + ('status', 'test 3', 'fail', None, False, 'tap meta', + b'test missing from TAP output', True, 'text/plain; charset=UTF8', + None, None)]) def test_missing_test_with_plan_adds_error(self): # A file @@ -248,45 +211,39 @@ class TestTAP2SubUnit(unittest.TestCase): # ok first test # not ok 3 third test # results in three tests, with the second being created - self.tap.write('1..3\n') - self.tap.write('ok first test\n') - self.tap.write('not ok 3 third test\n') + self.tap.write(_u('1..3\n')) + self.tap.write(_u('ok first test\n')) + self.tap.write(_u('not ok 3 third test\n')) self.tap.seek(0) result = subunit.TAP2SubUnit(self.tap, self.subunit) self.assertEqual(0, result) - self.assertEqual([ - 'test test 1 first test', - 'success test 1 first test', - 'test test 2', - 'error test 2 [', - 'test missing from TAP output', - ']', - 'test test 3 third test', - 'failure test 3 third test', - ], - self.subunit.getvalue().splitlines()) + self.check_events([ + ('status', 'test 1 first test', 'success', None, False, None, None, + True, None, None, None), + ('status', 'test 2', 'fail', None, False, 'tap meta', + b'test missing from TAP output', True, 'text/plain; charset=UTF8', + None, None), + ('status', 'test 3 third test', 'fail', None, False, None, None, + True, None, None, None)]) def test_missing_test_no_plan_adds_error(self): # A file # ok first test # not ok 3 third test # results in three tests, with the second being created - self.tap.write('ok first test\n') - self.tap.write('not ok 3 third test\n') + self.tap.write(_u('ok first test\n')) + self.tap.write(_u('not ok 3 third test\n')) self.tap.seek(0) result = subunit.TAP2SubUnit(self.tap, self.subunit) self.assertEqual(0, result) - self.assertEqual([ - 'test test 1 first test', - 'success test 1 first test', - 'test test 2', - 'error test 2 [', - 'test missing from TAP output', - ']', - 'test test 3 third test', - 'failure test 3 third test', - ], - self.subunit.getvalue().splitlines()) + self.check_events([ + ('status', 'test 1 first test', 'success', None, False, None, None, + True, None, None, None), + ('status', 'test 2', 'fail', None, False, 'tap meta', + b'test missing from TAP output', True, 'text/plain; charset=UTF8', + None, None), + ('status', 'test 3 third test', 'fail', None, False, None, None, + True, None, None, None)]) def test_four_tests_in_a_row_trailing_plan(self): # A file @@ -296,25 +253,23 @@ class TestTAP2SubUnit(unittest.TestCase): # not ok 4 - fourth # 1..4 # results in four tests numbered and named - self.tap.write('ok 1 - first test in a script with trailing plan\n') - self.tap.write('not ok 2 - second\n') - self.tap.write('ok 3 - third\n') - self.tap.write('not ok 4 - fourth\n') - self.tap.write('1..4\n') + self.tap.write(_u('ok 1 - first test in a script with trailing plan\n')) + self.tap.write(_u('not ok 2 - second\n')) + self.tap.write(_u('ok 3 - third\n')) + self.tap.write(_u('not ok 4 - fourth\n')) + self.tap.write(_u('1..4\n')) self.tap.seek(0) result = subunit.TAP2SubUnit(self.tap, self.subunit) self.assertEqual(0, result) - self.assertEqual([ - 'test test 1 - first test in a script with trailing plan', - 'success test 1 - first test in a script with trailing plan', - 'test test 2 - second', - 'failure test 2 - second', - 'test test 3 - third', - 'success test 3 - third', - 'test test 4 - fourth', - 'failure test 4 - fourth' - ], - self.subunit.getvalue().splitlines()) + self.check_events([ + ('status', 'test 1 - first test in a script with trailing plan', + 'success', None, False, None, None, True, None, None, None), + ('status', 'test 2 - second', 'fail', None, False, None, None, + True, None, None, None), + ('status', 'test 3 - third', 'success', None, False, None, None, + True, None, None, None), + ('status', 'test 4 - fourth', 'fail', None, False, None, None, + True, None, None, None)]) def test_four_tests_in_a_row_with_plan(self): # A file @@ -324,25 +279,23 @@ class TestTAP2SubUnit(unittest.TestCase): # ok 3 - third # not ok 4 - fourth # results in four tests numbered and named - self.tap.write('1..4\n') - self.tap.write('ok 1 - first test in a script with a plan\n') - self.tap.write('not ok 2 - second\n') - self.tap.write('ok 3 - third\n') - self.tap.write('not ok 4 - fourth\n') + self.tap.write(_u('1..4\n')) + self.tap.write(_u('ok 1 - first test in a script with a plan\n')) + self.tap.write(_u('not ok 2 - second\n')) + self.tap.write(_u('ok 3 - third\n')) + self.tap.write(_u('not ok 4 - fourth\n')) self.tap.seek(0) result = subunit.TAP2SubUnit(self.tap, self.subunit) self.assertEqual(0, result) - self.assertEqual([ - 'test test 1 - first test in a script with a plan', - 'success test 1 - first test in a script with a plan', - 'test test 2 - second', - 'failure test 2 - second', - 'test test 3 - third', - 'success test 3 - third', - 'test test 4 - fourth', - 'failure test 4 - fourth' - ], - self.subunit.getvalue().splitlines()) + self.check_events([ + ('status', 'test 1 - first test in a script with a plan', + 'success', None, False, None, None, True, None, None, None), + ('status', 'test 2 - second', 'fail', None, False, None, None, + True, None, None, None), + ('status', 'test 3 - third', 'success', None, False, None, None, + True, None, None, None), + ('status', 'test 4 - fourth', 'fail', None, False, None, None, + True, None, None, None)]) def test_four_tests_in_a_row_no_plan(self): # A file @@ -351,46 +304,43 @@ class TestTAP2SubUnit(unittest.TestCase): # ok 3 - third # not ok 4 - fourth # results in four tests numbered and named - self.tap.write('ok 1 - first test in a script with no plan at all\n') - self.tap.write('not ok 2 - second\n') - self.tap.write('ok 3 - third\n') - self.tap.write('not ok 4 - fourth\n') + self.tap.write(_u('ok 1 - first test in a script with no plan at all\n')) + self.tap.write(_u('not ok 2 - second\n')) + self.tap.write(_u('ok 3 - third\n')) + self.tap.write(_u('not ok 4 - fourth\n')) self.tap.seek(0) result = subunit.TAP2SubUnit(self.tap, self.subunit) self.assertEqual(0, result) - self.assertEqual([ - 'test test 1 - first test in a script with no plan at all', - 'success test 1 - first test in a script with no plan at all', - 'test test 2 - second', - 'failure test 2 - second', - 'test test 3 - third', - 'success test 3 - third', - 'test test 4 - fourth', - 'failure test 4 - fourth' - ], - self.subunit.getvalue().splitlines()) + self.check_events([ + ('status', 'test 1 - first test in a script with no plan at all', + 'success', None, False, None, None, True, None, None, None), + ('status', 'test 2 - second', 'fail', None, False, None, None, + True, None, None, None), + ('status', 'test 3 - third', 'success', None, False, None, None, + True, None, None, None), + ('status', 'test 4 - fourth', 'fail', None, False, None, None, + True, None, None, None)]) def test_todo_and_skip(self): # A file # not ok 1 - a fail but # TODO but is TODO # not ok 2 - another fail # SKIP instead # results in two tests, numbered and commented. - self.tap.write("not ok 1 - a fail but # TODO but is TODO\n") - self.tap.write("not ok 2 - another fail # SKIP instead\n") + self.tap.write(_u("not ok 1 - a fail but # TODO but is TODO\n")) + self.tap.write(_u("not ok 2 - another fail # SKIP instead\n")) self.tap.seek(0) result = subunit.TAP2SubUnit(self.tap, self.subunit) self.assertEqual(0, result) - self.assertEqual([ - 'test test 1 - a fail but', - 'xfail test 1 - a fail but [', - 'but is TODO', - ']', - 'test test 2 - another fail', - 'skip test 2 - another fail [', - 'instead', - ']', - ], - self.subunit.getvalue().splitlines()) + self.subunit.seek(0) + events = StreamResult() + subunit.ByteStreamToStreamResult(self.subunit).run(events) + self.check_events([ + ('status', 'test 1 - a fail but', 'xfail', None, False, + 'tap comment', b'but is TODO', True, 'text/plain; charset=UTF8', + None, None), + ('status', 'test 2 - another fail', 'skip', None, False, + 'tap comment', b'instead', True, 'text/plain; charset=UTF8', + None, None)]) def test_leading_comments_add_to_next_test_log(self): # A file @@ -399,21 +349,17 @@ class TestTAP2SubUnit(unittest.TestCase): # ok # results in a single test with the comment included # in the first test and not the second. - self.tap.write("# comment\n") - self.tap.write("ok\n") - self.tap.write("ok\n") + self.tap.write(_u("# comment\n")) + self.tap.write(_u("ok\n")) + self.tap.write(_u("ok\n")) self.tap.seek(0) result = subunit.TAP2SubUnit(self.tap, self.subunit) self.assertEqual(0, result) - self.assertEqual([ - 'test test 1', - 'success test 1 [', - '# comment', - ']', - 'test test 2', - 'success test 2', - ], - self.subunit.getvalue().splitlines()) + self.check_events([ + ('status', 'test 1', 'success', None, False, 'tap comment', + b'# comment', True, 'text/plain; charset=UTF8', None, None), + ('status', 'test 2', 'success', None, False, None, None, True, + None, None, None)]) def test_trailing_comments_are_included_in_last_test_log(self): # A file @@ -422,21 +368,23 @@ class TestTAP2SubUnit(unittest.TestCase): # # comment # results in a two tests, with the second having the comment # attached to its log. - self.tap.write("ok\n") - self.tap.write("ok\n") - self.tap.write("# comment\n") + self.tap.write(_u("ok\n")) + self.tap.write(_u("ok\n")) + self.tap.write(_u("# comment\n")) self.tap.seek(0) result = subunit.TAP2SubUnit(self.tap, self.subunit) self.assertEqual(0, result) - self.assertEqual([ - 'test test 1', - 'success test 1', - 'test test 2', - 'success test 2 [', - '# comment', - ']', - ], - self.subunit.getvalue().splitlines()) + self.check_events([ + ('status', 'test 1', 'success', None, False, None, None, True, + None, None, None), + ('status', 'test 2', 'success', None, False, 'tap comment', + b'# comment', True, 'text/plain; charset=UTF8', None, None)]) + + def check_events(self, events): + self.subunit.seek(0) + eventstream = StreamResult() + subunit.ByteStreamToStreamResult(self.subunit).run(eventstream) + self.assertEqual(events, eventstream._events) def test_suite(): |
