def __init__(self, client, stream=None, forward_stream=None): """Create a TestProtocolServer instance. :param client: An object meeting the unittest.TestResult protocol. :param stream: The stream that lines received which are not part of the subunit protocol should be written to. This allows custom handling of mixed protocols. By default, sys.stdout will be used for convenience. :param forward_stream: A stream to forward subunit lines to. This allows a filter to forward the entire stream while still parsing and acting on it. By default forward_stream is set to DiscardStream() and no forwarding happens. """ self.client = ExtendedToOriginalDecorator(client) if stream is None: stream = sys.stdout self._stream = stream self._forward_stream = forward_stream or DiscardStream() # state objects we can switch too self._in_test = _InTest(self) self._outside_test = _OutSideTest(self) self._reading_error_details = _ReadingErrorDetails(self) self._reading_failure_details = _ReadingFailureDetails(self) self._reading_skip_details = _ReadingSkipDetails(self) self._reading_success_details = _ReadingSuccessDetails(self) self._reading_xfail_details = _ReadingExpectedFailureDetails(self) # start with outside test. self._state = self._outside_test
def __init__(self, client, stream=None, forward_stream=None): """Create a TestProtocolServer instance. :param client: An object meeting the unittest.TestResult protocol. :param stream: The stream that lines received which are not part of the subunit protocol should be written to. This allows custom handling of mixed protocols. By default, sys.stdout will be used for convenience. It should accept bytes to its write() method. :param forward_stream: A stream to forward subunit lines to. This allows a filter to forward the entire stream while still parsing and acting on it. By default forward_stream is set to DiscardStream() and no forwarding happens. """ self.client = ExtendedToOriginalDecorator(client) if stream is None: stream = sys.stdout if sys.version_info > (3, 0): stream = stream.buffer self._stream = stream self._forward_stream = forward_stream or DiscardStream() # state objects we can switch too self._in_test = _InTest(self) self._outside_test = _OutSideTest(self) self._reading_error_details = _ReadingErrorDetails(self) self._reading_failure_details = _ReadingFailureDetails(self) self._reading_skip_details = _ReadingSkipDetails(self) self._reading_success_details = _ReadingSuccessDetails(self) self._reading_xfail_details = _ReadingExpectedFailureDetails(self) self._reading_uxsuccess_details = _ReadingUnexpectedSuccessDetails(self) # start with outside test. self._state = self._outside_test # Avoid casts on every call self._plusminus = _b('+-') self._push_sym = _b('push') self._pop_sym = _b('pop')
def _construct_xml(**kwargs): from junitxml import JUnitXmlResult stream = kwargs.pop('stream') failfast = kwargs.pop('failfast') _raise_on_unknown_kwargs(kwargs) result_object = LoggedTestResultDecorator( ExtendedToOriginalDecorator(JUnitXmlResult(stream))) result_object.failfast = failfast return result_object
class TestProtocolServer(object): """A parser for subunit. :ivar tags: The current tags associated with the protocol stream. """ def __init__(self, client, stream=None, forward_stream=None): """Create a TestProtocolServer instance. :param client: An object meeting the unittest.TestResult protocol. :param stream: The stream that lines received which are not part of the subunit protocol should be written to. This allows custom handling of mixed protocols. By default, sys.stdout will be used for convenience. It should accept bytes to its write() method. :param forward_stream: A stream to forward subunit lines to. This allows a filter to forward the entire stream while still parsing and acting on it. By default forward_stream is set to DiscardStream() and no forwarding happens. """ self.client = ExtendedToOriginalDecorator(client) if stream is None: stream = sys.stdout if sys.version_info > (3, 0): stream = stream.buffer self._stream = stream self._forward_stream = forward_stream or DiscardStream() # state objects we can switch too self._in_test = _InTest(self) self._outside_test = _OutSideTest(self) self._reading_error_details = _ReadingErrorDetails(self) self._reading_failure_details = _ReadingFailureDetails(self) self._reading_skip_details = _ReadingSkipDetails(self) self._reading_success_details = _ReadingSuccessDetails(self) self._reading_xfail_details = _ReadingExpectedFailureDetails(self) self._reading_uxsuccess_details = _ReadingUnexpectedSuccessDetails(self) # start with outside test. self._state = self._outside_test # Avoid casts on every call self._plusminus = _b('+-') self._push_sym = _b('push') self._pop_sym = _b('pop') def _handleProgress(self, offset, line): """Process a progress directive.""" line = line[offset:].strip() if line[0] in self._plusminus: whence = PROGRESS_CUR delta = int(line) elif line == self._push_sym: whence = PROGRESS_PUSH delta = None elif line == self._pop_sym: whence = PROGRESS_POP delta = None else: whence = PROGRESS_SET delta = int(line) self.client.progress(delta, whence) def _handleTags(self, offset, line): """Process a tags command.""" tags = line[offset:].decode('utf8').split() new_tags, gone_tags = tags_to_new_gone(tags) self.client.tags(new_tags, gone_tags) def _handleTime(self, offset, line): # Accept it, but do not do anything with it yet. try: event_time = iso8601.parse_date(line[offset:-1]) except TypeError: raise TypeError(_u("Failed to parse %r, got %r") % (line, sys.exec_info[1])) self.client.time(event_time) def lineReceived(self, line): """Call the appropriate local method for the received line.""" self._state.lineReceived(line) def _lostConnectionInTest(self, state_string): error_string = _u("lost connection during %stest '%s'") % ( state_string, self.current_test_description) self.client.addError(self._current_test, RemoteError(error_string)) self.client.stopTest(self._current_test) def lostConnection(self): """The input connection has finished.""" self._state.lostConnection() def readFrom(self, pipe): """Blocking convenience API to parse an entire stream. :param pipe: A file-like object supporting readlines(). :return: None. """ for line in pipe.readlines(): self.lineReceived(line) self.lostConnection() def _startTest(self, offset, line): """Internal call to change state machine. Override startTest().""" self._state.startTest(offset, line) def subunitLineReceived(self, line): self._forward_stream.write(line) def stdOutLineReceived(self, line): self._stream.write(line)
class TestProtocolServer(object): """A parser for subunit. :ivar tags: The current tags associated with the protocol stream. """ def __init__(self, client, stream=None, forward_stream=None): """Create a TestProtocolServer instance. :param client: An object meeting the unittest.TestResult protocol. :param stream: The stream that lines received which are not part of the subunit protocol should be written to. This allows custom handling of mixed protocols. By default, sys.stdout will be used for convenience. :param forward_stream: A stream to forward subunit lines to. This allows a filter to forward the entire stream while still parsing and acting on it. By default forward_stream is set to DiscardStream() and no forwarding happens. """ self.client = ExtendedToOriginalDecorator(client) if stream is None: stream = sys.stdout self._stream = stream self._forward_stream = forward_stream or DiscardStream() # state objects we can switch too self._in_test = _InTest(self) self._outside_test = _OutSideTest(self) self._reading_error_details = _ReadingErrorDetails(self) self._reading_failure_details = _ReadingFailureDetails(self) self._reading_skip_details = _ReadingSkipDetails(self) self._reading_success_details = _ReadingSuccessDetails(self) self._reading_xfail_details = _ReadingExpectedFailureDetails(self) # start with outside test. self._state = self._outside_test def _handleProgress(self, offset, line): """Process a progress directive.""" line = line[offset:].strip() if line[0] in '+-': whence = PROGRESS_CUR delta = int(line) elif line == "push": whence = PROGRESS_PUSH delta = None elif line == "pop": whence = PROGRESS_POP delta = None else: whence = PROGRESS_SET delta = int(line) self.client.progress(delta, whence) def _handleTags(self, offset, line): """Process a tags command.""" tags = line[offset:].split() new_tags, gone_tags = tags_to_new_gone(tags) self.client.tags(new_tags, gone_tags) def _handleTime(self, offset, line): # Accept it, but do not do anything with it yet. try: event_time = iso8601.parse_date(line[offset:-1]) except TypeError, e: raise TypeError("Failed to parse %r, got %r" % (line, e)) self.client.time(event_time)
def make_converter(self): self.converter = ExtendedToOriginalDecorator(self.result)
class TestExtendedToOriginalResultDecoratorBase(TestCase): def make_26_result(self): self.result = Python26TestResult() self.make_converter() def make_27_result(self): self.result = Python27TestResult() self.make_converter() def make_converter(self): self.converter = ExtendedToOriginalDecorator(self.result) def make_extended_result(self): self.result = ExtendedTestResult() self.make_converter() def check_outcome_details(self, outcome): """Call an outcome with a details dict to be passed through.""" # This dict is /not/ convertible - thats deliberate, as it should # not hit the conversion code path. details = {'foo': 'bar'} getattr(self.converter, outcome)(self, details=details) self.assertEqual([(outcome, self, details)], self.result._events) def get_details_and_string(self): """Get a details dict and expected string.""" text1 = lambda: [_b("1\n2\n")] text2 = lambda: [_b("3\n4\n")] bin1 = lambda: [_b("5\n")] details = {'text 1': Content(ContentType('text', 'plain'), text1), 'text 2': Content(ContentType('text', 'strange'), text2), 'bin 1': Content(ContentType('application', 'binary'), bin1)} return (details, "Binary content: bin 1\n" "Text attachment: text 1\n------------\n1\n2\n" "------------\nText attachment: text 2\n------------\n" "3\n4\n------------\n") def check_outcome_details_to_exec_info(self, outcome, expected=None): """Call an outcome with a details dict to be made into exc_info.""" # The conversion is a done using RemoteError and the string contents # of the text types in the details dict. if not expected: expected = outcome details, err_str = self.get_details_and_string() getattr(self.converter, outcome)(self, details=details) err = self.converter._details_to_exc_info(details) self.assertEqual([(expected, self, err)], self.result._events) def check_outcome_details_to_nothing(self, outcome, expected=None): """Call an outcome with a details dict to be swallowed.""" if not expected: expected = outcome details = {'foo': 'bar'} getattr(self.converter, outcome)(self, details=details) self.assertEqual([(expected, self)], self.result._events) def check_outcome_details_to_string(self, outcome): """Call an outcome with a details dict to be stringified.""" details, err_str = self.get_details_and_string() getattr(self.converter, outcome)(self, details=details) self.assertEqual([(outcome, self, err_str)], self.result._events) def check_outcome_details_to_arg(self, outcome, arg, extra_detail=None): """Call an outcome with a details dict to have an arg extracted.""" details, _ = self.get_details_and_string() if extra_detail: details.update(extra_detail) getattr(self.converter, outcome)(self, details=details) self.assertEqual([(outcome, self, arg)], self.result._events) def check_outcome_exc_info(self, outcome, expected=None): """Check that calling a legacy outcome still works.""" # calling some outcome with the legacy exc_info style api (no keyword # parameters) gets passed through. if not expected: expected = outcome err = sys.exc_info() getattr(self.converter, outcome)(self, err) self.assertEqual([(expected, self, err)], self.result._events) def check_outcome_exc_info_to_nothing(self, outcome, expected=None): """Check that calling a legacy outcome on a fallback works.""" # calling some outcome with the legacy exc_info style api (no keyword # parameters) gets passed through. if not expected: expected = outcome err = sys.exc_info() getattr(self.converter, outcome)(self, err) self.assertEqual([(expected, self)], self.result._events) def check_outcome_nothing(self, outcome, expected=None): """Check that calling a legacy outcome still works.""" if not expected: expected = outcome getattr(self.converter, outcome)(self) self.assertEqual([(expected, self)], self.result._events) def check_outcome_string_nothing(self, outcome, expected): """Check that calling outcome with a string calls expected.""" getattr(self.converter, outcome)(self, "foo") self.assertEqual([(expected, self)], self.result._events) def check_outcome_string(self, outcome): """Check that calling outcome with a string works.""" getattr(self.converter, outcome)(self, "foo") self.assertEqual([(outcome, self, "foo")], self.result._events)
def makeResult(self): return ExtendedToOriginalDecorator(Python27TestResult())