Skip to content

Commit 45ec1c6

Browse files
committed
conftest.py: Add ability to test stdout and stderr
Using an out-argument because it is (to my knowledge) not possible to get at the value returned from a contextmanager function.
1 parent 5a10920 commit 45ec1c6

File tree

1 file changed

+26
-6
lines changed

1 file changed

+26
-6
lines changed

tests/conftest.py

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
from queue import Empty, Queue
1414
from threading import Thread
1515
from types import TracebackType
16-
from typing import TYPE_CHECKING, Generator, Optional, Sequence, Type, Union
16+
from typing import TYPE_CHECKING, Generator, List, Optional, Sequence, Type, Union
1717

1818
import pytest
1919

@@ -113,10 +113,17 @@ def main(
113113
# pylint: disable=redefined-builtin
114114
input: Optional[bytes] = None,
115115
check: bool = True,
116+
capture_output: bool = False,
116117
) -> "subprocess.CompletedProcess[bytes]":
117118
cmd = [sys.executable, "-m", "gitrevise", *args]
118-
print("Running", cmd, dict(cwd=cwd, input=input, check=check))
119-
return subprocess.run(cmd, cwd=cwd, input=input, check=check)
119+
print(
120+
"Running",
121+
cmd,
122+
dict(cwd=cwd, input=input, check=check, capture_output=capture_output),
123+
)
124+
return subprocess.run(
125+
cmd, cwd=cwd, input=input, check=check, capture_output=capture_output
126+
)
120127

121128

122129
@contextmanager
@@ -125,9 +132,11 @@ def editor_main(
125132
cwd: Optional["StrPath"] = None,
126133
# pylint: disable=redefined-builtin
127134
input: Optional[bytes] = None,
135+
stdout_stderr_out: Optional[List[bytes]] = None,
128136
) -> "Generator[Editor, None, subprocess.CompletedProcess[bytes]]":
129137
with pytest.MonkeyPatch().context() as monkeypatch, Editor() as ed, ThreadPoolExecutor() as tpe:
130138
host, port = ed.server_address
139+
assert isinstance(host, str) # Satisfy mypy
131140
editor_cmd = " ".join(
132141
shlex.quote(p)
133142
for p in (
@@ -138,8 +147,12 @@ def editor_main(
138147
)
139148
monkeypatch.setenv("GIT_EDITOR", editor_cmd)
140149

150+
capture_output = stdout_stderr_out is not None
151+
141152
# Run the command asynchronously.
142-
future = tpe.submit(main, args, cwd=cwd, input=input)
153+
future = tpe.submit(
154+
main, args, cwd=cwd, input=input, capture_output=capture_output
155+
)
143156

144157
# If it fails, cancel anything waiting on `ed.next_file()`.
145158
def cancel_on_error(future: "Future[Any]") -> None:
@@ -152,7 +165,12 @@ def cancel_on_error(future: "Future[Any]") -> None:
152165
# Yield the editor, so that tests can process incoming requests via `ed.next_file()`.
153166
yield ed
154167

155-
return future.result()
168+
result = future.result()
169+
if stdout_stderr_out is not None:
170+
# Mutate instead of reassigning the out-argument object
171+
# to make the change observable to the caller.
172+
stdout_stderr_out += [result.stdout, result.stderr]
173+
return result
156174

157175

158176
class EditorFile:
@@ -189,7 +207,9 @@ class EditorFileRequestHandler(BaseHTTPRequestHandler):
189207

190208
# pylint: disable=invalid-name
191209
def do_POST(self) -> None:
192-
length = int(self.headers.get("content-length"))
210+
content_length = self.headers.get("content-length")
211+
assert isinstance(content_length, str) # Satisfy mypy
212+
length = int(content_length)
193213
in_data = self.rfile.read(length)
194214

195215
status, out_data = 500, b"no traceback"

0 commit comments

Comments
 (0)