Skip to content

Commit ca5095b

Browse files
committed
Attempt to fix pypy issue
1 parent d79a9dd commit ca5095b

File tree

2 files changed

+138
-113
lines changed

2 files changed

+138
-113
lines changed

testtools/tests/matchers/test_higherorder.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ class TestAnyMatch(TestCase, TestMatchersInterface):
8181
]
8282

8383

84+
# Module-level function to avoid PyPy compilation issues with staticmethod
8485
def parity(x):
8586
return x % 2
8687

testtools/tests/twistedsupport/test_runtest.py

Lines changed: 137 additions & 113 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
import signal
77
from typing import Any, ClassVar
88

9+
from testscenarios import multiply_scenarios
10+
911
from testtools import (
1012
TestCase,
1113
TestResult,
@@ -83,140 +85,161 @@
8385
_get_global_publisher_and_observers = None # type: ignore[assignment]
8486

8587

86-
class X:
87-
"""Tests that we run as part of our tests, nested to avoid discovery."""
88+
# Flattened test classes to avoid PyPy compilation crash with nested classes
89+
# Prefixed with _ to avoid pytest discovery
90+
91+
92+
class _XBase(TestCase):
93+
def setUp(self):
94+
super().setUp()
95+
self.calls = ["setUp"]
96+
self.addCleanup(self.calls.append, "clean-up")
97+
98+
def test_something(self):
99+
self.calls.append("test")
100+
101+
def tearDown(self):
102+
self.calls.append("tearDown")
103+
super().tearDown()
104+
88105

89-
# XXX: After testing-cabal/testtools#165 lands, fix up all of these to be
90-
# scenario tests for RunTest.
106+
class _XBaseExceptionRaised(_XBase):
107+
expected_calls: ClassVar[list] = ["setUp", "tearDown", "clean-up"]
108+
expected_results: ClassVar[list] = [("addError", SystemExit)]
91109

92-
class Base(TestCase):
93-
def setUp(self):
94-
super(X.Base, self).setUp()
95-
self.calls = ["setUp"]
96-
self.addCleanup(self.calls.append, "clean-up")
110+
def test_something(self):
111+
raise SystemExit(0)
97112

98-
def test_something(self):
99-
self.calls.append("test")
100113

101-
def tearDown(self):
102-
self.calls.append("tearDown")
103-
super(X.Base, self).tearDown()
114+
class _XErrorInSetup(_XBase):
115+
expected_calls: ClassVar[list] = ["setUp", "clean-up"]
116+
expected_results: ClassVar[list] = [("addError", RuntimeError)]
104117

105-
class BaseExceptionRaised(Base):
106-
expected_calls: ClassVar[list] = ["setUp", "tearDown", "clean-up"]
107-
expected_results: ClassVar[list] = [("addError", SystemExit)]
118+
def setUp(self):
119+
super().setUp()
120+
raise RuntimeError("Error in setUp")
108121

109-
def test_something(self):
110-
raise SystemExit(0)
111122

112-
class ErrorInSetup(Base):
113-
expected_calls: ClassVar[list] = ["setUp", "clean-up"]
114-
expected_results: ClassVar[list] = [("addError", RuntimeError)]
123+
class _XErrorInTest(_XBase):
124+
expected_calls: ClassVar[list] = ["setUp", "tearDown", "clean-up"]
125+
expected_results: ClassVar[list] = [("addError", RuntimeError)]
115126

116-
def setUp(self):
117-
super(X.ErrorInSetup, self).setUp()
118-
raise RuntimeError("Error in setUp")
127+
def test_something(self):
128+
raise RuntimeError("Error in test")
119129

120-
class ErrorInTest(Base):
121-
expected_calls: ClassVar[list] = ["setUp", "tearDown", "clean-up"]
122-
expected_results: ClassVar[list] = [("addError", RuntimeError)]
123130

124-
def test_something(self):
125-
raise RuntimeError("Error in test")
131+
class _XFailureInTest(_XBase):
132+
expected_calls: ClassVar[list] = ["setUp", "tearDown", "clean-up"]
133+
expected_results: ClassVar[list] = [("addFailure", AssertionError)]
126134

127-
class FailureInTest(Base):
128-
expected_calls: ClassVar[list] = ["setUp", "tearDown", "clean-up"]
129-
expected_results: ClassVar[list] = [("addFailure", AssertionError)]
135+
def test_something(self):
136+
self.fail("test failed")
130137

131-
def test_something(self):
132-
self.fail("test failed")
133138

134-
class ErrorInTearDown(Base):
135-
expected_calls: ClassVar[list] = ["setUp", "test", "clean-up"]
136-
expected_results: ClassVar[list] = [("addError", RuntimeError)]
139+
class _XErrorInTearDown(_XBase):
140+
expected_calls: ClassVar[list] = ["setUp", "test", "clean-up"]
141+
expected_results: ClassVar[list] = [("addError", RuntimeError)]
137142

138-
def tearDown(self):
139-
raise RuntimeError("Error in tearDown")
143+
def tearDown(self):
144+
raise RuntimeError("Error in tearDown")
140145

141-
class ErrorInCleanup(Base):
142-
expected_calls: ClassVar[list] = ["setUp", "test", "tearDown", "clean-up"]
143-
expected_results: ClassVar[list] = [("addError", ZeroDivisionError)]
144146

145-
def test_something(self):
146-
self.calls.append("test")
147-
self.addCleanup(lambda: 1 / 0)
147+
class _XErrorInCleanup(_XBase):
148+
expected_calls: ClassVar[list] = ["setUp", "test", "tearDown", "clean-up"]
149+
expected_results: ClassVar[list] = [("addError", ZeroDivisionError)]
148150

149-
class ExpectThatFailure(Base):
150-
"""Calling expectThat with a failing match fails the test."""
151+
def test_something(self):
152+
self.calls.append("test")
153+
self.addCleanup(lambda: 1 / 0)
151154

152-
expected_calls: ClassVar[list] = ["setUp", "test", "tearDown", "clean-up"]
153-
expected_results: ClassVar[list] = [("addFailure", AssertionError)]
154155

155-
def test_something(self):
156-
self.calls.append("test")
157-
self.expectThat(object(), Is(object()))
156+
class _XExpectThatFailure(_XBase):
157+
"""Calling expectThat with a failing match fails the test."""
158158

159-
class TestIntegration(NeedsTwistedTestCase):
160-
# These attributes are set dynamically in test generation
161-
test_factory: Any = None
162-
runner: Any = None
159+
expected_calls: ClassVar[list] = ["setUp", "test", "tearDown", "clean-up"]
160+
expected_results: ClassVar[list] = [("addFailure", AssertionError)]
163161

164-
def assertResultsMatch(self, test, result):
165-
events = list(result._events)
166-
self.assertEqual(("startTest", test), events.pop(0))
167-
for expected_result in test.expected_results:
168-
result = events.pop(0)
169-
if len(expected_result) == 1:
170-
self.assertEqual((expected_result[0], test), result)
171-
else:
172-
self.assertEqual((expected_result[0], test), result[:2])
173-
error_type = expected_result[1]
174-
self.assertIn(error_type.__name__, str(result[2]))
175-
self.assertEqual([("stopTest", test)], events)
162+
def test_something(self):
163+
self.calls.append("test")
164+
self.expectThat(object(), Is(object()))
176165

177-
def test_runner(self):
178-
result = ExtendedTestResult()
179-
test = self.test_factory("test_something", runTest=self.runner)
180-
if self.test_factory is X.BaseExceptionRaised:
181-
self.assertRaises(SystemExit, test.run, result)
166+
167+
class _XTestIntegration(NeedsTwistedTestCase):
168+
# These attributes are set dynamically in test generation
169+
test_factory: Any = None
170+
runner: Any = None
171+
172+
def assertResultsMatch(self, test, result):
173+
events = list(result._events)
174+
self.assertEqual(("startTest", test), events.pop(0))
175+
for expected_result in test.expected_results:
176+
result = events.pop(0)
177+
if len(expected_result) == 1:
178+
self.assertEqual((expected_result[0], test), result)
182179
else:
183-
test.run(result)
184-
self.assertEqual(test.calls, self.test_factory.expected_calls)
185-
self.assertResultsMatch(test, result)
186-
187-
188-
def make_integration_tests():
189-
from unittest import TestSuite
190-
191-
from testtools import clone_test_with_new_id
192-
193-
runners = [
194-
("RunTest", RunTest),
195-
("SynchronousDeferredRunTest", SynchronousDeferredRunTest),
196-
("AsynchronousDeferredRunTest", AsynchronousDeferredRunTest),
197-
]
198-
199-
tests = [
200-
X.BaseExceptionRaised,
201-
X.ErrorInSetup,
202-
X.ErrorInTest,
203-
X.ErrorInTearDown,
204-
X.FailureInTest,
205-
X.ErrorInCleanup,
206-
X.ExpectThatFailure,
207-
]
208-
base_test = X.TestIntegration("test_runner")
209-
integration_tests = []
210-
for runner_name, runner in runners:
211-
for test in tests:
212-
new_test = clone_test_with_new_id(
213-
base_test,
214-
f"{base_test.id()}({runner_name}, {test.__name__})",
215-
)
216-
new_test.test_factory = test
217-
new_test.runner = runner
218-
integration_tests.append(new_test)
219-
return TestSuite(integration_tests)
180+
self.assertEqual((expected_result[0], test), result[:2])
181+
error_type = expected_result[1]
182+
self.assertIn(error_type.__name__, str(result[2]))
183+
self.assertEqual([("stopTest", test)], events)
184+
185+
def test_runner(self):
186+
result = ExtendedTestResult()
187+
test = self.test_factory("test_something", runTest=self.runner)
188+
if self.test_factory is _XBaseExceptionRaised:
189+
self.assertRaises(SystemExit, test.run, result)
190+
else:
191+
test.run(result)
192+
self.assertEqual(test.calls, self.test_factory.expected_calls)
193+
self.assertResultsMatch(test, result)
194+
195+
196+
class TestRunTestIntegration(NeedsTwistedTestCase):
197+
"""Integration tests for different runner and test case combinations."""
198+
199+
# These attributes are provided by testscenarios
200+
runner: Any
201+
test_factory: Any
202+
203+
scenarios = multiply_scenarios(
204+
[ # Runner scenarios
205+
("RunTest", {"runner": RunTest}),
206+
("SynchronousDeferredRunTest", {"runner": SynchronousDeferredRunTest}),
207+
("AsynchronousDeferredRunTest", {"runner": AsynchronousDeferredRunTest}),
208+
],
209+
[ # Test case scenarios
210+
("BaseExceptionRaised", {"test_factory": _XBaseExceptionRaised}),
211+
("ErrorInSetup", {"test_factory": _XErrorInSetup}),
212+
("ErrorInTest", {"test_factory": _XErrorInTest}),
213+
("ErrorInTearDown", {"test_factory": _XErrorInTearDown}),
214+
("FailureInTest", {"test_factory": _XFailureInTest}),
215+
("ErrorInCleanup", {"test_factory": _XErrorInCleanup}),
216+
("ExpectThatFailure", {"test_factory": _XExpectThatFailure}),
217+
],
218+
)
219+
220+
def assertResultsMatch(self, test, result):
221+
events = list(result._events)
222+
self.assertEqual(("startTest", test), events.pop(0))
223+
for expected_result in test.expected_results:
224+
result = events.pop(0)
225+
if len(expected_result) == 1:
226+
self.assertEqual((expected_result[0], test), result)
227+
else:
228+
self.assertEqual((expected_result[0], test), result[:2])
229+
error_type = expected_result[1]
230+
self.assertIn(error_type.__name__, str(result[2]))
231+
self.assertEqual([("stopTest", test)], events)
232+
233+
def test_runner(self):
234+
"""Test that each runner handles each test case scenario correctly."""
235+
result = ExtendedTestResult()
236+
test = self.test_factory("test_something", runTest=self.runner)
237+
if self.test_factory is _XBaseExceptionRaised:
238+
self.assertRaises(SystemExit, test.run, result)
239+
else:
240+
test.run(result)
241+
self.assertEqual(test.calls, self.test_factory.expected_calls)
242+
self.assertResultsMatch(test, result)
220243

221244

222245
class TestSynchronousDeferredRunTest(NeedsTwistedTestCase):
@@ -1142,5 +1165,6 @@ def test_suite():
11421165

11431166

11441167
def load_tests(loader, tests, pattern):
1145-
tests.addTest(make_integration_tests())
1146-
return tests
1168+
from testscenarios import load_tests_apply_scenarios
1169+
1170+
return load_tests_apply_scenarios(loader, tests, pattern)

0 commit comments

Comments
 (0)