Skip to content

Commit b910646

Browse files
authored
Merge pull request #94 from testing-cabal/testtools-compat
Drop use of Python26TestResult and Python27TestResult
2 parents 4dc3e0d + 4b1599a commit b910646

File tree

2 files changed

+79
-197
lines changed

2 files changed

+79
-197
lines changed

NEWS

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,22 @@ subunit release notes
55
NEXT (In development)
66
---------------------
77

8+
BUG FIXES
9+
~~~~~~~~~
10+
11+
* Drop support for Python 3.9.
12+
(Jelmer Vernooij)
13+
14+
* Drop use of Python26 and Python27 test cases from testtools.
15+
These are no longer relevant and no longer provided by
16+
modern versions of testtools. (Jelmer Vernooij)
17+
18+
IMPROVEMENTS
19+
~~~~~~~~~~~~
20+
21+
* Add support for Python 3.14.
22+
(Jelmer Vernooij)
23+
824
1.4.4 (2023-11-17)
925
------------------
1026

python/subunit/tests/test_test_protocol.py

Lines changed: 63 additions & 197 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
from testtools.content import Content, TracebackContent, text_content
2626
from testtools.content_type import ContentType
2727

28-
from testtools.testresult.doubles import ExtendedTestResult, Python26TestResult, Python27TestResult
28+
from testtools.testresult.doubles import ExtendedTestResult
2929

3030
from testtools.matchers import Contains, Equals, MatchesAny
3131

@@ -147,7 +147,7 @@ def test_non_test_characters_forwarded_immediately(self):
147147

148148
class TestTestProtocolServerStartTest(unittest.TestCase):
149149
def setUp(self):
150-
self.client = Python26TestResult()
150+
self.client = ExtendedTestResult()
151151
self.stream = BytesIO()
152152
self.protocol = subunit.TestProtocolServer(self.client, self.stream)
153153

@@ -327,7 +327,7 @@ def test_stdout_passthrough(self):
327327

328328
class TestTestProtocolServerLostConnection(unittest.TestCase):
329329
def setUp(self):
330-
self.client = Python26TestResult()
330+
self.client = ExtendedTestResult()
331331
self.protocol = subunit.TestProtocolServer(self.client)
332332
self.test = subunit.RemotedTestCase("old mcdonald")
333333

@@ -355,7 +355,7 @@ def test_lost_connected_after_error(self):
355355
self.assertEqual(
356356
[
357357
("startTest", self.test),
358-
("addError", self.test, subunit.RemoteError("")),
358+
("addError", self.test, {}),
359359
("stopTest", self.test),
360360
],
361361
self.client._events,
@@ -388,7 +388,7 @@ def test_lost_connected_after_failure(self):
388388
self.assertEqual(
389389
[
390390
("startTest", self.test),
391-
("addFailure", self.test, subunit.RemoteError("")),
391+
("addFailure", self.test, {}),
392392
("stopTest", self.test),
393393
],
394394
self.client._events,
@@ -565,248 +565,114 @@ def test_failure_colon_quoted_bracket(self):
565565

566566

567567
class TestTestProtocolServerAddxFail(unittest.TestCase):
568-
"""Tests for the xfail keyword.
569-
570-
In Python this can thunk through to Success due to stdlib limitations (see
571-
README).
572-
"""
573-
574-
def capture_expected_failure(self, test, err):
575-
self._events.append((test, err))
576-
577-
def setup_python26(self):
578-
"""Setup a test object ready to be xfailed and thunk to success."""
579-
self.client = Python26TestResult()
580-
self.setup_protocol()
568+
"""Tests for the xfail keyword."""
581569

582-
def setup_python27(self):
583-
"""Setup a test object ready to be xfailed."""
584-
self.client = Python27TestResult()
585-
self.setup_protocol()
586-
587-
def setup_python_ex(self):
570+
def setUp(self):
588571
"""Setup a test object ready to be xfailed with details."""
589572
self.client = ExtendedTestResult()
590-
self.setup_protocol()
591-
592-
def setup_protocol(self):
593-
"""Setup the protocol based on self.client."""
594573
self.protocol = subunit.TestProtocolServer(self.client)
595574
self.protocol.lineReceived(b"test mcdonalds farm\n")
596575
self.test = self.client._events[-1][-1]
597576

598-
def simple_xfail_keyword(self, keyword, as_success):
577+
def simple_xfail_keyword(self, keyword):
599578
self.protocol.lineReceived(("%s mcdonalds farm\n" % keyword).encode())
600-
self.check_success_or_xfail(as_success)
601-
602-
def check_success_or_xfail(self, as_success, error_message=None):
603-
if as_success:
604-
self.assertEqual(
605-
[
606-
("startTest", self.test),
607-
("addSuccess", self.test),
608-
("stopTest", self.test),
609-
],
610-
self.client._events,
611-
)
612-
else:
613-
details = {}
614-
if error_message is not None:
615-
details["traceback"] = Content(
616-
ContentType("text", "x-traceback", {"charset": "utf8"}), lambda: [error_message.encode()]
617-
)
618-
if isinstance(self.client, ExtendedTestResult):
619-
value = details
620-
else:
621-
if error_message is not None:
622-
value = subunit.RemoteError(details_to_str(details))
623-
else:
624-
value = subunit.RemoteError()
625-
self.assertEqual(
626-
[
627-
("startTest", self.test),
628-
("addExpectedFailure", self.test, value),
629-
("stopTest", self.test),
630-
],
631-
self.client._events,
579+
self.check_xfail()
580+
581+
def check_xfail(self, error_message=None):
582+
details = {}
583+
if error_message is not None:
584+
details["traceback"] = Content(
585+
ContentType("text", "x-traceback", {"charset": "utf8"}), lambda: [error_message.encode()]
632586
)
587+
self.assertEqual(
588+
[
589+
("startTest", self.test),
590+
("addExpectedFailure", self.test, details),
591+
("stopTest", self.test),
592+
],
593+
self.client._events,
594+
)
633595

634596
def test_simple_xfail(self):
635-
self.setup_python26()
636-
self.simple_xfail_keyword("xfail", True)
637-
self.setup_python27()
638-
self.simple_xfail_keyword("xfail", False)
639-
self.setup_python_ex()
640-
self.simple_xfail_keyword("xfail", False)
597+
self.simple_xfail_keyword("xfail")
641598

642599
def test_simple_xfail_colon(self):
643-
self.setup_python26()
644-
self.simple_xfail_keyword("xfail:", True)
645-
self.setup_python27()
646-
self.simple_xfail_keyword("xfail:", False)
647-
self.setup_python_ex()
648-
self.simple_xfail_keyword("xfail:", False)
600+
self.simple_xfail_keyword("xfail:")
649601

650602
def test_xfail_empty_message(self):
651-
self.setup_python26()
652-
self.empty_message(True)
653-
self.setup_python27()
654-
self.empty_message(False)
655-
self.setup_python_ex()
656-
self.empty_message(False, error_message="")
657-
658-
def empty_message(self, as_success, error_message="\n"):
659603
self.protocol.lineReceived(b"xfail mcdonalds farm [\n")
660604
self.protocol.lineReceived(b"]\n")
661-
self.check_success_or_xfail(as_success, error_message)
605+
self.check_xfail(error_message="")
662606

663-
def xfail_quoted_bracket(self, keyword, as_success):
664-
# This tests it is accepted, but cannot test it is used today, because
665-
# of not having a way to expose it in Python so far.
666-
self.protocol.lineReceived(("%s mcdonalds farm [\n" % keyword).encode())
607+
def test_xfail_quoted_bracket(self):
608+
self.protocol.lineReceived(b"xfail mcdonalds farm [\n")
667609
self.protocol.lineReceived(b" ]\n")
668610
self.protocol.lineReceived(b"]\n")
669-
self.check_success_or_xfail(as_success, "]\n")
670-
671-
def test_xfail_quoted_bracket(self):
672-
self.setup_python26()
673-
self.xfail_quoted_bracket("xfail", True)
674-
self.setup_python27()
675-
self.xfail_quoted_bracket("xfail", False)
676-
self.setup_python_ex()
677-
self.xfail_quoted_bracket("xfail", False)
611+
self.check_xfail("]\n")
678612

679613
def test_xfail_colon_quoted_bracket(self):
680-
self.setup_python26()
681-
self.xfail_quoted_bracket("xfail:", True)
682-
self.setup_python27()
683-
self.xfail_quoted_bracket("xfail:", False)
684-
self.setup_python_ex()
685-
self.xfail_quoted_bracket("xfail:", False)
614+
self.protocol.lineReceived(b"xfail: mcdonalds farm [\n")
615+
self.protocol.lineReceived(b" ]\n")
616+
self.protocol.lineReceived(b"]\n")
617+
self.check_xfail("]\n")
686618

687619

688620
class TestTestProtocolServerAddunexpectedSuccess(TestCase):
689621
"""Tests for the uxsuccess keyword."""
690622

691-
def capture_expected_failure(self, test, err):
692-
self._events.append((test, err))
693-
694-
def setup_python26(self):
695-
"""Setup a test object ready to be xfailed and thunk to success."""
696-
self.client = Python26TestResult()
697-
self.setup_protocol()
698-
699-
def setup_python27(self):
700-
"""Setup a test object ready to be xfailed."""
701-
self.client = Python27TestResult()
702-
self.setup_protocol()
703-
704-
def setup_python_ex(self):
705-
"""Setup a test object ready to be xfailed with details."""
623+
def setUp(self):
624+
"""Setup a test object ready for uxsuccess with details."""
625+
super().setUp()
706626
self.client = ExtendedTestResult()
707-
self.setup_protocol()
708-
709-
def setup_protocol(self):
710-
"""Setup the protocol based on self.client."""
711627
self.protocol = subunit.TestProtocolServer(self.client)
712628
self.protocol.lineReceived(b"test mcdonalds farm\n")
713629
self.test = self.client._events[-1][-1]
714630

715-
def simple_uxsuccess_keyword(self, keyword, as_fail):
631+
def simple_uxsuccess_keyword(self, keyword):
716632
self.protocol.lineReceived(("%s mcdonalds farm\n" % keyword).encode())
717-
self.check_fail_or_uxsuccess(as_fail)
633+
self.check_uxsuccess()
718634

719-
def check_fail_or_uxsuccess(self, as_fail, error_message=None):
720-
details = {}
635+
def check_uxsuccess(self, error_message=None):
721636
if error_message is not None:
637+
details = {}
722638
details["traceback"] = Content(
723639
ContentType("text", "x-traceback", {"charset": "utf8"}), lambda: [error_message.encode()]
724640
)
725-
if isinstance(self.client, ExtendedTestResult):
726-
value = details
727-
else:
728-
value = None
729-
if as_fail:
730-
self.client._events[1] = self.client._events[1][:2]
731-
# The value is generated within the extended to original decorator:
732-
# todo use the testtools matcher to check on this.
733-
self.assertEqual(
734-
[
735-
("startTest", self.test),
736-
("addFailure", self.test),
737-
("stopTest", self.test),
738-
],
739-
self.client._events,
740-
)
741-
elif value:
742-
self.assertEqual(
743-
[
744-
("startTest", self.test),
745-
("addUnexpectedSuccess", self.test, value),
746-
("stopTest", self.test),
747-
],
748-
self.client._events,
749-
)
641+
expected_events = [
642+
("startTest", self.test),
643+
("addUnexpectedSuccess", self.test, details),
644+
("stopTest", self.test),
645+
]
750646
else:
751-
self.assertEqual(
752-
[
753-
("startTest", self.test),
754-
("addUnexpectedSuccess", self.test),
755-
("stopTest", self.test),
756-
],
757-
self.client._events,
758-
)
647+
expected_events = [
648+
("startTest", self.test),
649+
("addUnexpectedSuccess", self.test),
650+
("stopTest", self.test),
651+
]
652+
self.assertEqual(expected_events, self.client._events)
759653

760654
def test_simple_uxsuccess(self):
761-
self.setup_python26()
762-
self.simple_uxsuccess_keyword("uxsuccess", True)
763-
self.setup_python27()
764-
self.simple_uxsuccess_keyword("uxsuccess", False)
765-
self.setup_python_ex()
766-
self.simple_uxsuccess_keyword("uxsuccess", False)
655+
self.simple_uxsuccess_keyword("uxsuccess")
767656

768657
def test_simple_uxsuccess_colon(self):
769-
self.setup_python26()
770-
self.simple_uxsuccess_keyword("uxsuccess:", True)
771-
self.setup_python27()
772-
self.simple_uxsuccess_keyword("uxsuccess:", False)
773-
self.setup_python_ex()
774-
self.simple_uxsuccess_keyword("uxsuccess:", False)
658+
self.simple_uxsuccess_keyword("uxsuccess:")
775659

776660
def test_uxsuccess_empty_message(self):
777-
self.setup_python26()
778-
self.empty_message(True)
779-
self.setup_python27()
780-
self.empty_message(False)
781-
self.setup_python_ex()
782-
self.empty_message(False, error_message="")
783-
784-
def empty_message(self, as_fail, error_message="\n"):
785661
self.protocol.lineReceived(b"uxsuccess mcdonalds farm [\n")
786662
self.protocol.lineReceived(b"]\n")
787-
self.check_fail_or_uxsuccess(as_fail, error_message)
663+
self.check_uxsuccess(error_message="")
788664

789-
def uxsuccess_quoted_bracket(self, keyword, as_fail):
790-
self.protocol.lineReceived(("%s mcdonalds farm [\n" % keyword).encode())
665+
def test_uxsuccess_quoted_bracket(self):
666+
self.protocol.lineReceived(b"uxsuccess mcdonalds farm [\n")
791667
self.protocol.lineReceived(b" ]\n")
792668
self.protocol.lineReceived(b"]\n")
793-
self.check_fail_or_uxsuccess(as_fail, "]\n")
794-
795-
def test_uxsuccess_quoted_bracket(self):
796-
self.setup_python26()
797-
self.uxsuccess_quoted_bracket("uxsuccess", True)
798-
self.setup_python27()
799-
self.uxsuccess_quoted_bracket("uxsuccess", False)
800-
self.setup_python_ex()
801-
self.uxsuccess_quoted_bracket("uxsuccess", False)
669+
self.check_uxsuccess("]\n")
802670

803671
def test_uxsuccess_colon_quoted_bracket(self):
804-
self.setup_python26()
805-
self.uxsuccess_quoted_bracket("uxsuccess:", True)
806-
self.setup_python27()
807-
self.uxsuccess_quoted_bracket("uxsuccess:", False)
808-
self.setup_python_ex()
809-
self.uxsuccess_quoted_bracket("uxsuccess:", False)
672+
self.protocol.lineReceived(b"uxsuccess: mcdonalds farm [\n")
673+
self.protocol.lineReceived(b" ]\n")
674+
self.protocol.lineReceived(b"]\n")
675+
self.check_uxsuccess("]\n")
810676

811677

812678
class TestTestProtocolServerAddSkip(unittest.TestCase):
@@ -928,7 +794,7 @@ class TestTestProtocolServerProgress(unittest.TestCase):
928794
"""Test receipt of progress: directives."""
929795

930796
def test_progress_accepted_stdlib(self):
931-
self.result = Python26TestResult()
797+
self.result = ExtendedTestResult()
932798
self.stream = BytesIO()
933799
self.protocol = subunit.TestProtocolServer(self.result, stream=self.stream)
934800
self.protocol.lineReceived(b"progress: 23")
@@ -1007,7 +873,7 @@ class TestTestProtocolServerStreamTime(unittest.TestCase):
1007873
"""Test managing time information at the protocol level."""
1008874

1009875
def test_time_accepted_stdlib(self):
1010-
self.result = Python26TestResult()
876+
self.result = ExtendedTestResult()
1011877
self.stream = BytesIO()
1012878
self.protocol = subunit.TestProtocolServer(self.result, stream=self.stream)
1013879
self.protocol.lineReceived(b"time: 2001-12-12 12:59:59Z\n")

0 commit comments

Comments
 (0)