First pass, missing some tests.
authorThomi Richards <thomi.richards@canonical.com>
Mon, 18 Nov 2013 02:27:08 +0000 (15:27 +1300)
committerThomi Richards <thomi.richards@canonical.com>
Mon, 18 Nov 2013 02:27:08 +0000 (15:27 +1300)
python/subunit/_output.py
python/subunit/tests/test_output_filter.py

index 66093bb..e513639 100644 (file)
 #  license you chose for the specific language governing permissions and
 #  limitations under that license.
 
+from argparse import ArgumentParser
+from sys import stdout
+
+from subunit.v2 import StreamResultToBytes
 
 def output_main():
+    args = parse_arguments()
+    output = get_output_stream_writer()
+    generate_bytestream(args, output)
+
     return 0
+
+
+def parse_arguments(args=None):
+    """Parse arguments from the command line.
+
+    If specified, args must be a list of strings, similar to sys.argv[1:].
+
+    """
+    parser = ArgumentParser(
+        prog='subunit-output',
+        description="A tool to generate a subunit result byte-stream",
+    )
+    sub_parsers = parser.add_subparsers(dest="action")
+
+    parser_start = sub_parsers.add_parser("start", help="Start a test.")
+    parser_start.add_argument("test_id", help="The test id you want to start.")
+
+    parser_pass = sub_parsers.add_parser("pass", help="Pass a test.")
+    parser_pass.add_argument("test_id", help="The test id you want to pass.")
+
+    parser_fail = sub_parsers.add_parser("fail", help="Fail a test.")
+    parser_fail.add_argument("test_id", help="The test id you want to fail.")
+
+    parser_skip = sub_parsers.add_parser("skip", help="Skip a test.")
+    parser_skip.add_argument("test_id", help="The test id you want to skip.")
+
+    return parser.parse_args(args)
+
+
+def translate_command_name(command_name):
+    """Turn the friendly command names we show users on the command line into
+    something subunit understands.
+
+    """
+    return {
+        'start': 'inprogress',
+        'pass': 'success',
+    }.get(command_name, command_name)
+
+
+def get_output_stream_writer():
+    return StreamResultToBytes(stdout)
+
+
+def generate_bytestream(args, output_writer):
+    output_writer.status(
+        test_id=args.test_id,
+        test_status=translate_command_name(args.action)
+        )
index 8317ffe..27caa4e 100644 (file)
 #
 
 
-from testtools import TestCase
+from io import BytesIO
+
+from testtools import TestCase, StreamToExtendedDecorator, TestResult
+from testtools.matchers import Equals
+
+from subunit.v2 import StreamResultToBytes, ByteStreamToStreamResult
+from subunit._output import (
+    generate_bytestream,
+    parse_arguments,
+    translate_command_name,
+)
+
+class OutputFilterArgumentTests(TestCase):
+
+    """Tests for the command line argument parser."""
+
+    def _test_command(self, command, test_id):
+        args = parse_arguments(args=[command, test_id])
+
+        self.assertThat(args.action, Equals(command))
+        self.assertThat(args.test_id, Equals(test_id))
+
+    def test_can_parse_start_test(self):
+        self._test_command('start', self.getUniqueString())
+
+    def test_can_parse_pass_test(self):
+        self._test_command('pass', self.getUniqueString())
+
+    def test_can_parse_fail_test(self):
+        self._test_command('fail', self.getUniqueString())
+
+    def test_can_parse_skip_test(self):
+        self._test_command('skip', self.getUniqueString())
+
+    def test_command_translation(self):
+        self.assertThat(translate_command_name('start'), Equals('inprogress'))
+        self.assertThat(translate_command_name('pass'), Equals('success'))
+        for command in ('fail', 'skip'):
+            self.assertThat(translate_command_name(command), Equals(command))
+
+
+class ByteStreamCompatibilityTests(TestCase):
+
+    """Tests that ensure that the subunit byetstream we generate contains what
+    we expect it to.
+
+    """
+
+    def _get_result_for(self, *commands):
+        """Get a result object from *args.
+
+        Runs the 'generate_bytestream' function from subunit._output after
+        parsing *args as if they were specified on the command line. The
+        resulting bytestream is then converted back into a result object and
+        returned.
+
+        """
+        stream = BytesIO()
+
+        for command_list in commands:
+            args = parse_arguments(command_list)
+            output_writer = StreamResultToBytes(output_stream=stream)
+            generate_bytestream(args, output_writer)
+
+        stream.seek(0)
+
+        case = ByteStreamToStreamResult(source=stream)
+        result = TestResult()
+        result = StreamToExtendedDecorator(result)
+        result.startTestRun()
+        case.run(result)
+        result.stopTestRun()
+        return result
+
+    def test_start(self):
+        result = self._get_result_for(
+            ['start', 'foo'],
+            ['pass', 'foo'],
+        )
+
+        self.assertThat(result.decorated.wasSuccessful(), Equals(True))
+        # How do I get the id? or details?
+        self.assertThat(result.decorated.id(), Equals('foo'))
+
 
 
-class OutputFilterTests(TestCase):
-    pass