summaryrefslogtreecommitdiff
path: root/python/subunit/__init__.py
diff options
context:
space:
mode:
authorRobert Collins <robertc@robertcollins.net>2009-09-08 22:08:23 +1000
committerRobert Collins <robertc@robertcollins.net>2009-09-08 22:08:23 +1000
commit3b11398f6c6247545d846c2bb607b6ff526ecbc1 (patch)
tree45511636f6568dd6ea0f0279d282665cd456f0cb /python/subunit/__init__.py
parent56f366ba26b9bd81079f2ce77c851b0324ef28f6 (diff)
parent95a5816c1bb8808141416005c5a203bc4d7f8599 (diff)
downloadsubunit-git-3b11398f6c6247545d846c2bb607b6ff526ecbc1.tar.gz
Merge python API changes for tagging.
Diffstat (limited to 'python/subunit/__init__.py')
-rw-r--r--python/subunit/__init__.py80
1 files changed, 62 insertions, 18 deletions
diff --git a/python/subunit/__init__.py b/python/subunit/__init__.py
index 5407f2a..58d345b 100644
--- a/python/subunit/__init__.py
+++ b/python/subunit/__init__.py
@@ -100,7 +100,6 @@ class TestProtocolServer(object):
if stream is None:
stream = sys.stdout
self._stream = stream
- self.tags = set()
def _addError(self, offset, line):
if (self.state == TestProtocolServer.TEST_STARTED and
@@ -246,12 +245,9 @@ class TestProtocolServer(object):
"""Process a tags command."""
tags = line[offset:].split()
new_tags, gone_tags = tags_to_new_gone(tags)
- if self.state == TestProtocolServer.OUTSIDE_TEST:
- update_tags = self.tags
- else:
- update_tags = self._current_test.tags
- update_tags.update(new_tags)
- update_tags.difference_update(gone_tags)
+ tags_method = getattr(self.client, 'tags', None)
+ if tags_method is not None:
+ tags_method(new_tags, gone_tags)
def _handleTime(self, offset, line):
# Accept it, but do not do anything with it yet.
@@ -339,7 +335,6 @@ class TestProtocolServer(object):
self._current_test = RemotedTestCase(line[offset:-1])
self.current_test_description = line[offset:-1]
self.client.startTest(self._current_test)
- self._current_test.tags = set(self.tags)
else:
self.stdOutLineReceived(line)
@@ -765,7 +760,7 @@ class TestResultStats(unittest.TestResult):
:ivar total_tests: The total tests seen.
:ivar passed_tests: The tests that passed.
:ivar failed_tests: The tests that failed.
- :ivar tags: The tags seen across all tests.
+ :ivar seen_tags: The tags seen across all tests.
"""
def __init__(self, stream):
@@ -774,7 +769,7 @@ class TestResultStats(unittest.TestResult):
self._stream = stream
self.failed_tests = 0
self.skipped_tests = 0
- self.tags = set()
+ self.seen_tags = set()
@property
def total_tests(self):
@@ -794,16 +789,16 @@ class TestResultStats(unittest.TestResult):
self._stream.write("Passed tests: %5d\n" % self.passed_tests)
self._stream.write("Failed tests: %5d\n" % self.failed_tests)
self._stream.write("Skipped tests: %5d\n" % self.skipped_tests)
- tags = sorted(self.tags)
- self._stream.write("Tags: %s\n" % (", ".join(tags)))
+ tags = sorted(self.seen_tags)
+ self._stream.write("Seen tags: %s\n" % (", ".join(tags)))
@property
def passed_tests(self):
return self.total_tests - self.failed_tests - self.skipped_tests
- def stopTest(self, test):
- unittest.TestResult.stopTest(self, test)
- self.tags.update(test.tags)
+ def tags(self, new_tags, gone_tags):
+ """Accumulate the seen tags."""
+ self.seen_tags.update(new_tags)
def wasSuccessful(self):
"""Tells whether or not this result was a success"""
@@ -844,18 +839,22 @@ class TestResultFilter(unittest.TestResult):
if filter_predicate is None:
filter_predicate = lambda test, err: True
self.filter_predicate = filter_predicate
+ # The current test (for filtering tags)
+ self._current_test = None
+ # Has the current test been filtered (for outputting test tags)
+ self._current_test_filtered = None
+ # The (new, gone) tags for the current test.
+ self._current_test_tags = None
def addError(self, test, err):
if not self._filter_error and self.filter_predicate(test, err):
self.result.startTest(test)
self.result.addError(test, err)
- self.result.stopTest(test)
def addFailure(self, test, err):
if not self._filter_failure and self.filter_predicate(test, err):
self.result.startTest(test)
self.result.addFailure(test, err)
- self.result.stopTest(test)
def addSkip(self, test, reason):
if not self._filter_skip and self.filter_predicate(test, reason):
@@ -867,13 +866,58 @@ class TestResultFilter(unittest.TestResult):
self.result.addError(test, RemoteError(reason))
else:
self.result.addSkip(test, reason)
- self.result.stopTest(test)
def addSuccess(self, test):
if not self._filter_success and self.filter_predicate(test, None):
self.result.startTest(test)
self.result.addSuccess(test)
+
+ def startTest(self, test):
+ """Start a test.
+
+ Not directly passed to the client, but used for handling of tags
+ correctly.
+ """
+ self._current_test = test
+ self._current_test_filtered = False
+ self._current_test_tags = set(), set()
+
+ def stopTest(self, test):
+ """Stop a test.
+
+ Not directly passed to the client, but used for handling of tags
+ correctly.
+ """
+ if not self._current_test_filtered:
+ # Tags to output for this test.
+ if self._current_test_tags[0] or self._current_test_tags[1]:
+ tags_method = getattr(self.result, 'tags', None)
+ if callable(tags_method):
+ self.result.tags(*self._current_test_tags)
self.result.stopTest(test)
+ self._current_test = None
+ self._current_test_filtered = None
+ self._current_test_tags = None
+
+ def tags(self, new_tags, gone_tags):
+ """Handle tag instructions.
+
+ Adds and removes tags as appropriate. If a test is currently running,
+ tags are not affected for subsequent tests.
+
+ :param new_tags: Tags to add,
+ :param gone_tags: Tags to remove.
+ """
+ if self._current_test is not None:
+ # gather the tags until the test stops.
+ self._current_test_tags[0].update(new_tags)
+ self._current_test_tags[0].difference_update(gone_tags)
+ self._current_test_tags[1].update(gone_tags)
+ self._current_test_tags[1].difference_update(new_tags)
+ tags_method = getattr(self.result, 'tags', None)
+ if tags_method is None:
+ return
+ return tags_method(new_tags, gone_tags)
def id_to_orig_id(self, id):
if id.startswith("subunit.RemotedTestCase."):