Add StreamTagger, for tagging StreamResult events.

This commit is contained in:
Robert Collins
2013-03-16 19:45:05 +13:00
parent 92c675a9ff
commit e7ac371211
6 changed files with 89 additions and 0 deletions

3
NEWS
View File

@@ -31,6 +31,9 @@ Improvements
* New support class ``StreamSummary`` which summarises a ``StreamResult``
stream compatibly with ``TestResult`` code. (Robert Collins)
* New support class ``StreamTagger`` which adds or removes tags from
``StreamResult`` events. (RobertCollins)
* New support class ``StreamToDict`` which converts a ``StreamResult`` to a
series of dicts describing a test. Useful for writing trivial stream
analysers. (Robert Collins)

View File

@@ -187,6 +187,18 @@ Aborting multiple workers in a distributed environment requires hooking
whatever signalling mechanism the distributed environment has up to a
``TestControl`` in each worker process.
StreamTagger
------------
A ``StreamResult`` filter that adds or removes tags from events::
>>> from testtools import StreamTagger
>>> sink = StreamResult()
>>> result = StreamTagger([sink], set(['add']), set(['discard']))
>>> result.startTestRun()
>>> # Run tests against result here.
>>> result.stopTestRun()
StreamToDict
------------

View File

@@ -31,6 +31,7 @@ __all__ = [
'StreamFailFast',
'StreamResult',
'StreamSummary',
'StreamTagger',
'StreamToDict',
'StreamToExtendedDecorator',
'TestControl',
@@ -81,6 +82,7 @@ else:
StreamFailFast,
StreamResult,
StreamSummary,
StreamTagger,
StreamToDict,
StreamToExtendedDecorator,
Tagger,

View File

@@ -10,6 +10,7 @@ __all__ = [
'StreamFailFast',
'StreamResult',
'StreamSummary',
'StreamTagger',
'StreamToDict',
'StreamToExtendedDecorator',
'Tagger',
@@ -29,6 +30,7 @@ from testtools.testresult.real import (
StreamFailFast,
StreamResult,
StreamSummary,
StreamTagger,
StreamToDict,
StreamToExtendedDecorator,
Tagger,

View File

@@ -10,6 +10,7 @@ __all__ = [
'StreamFailFast',
'StreamResult',
'StreamSummary',
'StreamTagger',
'StreamToDict',
'StreamToExtendedDecorator',
'Tagger',
@@ -423,6 +424,29 @@ class StreamFailFast(StreamResult):
self.on_error()
class StreamTagger(CopyStreamResult):
"""Adds or discards tags from StreamResult events."""
def __init__(self, targets, add=None, discard=None):
"""Create a StreamTagger.
:param targets: A list of targets to forward events onto.
:param add: Either None or an iterable of tags to add to each event.
:param discard: Either None or an iterable of tags to discard from each
event.
"""
super(StreamTagger, self).__init__(targets)
self.add = frozenset(add or ())
self.discard = frozenset(discard or ())
def status(self, *args, **kwargs):
test_tags = kwargs.get('test_tags') or set()
test_tags.update(self.add)
test_tags.difference_update(self.discard)
kwargs['test_tags'] = test_tags or None
super(StreamTagger, self).status(*args, **kwargs)
class StreamToDict(StreamResult):
"""A specialised StreamResult that emits a callback as tests complete.

View File

@@ -27,6 +27,7 @@ from testtools import (
StreamFailFast,
StreamResult,
StreamSummary,
StreamTagger,
StreamToDict,
StreamToExtendedDecorator,
Tagger,
@@ -563,6 +564,12 @@ class TestStreamSummaryResultContract(TestCase, TestStreamResultContract):
return StreamSummary()
class TestStreamTaggerContract(TestCase, TestStreamResultContract):
def _make_result(self):
return StreamTagger([StreamResult()], add=set(), discard=set())
class TestStreamToDictContract(TestCase, TestStreamResultContract):
def _make_result(self):
@@ -649,6 +656,45 @@ class TestCopyStreamResultCopies(TestCase):
])))
class TestStreamTagger(TestCase):
def test_adding(self):
log = LoggingStreamResult()
result = StreamTagger([log], add=['foo'])
result.startTestRun()
result.status()
result.status(test_tags=set(['bar']))
result.status(test_tags=None)
result.stopTestRun()
self.assertEqual([
('startTestRun',),
('status', None, None, set(['foo']), True, None, None, False, None, None, None),
('status', None, None, set(['foo', 'bar']), True, None, None, False, None, None, None),
('status', None, None, set(['foo']), True, None, None, False, None, None, None),
('stopTestRun',),
], log._events)
def test_discarding(self):
log = LoggingStreamResult()
result = StreamTagger([log], discard=['foo'])
result.startTestRun()
result.status()
result.status(test_tags=None)
result.status(test_tags=set(['foo']))
result.status(test_tags=set(['bar']))
result.status(test_tags=set(['foo', 'bar']))
result.stopTestRun()
self.assertEqual([
('startTestRun',),
('status', None, None, None, True, None, None, False, None, None, None),
('status', None, None, None, True, None, None, False, None, None, None),
('status', None, None, None, True, None, None, False, None, None, None),
('status', None, None, set(['bar']), True, None, None, False, None, None, None),
('status', None, None, set(['bar']), True, None, None, False, None, None, None),
('stopTestRun',),
], log._events)
class TestStreamToDict(TestCase):
def test_hung_test(self):