From 5e91d1d2c6ad2bb52e302d82d98f289b5ec57aae Mon Sep 17 00:00:00 2001 From: Jonathan Lange Date: Mon, 2 Nov 2015 18:25:00 +0000 Subject: [PATCH 01/10] Lint clear-up --- testtools/testresult/doubles.py | 13 +++++++------ testtools/tests/test_testresult.py | 20 +++++++++++++++----- 2 files changed, 22 insertions(+), 11 deletions(-) diff --git a/testtools/testresult/doubles.py b/testtools/testresult/doubles.py index d86f7fae..493ae800 100644 --- a/testtools/testresult/doubles.py +++ b/testtools/testresult/doubles.py @@ -1,4 +1,4 @@ -# Copyright (c) 2009-2010 testtools developers. See LICENSE for details. +# Copyright (c) 2009-2015 testtools developers. See LICENSE for details. """Doubles of test result objects, useful for testing unittest code.""" @@ -167,8 +167,9 @@ def stopTestRun(self): self._events.append(('stopTestRun',)) def status(self, test_id=None, test_status=None, test_tags=None, - runnable=True, file_name=None, file_bytes=None, eof=False, - mime_type=None, route_code=None, timestamp=None): - self._events.append(('status', test_id, test_status, test_tags, - runnable, file_name, file_bytes, eof, mime_type, route_code, - timestamp)) + runnable=True, file_name=None, file_bytes=None, eof=False, + mime_type=None, route_code=None, timestamp=None): + self._events.append( + ('status', test_id, test_status, test_tags, + runnable, file_name, file_bytes, eof, mime_type, route_code, + timestamp)) diff --git a/testtools/tests/test_testresult.py b/testtools/tests/test_testresult.py index 924313ca..e81c139c 100644 --- a/testtools/tests/test_testresult.py +++ b/testtools/tests/test_testresult.py @@ -1,4 +1,4 @@ -# Copyright (c) 2008-2012 testtools developers. See LICENSE for details. +# Copyright (c) 2008-2015 testtools developers. See LICENSE for details. """Test TestResults and related things.""" @@ -15,7 +15,6 @@ import tempfile import threading from unittest import TestSuite -import warnings from extras import safe_hasattr, try_imports @@ -225,11 +224,14 @@ def test_startStopTestRun(self): def test_failfast(self): result = self.makeResult() result.failfast = True + class Failing(TestCase): def test_a(self): self.fail('a') + def test_b(self): self.fail('b') + TestSuite([Failing('test_a'), Failing('test_b')]).run(result) self.assertEqual(1, result.testsRun) @@ -520,8 +522,15 @@ def test_test_status(self): result.startTestRun() self.addCleanup(result.stopTestRun) now = datetime.datetime.now(utc) - args = [[_u("foo"), s] for s in ['exists', 'inprogress', 'xfail', - 'uxsuccess', 'success', 'fail', 'skip']] + args = [[_u("foo"), s] for s in [ + 'exists', + 'inprogress', + 'xfail', + 'uxsuccess', + 'success', + 'fail', + 'skip', + ]] inputs = list(dict( runnable=False, test_tags=set(['quux']), @@ -537,7 +546,8 @@ def _power_set(self, iterable): "powerset([1,2,3]) --> () (1,) (2,) (3,) (1,2) (1,3) (2,3) (1,2,3)" s = list(iterable) param_dicts = [] - for ss in chain.from_iterable(combinations(s, r) for r in range(len(s)+1)): + combos = (combinations(s, r) for r in range(len(s) + 1)) + for ss in chain.from_iterable(combos): param_dicts.append(dict(ss)) return param_dicts From 58bcab673d0858b0573f199393c3888071d00d6f Mon Sep 17 00:00:00 2001 From: Jonathan Lange Date: Mon, 2 Nov 2015 18:38:11 +0000 Subject: [PATCH 02/10] Fix lint in testresult.real --- testtools/testresult/real.py | 129 ++++++++++++++++++++--------------- 1 file changed, 73 insertions(+), 56 deletions(-) diff --git a/testtools/testresult/real.py b/testtools/testresult/real.py index 44e34684..5ecd24d9 100644 --- a/testtools/testresult/real.py +++ b/testtools/testresult/real.py @@ -47,7 +47,6 @@ # From http://docs.python.org/library/datetime.html _ZERO = datetime.timedelta(0) -# A UTC class. class UTC(datetime.tzinfo): """UTC""" @@ -110,8 +109,8 @@ def addError(self, test, err=None, details=None): :param details: Alternative way to supply details about the outcome. see the class docstring for more information. """ - self.errors.append((test, - self._err_details_to_string(test, err, details))) + self.errors.append( + (test, self._err_details_to_string(test, err, details))) if self.failfast: self.stop() @@ -122,8 +121,8 @@ def addFailure(self, test, err=None, details=None): :param details: Alternative way to supply details about the outcome. see the class docstring for more information. """ - self.failures.append((test, - self._err_details_to_string(test, err, details))) + self.failures.append( + (test, self._err_details_to_string(test, err, details))) if self.failfast: self.stop() @@ -325,8 +324,8 @@ def stopTestRun(self): """ def status(self, test_id=None, test_status=None, test_tags=None, - runnable=True, file_name=None, file_bytes=None, eof=False, - mime_type=None, route_code=None, timestamp=None): + runnable=True, file_name=None, file_bytes=None, eof=False, + mime_type=None, route_code=None, timestamp=None): """Inform the result about a test status. :param test_id: The test whose status is being reported. None to @@ -342,24 +341,24 @@ def status(self, test_id=None, test_status=None, test_tags=None, * None - no particular status is being reported, or status being reported is not associated with a test (e.g. when reporting on stdout / stderr chatter). - * inprogress - the test is currently running. Emitted by tests when - they start running and at any intermediary point they might - choose to indicate their continual operation. + * inprogress - the test is currently running. Emitted by tests + when they start running and at any intermediary point they + might choose to indicate their continual operation. Final states: * exists - the test exists. This is used when a test is not being - executed. Typically this is when querying what tests could be run - in a test run (which is useful for selecting tests to run). + executed. Typically this is when querying what tests could be + run in a test run (which is useful for selecting tests to run). * xfail - the test failed but that was expected. This is purely informative - the test is not considered to be a failure. * uxsuccess - the test passed but was expected to fail. The test will be considered a failure. * success - the test has finished without error. - * fail - the test failed (or errored). The test will be considered - a failure. - * skip - the test was selected to run but chose to be skipped. E.g. - a test dependency was missing. This is purely informative - the - test is not considered to be a failure. + * fail - the test failed (or errored). The test will be + considered a failure. + * skip - the test was selected to run but chose to be skipped. + e.g. a test dependency was missing. This is purely informative- + the test is not considered to be a failure. :param test_tags: Optional set of tags to apply to the test. Tags have no intrinsic meaning - that is up to the test author. @@ -428,8 +427,8 @@ def __init__(self, on_error): self.on_error = on_error def status(self, test_id=None, test_status=None, test_tags=None, - runnable=True, file_name=None, file_bytes=None, eof=False, - mime_type=None, route_code=None, timestamp=None): + runnable=True, file_name=None, file_bytes=None, eof=False, + mime_type=None, route_code=None, timestamp=None): if test_status in ('uxsuccess', 'fail'): self.on_error() @@ -449,7 +448,8 @@ class StreamResultRouter(StreamResult): >>> sink = doubles.StreamResult() >>> router.add_rule(sink, 'route_code_prefix', route_prefix='0', ... consume_route=True) - >>> router.status(test_id='foo', route_code='0/1', test_status='uxsuccess') + >>> router.status( + ... test_id='foo', route_code='0/1', test_status='uxsuccess') StreamResultRouter has no buffering. @@ -617,9 +617,10 @@ def startTestRun(self): self._inprogress = {} def status(self, test_id=None, test_status=None, test_tags=None, - runnable=True, file_name=None, file_bytes=None, eof=False, - mime_type=None, route_code=None, timestamp=None): - super(StreamToDict, self).status(test_id, test_status, + runnable=True, file_name=None, file_bytes=None, eof=False, + mime_type=None, route_code=None, timestamp=None): + super(StreamToDict, self).status( + test_id, test_status, test_tags=test_tags, runnable=runnable, file_name=file_name, file_bytes=file_bytes, eof=eof, mime_type=mime_type, route_code=route_code, timestamp=timestamp) @@ -646,7 +647,7 @@ def status(self, test_id=None, test_status=None, test_tags=None, content_type = ContentType(primary, sub, parameters) content_bytes = [] case['details'][file_name] = Content( - content_type, lambda:content_bytes) + content_type, lambda: content_bytes) case['details'][file_name].iter_bytes().append(file_bytes) if test_tags is not None: self._inprogress[key]['tags'] = test_tags @@ -698,8 +699,8 @@ def test_dict_to_case(test_dict): from testtools.testcase import PlaceHolder outcome = _status_map[test_dict['status']] return PlaceHolder(test_dict['id'], outcome=outcome, - details=test_dict['details'], tags=test_dict['tags'], - timestamps=test_dict['timestamps']) + details=test_dict['details'], tags=test_dict['tags'], + timestamps=test_dict['timestamps']) class StreamSummary(StreamToDict): @@ -812,12 +813,14 @@ def _dispatch(self, message, *args, **kwargs): def _get_failfast(self): return getattr(self._results[0], 'failfast', False) + def _set_failfast(self, value): self._dispatch('__setattr__', 'failfast', value) failfast = property(_get_failfast, _set_failfast) def _get_shouldStop(self): return any(self._dispatch('__getattr__', 'shouldStop')) + def _set_shouldStop(self, value): # Called because we subclass TestResult. Probably should not do that. pass @@ -895,8 +898,9 @@ def _delta_to_float(self, a_timedelta, precision): # to decide whether to round/floor/ceiling. This was added when we # had pyp3 test failures that suggest a floor was happening. shift = 10 ** precision - return math.ceil((a_timedelta.days * 86400.0 + a_timedelta.seconds + - a_timedelta.microseconds / 1000000.0) * shift) / shift + return math.ceil( + (a_timedelta.days * 86400.0 + a_timedelta.seconds + + a_timedelta.microseconds / 1000000.0) * shift) / shift def _show_list(self, label, error_list): for test, output in error_list: @@ -922,9 +926,10 @@ def stopTestRun(self): self.stream.write( "%sUNEXPECTED SUCCESS: %s\n%s" % ( self.sep1, test.id(), self.sep2)) - self.stream.write("\nRan %d test%s in %.3fs\n" % - (self.testsRun, plural, - self._delta_to_float(stop - self.__start, 3))) + self.stream.write( + "\nRan %d test%s in %.3fs\n" % ( + self.testsRun, plural, + self._delta_to_float(stop - self.__start, 3))) if self.wasSuccessful(): self.stream.write("OK\n") else: @@ -1004,28 +1009,28 @@ def _add_result_with_semaphore(self, method, test, *args, **kwargs): self._test_start = None def addError(self, test, err=None, details=None): - self._add_result_with_semaphore(self.result.addError, - test, err, details=details) + self._add_result_with_semaphore( + self.result.addError, test, err, details=details) def addExpectedFailure(self, test, err=None, details=None): - self._add_result_with_semaphore(self.result.addExpectedFailure, - test, err, details=details) + self._add_result_with_semaphore( + self.result.addExpectedFailure, test, err, details=details) def addFailure(self, test, err=None, details=None): - self._add_result_with_semaphore(self.result.addFailure, - test, err, details=details) + self._add_result_with_semaphore( + self.result.addFailure, test, err, details=details) def addSkip(self, test, reason=None, details=None): - self._add_result_with_semaphore(self.result.addSkip, - test, reason, details=details) + self._add_result_with_semaphore( + self.result.addSkip, test, reason, details=details) def addSuccess(self, test, details=None): - self._add_result_with_semaphore(self.result.addSuccess, - test, details=details) + self._add_result_with_semaphore( + self.result.addSuccess, test, details=details) def addUnexpectedSuccess(self, test, details=None): - self._add_result_with_semaphore(self.result.addUnexpectedSuccess, - test, details=details) + self._add_result_with_semaphore( + self.result.addUnexpectedSuccess, test, details=details) def progress(self, offset, whence): pass @@ -1044,6 +1049,7 @@ def _get_shouldStop(self): return self.result.shouldStop finally: self.semaphore.release() + def _set_shouldStop(self, value): # Another case where we should not subclass TestResult pass @@ -1212,7 +1218,8 @@ def _check_args(self, err, details): if details is not None: param_count += 1 if param_count != 1: - raise ValueError("Must pass only one of err '%s' and details '%s" + raise ValueError( + "Must pass only one of err '%s' and details '%s" % (err, details)) def _details_to_exc_info(self, details): @@ -1235,6 +1242,7 @@ def done(self): def _get_failfast(self): return getattr(self.decorated, 'failfast', self._failfast) + def _set_failfast(self, value): if safe_hasattr(self.decorated, 'failfast'): self.decorated.failfast = value @@ -1311,6 +1319,7 @@ def __init__(self, decorated): def _get_failfast(self): return len(self.targets) == 2 + def _set_failfast(self, value): if value: if len(self.targets) == 2: @@ -1323,7 +1332,8 @@ def _set_failfast(self, value): def startTest(self, test): if not self._started: self.startTestRun() - self.status(test_id=test.id(), test_status='inprogress', timestamp=self._now()) + self.status( + test_id=test.id(), test_status='inprogress', timestamp=self._now()) self._tags = TagContext(self._tags) def stopTest(self, test): @@ -1349,18 +1359,23 @@ def _convert(self, test, err, details, status, reason=None): file_bytes = None for next_bytes in content.iter_bytes(): if file_bytes is not None: - self.status(file_name=name, file_bytes=file_bytes, - mime_type=mime_type, test_id=test_id, timestamp=now) + self.status( + file_name=name, file_bytes=file_bytes, + mime_type=mime_type, test_id=test_id, + timestamp=now) file_bytes = next_bytes if file_bytes is None: file_bytes = _b("") - self.status(file_name=name, file_bytes=file_bytes, eof=True, + self.status( + file_name=name, file_bytes=file_bytes, eof=True, mime_type=mime_type, test_id=test_id, timestamp=now) if reason is not None: - self.status(file_name='reason', file_bytes=reason.encode('utf8'), + self.status( + file_name='reason', file_bytes=reason.encode('utf8'), eof=True, mime_type="text/plain; charset=utf8", test_id=test_id, timestamp=now) - self.status(test_id=test_id, test_status=status, + self.status( + test_id=test_id, test_status=status, test_tags=self.current_tags, timestamp=now) def addExpectedFailure(self, test, err=None, details=None): @@ -1383,7 +1398,8 @@ def _check_args(self, err, details): if details is not None: param_count += 1 if param_count != 1: - raise ValueError("Must pass only one of err '%s' and details '%s" + raise ValueError( + "Must pass only one of err '%s' and details '%s" % (err, details)) def startTestRun(self): @@ -1512,9 +1528,10 @@ def startTestRun(self): self.queue.put(dict(event='startTestRun', result=self)) def status(self, test_id=None, test_status=None, test_tags=None, - runnable=True, file_name=None, file_bytes=None, eof=False, - mime_type=None, route_code=None, timestamp=None): - self.queue.put(dict(event='status', test_id=test_id, + runnable=True, file_name=None, file_bytes=None, eof=False, + mime_type=None, route_code=None, timestamp=None): + self.queue.put(dict( + event='status', test_id=test_id, test_status=test_status, test_tags=test_tags, runnable=runnable, file_name=file_name, file_bytes=file_bytes, eof=eof, mime_type=mime_type, route_code=self.route_code(route_code), @@ -1718,8 +1735,8 @@ class _StringException(Exception): if not str_is_unicode: def __init__(self, string): if type(string) is not unicode: - raise TypeError("_StringException expects unicode, got %r" % - (string,)) + raise TypeError( + "_StringException expects unicode, got %r" % (string,)) Exception.__init__(self, string) def __str__(self): From ac8142979c8a50c875764a72947692efa8d9bf97 Mon Sep 17 00:00:00 2001 From: Jonathan Lange Date: Mon, 2 Nov 2015 18:31:25 +0000 Subject: [PATCH 03/10] Allow event_log to be passed to result doubles --- testtools/testresult/doubles.py | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/testtools/testresult/doubles.py b/testtools/testresult/doubles.py index 493ae800..bc7dbace 100644 --- a/testtools/testresult/doubles.py +++ b/testtools/testresult/doubles.py @@ -16,8 +16,10 @@ class LoggingBase(object): """Basic support for logging of results.""" - def __init__(self): - self._events = [] + def __init__(self, event_log=None): + if event_log is None: + event_log = [] + self._events = event_log self.shouldStop = False self._was_successful = True self.testsRun = 0 @@ -54,8 +56,8 @@ def wasSuccessful(self): class Python27TestResult(Python26TestResult): """A precisely python 2.7 like test result, that logs.""" - def __init__(self): - super(Python27TestResult, self).__init__() + def __init__(self, event_log=None): + super(Python27TestResult, self).__init__(event_log) self.failfast = False def addError(self, test, err): @@ -89,8 +91,8 @@ def stopTestRun(self): class ExtendedTestResult(Python27TestResult): """A test result like the proposed extended unittest result API.""" - def __init__(self): - super(ExtendedTestResult, self).__init__() + def __init__(self, event_log=None): + super(ExtendedTestResult, self).__init__(event_log) self._tags = TagContext() def addError(self, test, err=None, details=None): @@ -157,8 +159,10 @@ class StreamResult(object): All events are logged to _events. """ - def __init__(self): - self._events = [] + def __init__(self, event_log=None): + if event_log is None: + event_log = [] + self._events = event_log def startTestRun(self): self._events.append(('startTestRun',)) From 52c953afd7bcd968d60627ffaa8778609773a22c Mon Sep 17 00:00:00 2001 From: Jonathan Lange Date: Mon, 2 Nov 2015 18:39:28 +0000 Subject: [PATCH 04/10] Remove duplicate implementation of method --- testtools/testresult/real.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/testtools/testresult/real.py b/testtools/testresult/real.py index 5ecd24d9..bba62fdc 100644 --- a/testtools/testresult/real.py +++ b/testtools/testresult/real.py @@ -1409,9 +1409,6 @@ def startTestRun(self): self.__now = None self._started = True - def stopTest(self, test): - self._tags = self._tags.parent - @property def current_tags(self): """The currently set tags.""" From ad1e0d6c4d0413a91fbc7bf1461c1ec8a7a2ac35 Mon Sep 17 00:00:00 2001 From: Jonathan Lange Date: Mon, 2 Nov 2015 18:45:19 +0000 Subject: [PATCH 05/10] Document confusing `domap` --- testtools/testresult/real.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/testtools/testresult/real.py b/testtools/testresult/real.py index bba62fdc..e0d6cf7f 100644 --- a/testtools/testresult/real.py +++ b/testtools/testresult/real.py @@ -1,4 +1,4 @@ -# Copyright (c) 2008-2012 testtools developers. See LICENSE for details. +# Copyright (c) 2008-2015 testtools developers. See LICENSE for details. """Test results and related things.""" @@ -385,8 +385,9 @@ def status(self, test_id=None, test_status=None, test_tags=None, """ -def domap(*args, **kwargs): - return list(map(*args, **kwargs)) +def strict_map(f, xs): + """A version of 'map' that's guaranteed to run on all inputs.""" + return list(map(f, xs)) class CopyStreamResult(StreamResult): @@ -403,15 +404,15 @@ def __init__(self, targets): def startTestRun(self): super(CopyStreamResult, self).startTestRun() - domap(methodcaller('startTestRun'), self.targets) + strict_map(methodcaller('startTestRun'), self.targets) def stopTestRun(self): super(CopyStreamResult, self).stopTestRun() - domap(methodcaller('stopTestRun'), self.targets) + strict_map(methodcaller('stopTestRun'), self.targets) def status(self, *args, **kwargs): super(CopyStreamResult, self).status(*args, **kwargs) - domap(methodcaller('status', *args, **kwargs), self.targets) + strict_map(methodcaller('status', *args, **kwargs), self.targets) class StreamFailFast(StreamResult): From bb220ee20cae3f285d8a2f600aabeb89a3a4349a Mon Sep 17 00:00:00 2001 From: Jonathan Lange Date: Mon, 2 Nov 2015 18:55:10 +0000 Subject: [PATCH 06/10] Drop `__metaclass__` declaration --- testtools/testresult/real.py | 1 - 1 file changed, 1 deletion(-) diff --git a/testtools/testresult/real.py b/testtools/testresult/real.py index e0d6cf7f..a2be0a6f 100644 --- a/testtools/testresult/real.py +++ b/testtools/testresult/real.py @@ -2,7 +2,6 @@ """Test results and related things.""" -__metaclass__ = type __all__ = [ 'ExtendedToOriginalDecorator', 'ExtendedToStreamDecorator', From 7c7f747f1092c8845a96041fff85d685703339e0 Mon Sep 17 00:00:00 2001 From: Jonathan Lange Date: Tue, 3 Nov 2015 10:28:23 +0000 Subject: [PATCH 07/10] Spell out `f` and `xs` --- testtools/testresult/real.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/testtools/testresult/real.py b/testtools/testresult/real.py index a2be0a6f..665d3012 100644 --- a/testtools/testresult/real.py +++ b/testtools/testresult/real.py @@ -384,9 +384,9 @@ def status(self, test_id=None, test_status=None, test_tags=None, """ -def strict_map(f, xs): +def strict_map(function, items): """A version of 'map' that's guaranteed to run on all inputs.""" - return list(map(f, xs)) + return list(map(function, items)) class CopyStreamResult(StreamResult): From 5c308ec9894d341d052bdbb857c2d2f82db0947c Mon Sep 17 00:00:00 2001 From: Jonathan Lange Date: Fri, 6 Nov 2015 12:56:54 +0000 Subject: [PATCH 08/10] Restore & deprecate domap * Private name for `_strict_map` * Use `map` signature to `_strict_map` * Add alias `domap` with deprecation warning --- testtools/testresult/real.py | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/testtools/testresult/real.py b/testtools/testresult/real.py index 665d3012..fbee6305 100644 --- a/testtools/testresult/real.py +++ b/testtools/testresult/real.py @@ -26,6 +26,7 @@ from operator import methodcaller import sys import unittest +import warnings from extras import safe_hasattr, try_import, try_imports parse_mime_type = try_import('mimeparse.parse_mime_type') @@ -384,9 +385,21 @@ def status(self, test_id=None, test_status=None, test_tags=None, """ -def strict_map(function, items): - """A version of 'map' that's guaranteed to run on all inputs.""" - return list(map(function, items)) +def domap(function, *sequences): + """A strict version of 'map' that's guaranteed to run on all inputs. + + DEPRECATED since testtools 1.8.1: Internal code should use _strict_map. + External code should look for other solutions for their strict mapping + needs. + """ + warnings.warn( + "domap deprecated since 1.8.1. Please implement your own strict map.", + DeprecationWarning, stacklevel=2) + return _strict_map(function, *sequences) + + +def _strict_map(function, *sequences): + return list(map(function, *sequences)) class CopyStreamResult(StreamResult): @@ -403,15 +416,15 @@ def __init__(self, targets): def startTestRun(self): super(CopyStreamResult, self).startTestRun() - strict_map(methodcaller('startTestRun'), self.targets) + _strict_map(methodcaller('startTestRun'), self.targets) def stopTestRun(self): super(CopyStreamResult, self).stopTestRun() - strict_map(methodcaller('stopTestRun'), self.targets) + _strict_map(methodcaller('stopTestRun'), self.targets) def status(self, *args, **kwargs): super(CopyStreamResult, self).status(*args, **kwargs) - strict_map(methodcaller('status', *args, **kwargs), self.targets) + _strict_map(methodcaller('status', *args, **kwargs), self.targets) class StreamFailFast(StreamResult): From 5690ca26a02b8d4667576de79c3596a44e64646b Mon Sep 17 00:00:00 2001 From: Jonathan Lange Date: Fri, 6 Nov 2015 13:18:22 +0000 Subject: [PATCH 09/10] Update PlaceHolder indentation --- testtools/testresult/real.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/testtools/testresult/real.py b/testtools/testresult/real.py index fbee6305..8773c65f 100644 --- a/testtools/testresult/real.py +++ b/testtools/testresult/real.py @@ -711,9 +711,9 @@ def test_dict_to_case(test_dict): if PlaceHolder is None: from testtools.testcase import PlaceHolder outcome = _status_map[test_dict['status']] - return PlaceHolder(test_dict['id'], outcome=outcome, - details=test_dict['details'], tags=test_dict['tags'], - timestamps=test_dict['timestamps']) + return PlaceHolder( + test_dict['id'], outcome=outcome, details=test_dict['details'], + tags=test_dict['tags'], timestamps=test_dict['timestamps']) class StreamSummary(StreamToDict): From eb2374bde2a75ffa395c44352f5e8859e45bcc3a Mon Sep 17 00:00:00 2001 From: Jonathan Lange Date: Fri, 6 Nov 2015 13:41:45 +0000 Subject: [PATCH 10/10] Remove VWS --- testtools/tests/test_testresult.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/testtools/tests/test_testresult.py b/testtools/tests/test_testresult.py index e81c139c..3e57066d 100644 --- a/testtools/tests/test_testresult.py +++ b/testtools/tests/test_testresult.py @@ -224,14 +224,11 @@ def test_startStopTestRun(self): def test_failfast(self): result = self.makeResult() result.failfast = True - class Failing(TestCase): def test_a(self): self.fail('a') - def test_b(self): self.fail('b') - TestSuite([Failing('test_a'), Failing('test_b')]).run(result) self.assertEqual(1, result.testsRun)