diff options
| author | Robert Collins <robertc@robertcollins.net> | 2009-07-28 23:32:10 +1000 |
|---|---|---|
| committer | Robert Collins <robertc@robertcollins.net> | 2009-07-28 23:32:10 +1000 |
| commit | 7aa495ccf553cf96c04cf2c2419aec8dd7465fac (patch) | |
| tree | 5b90a06fe9dadb0a5fea1cdb61caaddcb512d575 /python | |
| parent | 9361b85f6b08a1b0838d157a6b2f427291a06aa7 (diff) | |
| download | subunit-git-7aa495ccf553cf96c04cf2c2419aec8dd7465fac.tar.gz | |
Basic progress support.
Diffstat (limited to 'python')
| -rw-r--r-- | python/subunit/__init__.py | 33 | ||||
| -rw-r--r-- | python/subunit/test_results.py | 7 | ||||
| -rw-r--r-- | python/subunit/tests/test_test_protocol.py | 51 | ||||
| -rw-r--r-- | python/subunit/tests/test_test_results.py | 7 |
4 files changed, 98 insertions, 0 deletions
diff --git a/python/subunit/__init__.py b/python/subunit/__init__.py index 7859ea7..e0a4ccc 100644 --- a/python/subunit/__init__.py +++ b/python/subunit/__init__.py @@ -28,6 +28,10 @@ import unittest import iso8601 +SEEK_CUR = os.SEEK_CUR +SEEK_SET = os.SEEK_SET + + def test_suite(): import subunit.tests return subunit.tests.test_suite() @@ -200,6 +204,18 @@ class TestProtocolServer(object): else: self.stdOutLineReceived(line) + def _handleProgress(self, offset, line): + """Process a progress directive.""" + line = line[offset:].strip() + if line[0] in '+-': + whence = SEEK_CUR + else: + whence = SEEK_SET + delta = int(line) + progress_method = getattr(self.client, 'progress', None) + if callable(progress_method): + progress_method(delta, whence) + def _handleTags(self, offset, line): """Process a tags command.""" tags = line[offset:].split() @@ -243,6 +259,8 @@ class TestProtocolServer(object): self._addError(offset, line) elif cmd == 'failure': self._addFailure(offset, line) + elif cmd == 'progress': + self._handleProgress(offset, line) elif cmd == 'skip': self._addSkip(offset, line) elif cmd in ('success', 'successful'): @@ -355,6 +373,21 @@ class TestProtocolClient(unittest.TestResult): """Mark a test as starting its test run.""" self._stream.write("test: %s\n" % test.id()) + def progress(self, offset, whence): + """Provide indication about the progress/length of the test run. + + :param offset: Information about the number of tests remaining. If + whence is SEEK_CUR, then offset increases/decreases the remaining + test count. If whence is SEEK_SET, then offset specifies exactly + the remaining test count. + :param whence: One of SEEK_CUR or SEEK_SET. + """ + if whence == SEEK_CUR and offset > -1: + prefix = "+" + else: + prefix = "" + self._stream.write("progress: %s%s\n" % (prefix, offset)) + def time(self, a_datetime): """Inform the client of the time. diff --git a/python/subunit/test_results.py b/python/subunit/test_results.py index 0a87ba6..a5811aa 100644 --- a/python/subunit/test_results.py +++ b/python/subunit/test_results.py @@ -87,6 +87,10 @@ class HookedTestResultDecorator(object): self._before_event() return self._call_maybe("addUnexpectedSuccess", test) + def progress(self, offset, whence): + self._before_event() + return self._call_maybe("progress", offset, whence) + def wasSuccessful(self): self._before_event() return self.decorated.wasSuccessful() @@ -124,6 +128,9 @@ class AutoTimingTestResultDecorator(HookedTestResultDecorator): time = datetime.datetime.utcnow().replace(tzinfo=iso8601.Utc()) self._call_maybe("time", time) + def progress(self, offset, whence): + return self._call_maybe("progress", offset, whence) + @property def shouldStop(self): return self.decorated.shouldStop diff --git a/python/subunit/tests/test_test_protocol.py b/python/subunit/tests/test_test_protocol.py index 8124042..5eedbf9 100644 --- a/python/subunit/tests/test_test_protocol.py +++ b/python/subunit/tests/test_test_protocol.py @@ -37,6 +37,7 @@ class MockTestProtocolServerClient(object): self.skip_calls = [] self.start_calls = [] self.success_calls = [] + self.progress_calls = [] self._time = None super(MockTestProtocolServerClient, self).__init__() @@ -58,6 +59,9 @@ class MockTestProtocolServerClient(object): def startTest(self, test): self.start_calls.append(test) + def progress(self, offset, whence): + self.progress_calls.append((offset, whence)) + def time(self, time): self._time = time @@ -118,6 +122,11 @@ class TestMockTestProtocolServer(unittest.TestCase): self.assertEqual(protocol.success_calls, []) self.assertEqual(protocol.start_calls, []) + def test_progress(self): + protocol = MockTestProtocolServerClient() + protocol.progress(-1, subunit.SEEK_CUR) + self.assertEqual(protocol.progress_calls, [(-1, subunit.SEEK_CUR)]) + class TestTestImports(unittest.TestCase): @@ -710,6 +719,36 @@ class TestTestProtocolServerAddSuccess(unittest.TestCase): self.success_quoted_bracket("success:") +class TestTestProtocolServerProgress(unittest.TestCase): + """Test receipt of progress: directives.""" + + def test_progress_accepted_stdlib(self): + # With a stdlib TestResult, progress events are swallowed. + self.result = unittest.TestResult() + self.stream = StringIO() + self.protocol = subunit.TestProtocolServer(self.result, + stream=self.stream) + self.protocol.lineReceived("progress: 23") + self.protocol.lineReceived("progress: -2") + self.protocol.lineReceived("progress: +4") + self.assertEqual("", self.stream.getvalue()) + + def test_progress_accepted_extended(self): + # With a progress capable TestResult, progress events are emitted. + self.result = MockTestProtocolServerClient() + self.stream = StringIO() + self.protocol = subunit.TestProtocolServer(self.result, + stream=self.stream) + self.protocol.lineReceived("progress: 23") + self.protocol.lineReceived("progress: -2") + self.protocol.lineReceived("progress: +4") + self.assertEqual("", self.stream.getvalue()) + self.assertEqual( + [(23, subunit.SEEK_SET), (-2, subunit.SEEK_CUR), + (4, subunit.SEEK_CUR)], + self.result.progress_calls) + + class TestTestProtocolServerStreamTags(unittest.TestCase): """Test managing tags on the protocol level.""" @@ -1005,6 +1044,18 @@ class TestTestProtocolClient(unittest.TestCase): self.io.getvalue(), 'skip: %s [\nHas it really?\n]\n' % self.test.id()) + def test_progress_set(self): + self.protocol.progress(23, subunit.SEEK_SET) + self.assertEqual(self.io.getvalue(), 'progress: 23\n') + + def test_progress_neg_cur(self): + self.protocol.progress(-23, subunit.SEEK_CUR) + self.assertEqual(self.io.getvalue(), 'progress: -23\n') + + def test_progress_pos_cur(self): + self.protocol.progress(23, subunit.SEEK_CUR) + self.assertEqual(self.io.getvalue(), 'progress: +23\n') + def test_time(self): # Calling time() outputs a time signal immediately. self.protocol.time( diff --git a/python/subunit/tests/test_test_results.py b/python/subunit/tests/test_test_results.py index 2ba9198..4537304 100644 --- a/python/subunit/tests/test_test_results.py +++ b/python/subunit/tests/test_test_results.py @@ -108,6 +108,9 @@ class TestHookedTestResultDecorator(unittest.TestCase): def test_addUnexpectedSuccess(self): self.result.addUnexpectedSuccess(self) + def test_progress(self): + self.result.progress(1, os.SEEK_SET) + def test_wasSuccessful(self): self.result.wasSuccessful() @@ -135,6 +138,10 @@ class TestAutoTimingTestResultDecorator(unittest.TestCase): self.assertEqual(1, len(self.result.decorated._calls)) self.assertNotEqual(None, self.result.decorated._calls[0]) + def test_no_time_from_progress(self): + self.result.progress(1, os.SEEK_CUR) + self.assertEqual(0, len(self.result.decorated._calls)) + def test_no_time_from_shouldStop(self): self.result.decorated.stop() self.result.shouldStop |
