Skip to content

Commit ac5e7d1

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 ac5e7d1

File tree

1 file changed

+22
-6
lines changed

1 file changed

+22
-6
lines changed

tests/conftest.py

Lines changed: 22 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,13 @@ 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(f"Running {cmd} {{{cwd=}, {input=}, {check=}, {capture_output=}}}")
120+
return subprocess.run(
121+
cmd, cwd=cwd, input=input, check=check, capture_output=capture_output
122+
)
120123

121124

122125
@contextmanager
@@ -125,9 +128,11 @@ def editor_main(
125128
cwd: Optional["StrPath"] = None,
126129
# pylint: disable=redefined-builtin
127130
input: Optional[bytes] = None,
131+
stdout_stderr_out: Optional[List[bytes]] = None,
128132
) -> "Generator[Editor, None, subprocess.CompletedProcess[bytes]]":
129133
with pytest.MonkeyPatch().context() as monkeypatch, Editor() as ed, ThreadPoolExecutor() as tpe:
130134
host, port = ed.server_address
135+
assert isinstance(host, str) # Satisfy mypy
131136
editor_cmd = " ".join(
132137
shlex.quote(p)
133138
for p in (
@@ -138,8 +143,12 @@ def editor_main(
138143
)
139144
monkeypatch.setenv("GIT_EDITOR", editor_cmd)
140145

146+
capture_output = stdout_stderr_out is not None
147+
141148
# Run the command asynchronously.
142-
future = tpe.submit(main, args, cwd=cwd, input=input)
149+
future = tpe.submit(
150+
main, args, cwd=cwd, input=input, capture_output=capture_output
151+
)
143152

144153
# If it fails, cancel anything waiting on `ed.next_file()`.
145154
def cancel_on_error(future: "Future[Any]") -> None:
@@ -152,7 +161,12 @@ def cancel_on_error(future: "Future[Any]") -> None:
152161
# Yield the editor, so that tests can process incoming requests via `ed.next_file()`.
153162
yield ed
154163

155-
return future.result()
164+
result = future.result()
165+
if stdout_stderr_out is not None:
166+
# Mutate instead of reassigning the out-argument object
167+
# to make the change observable to the caller.
168+
stdout_stderr_out += [result.stdout, result.stderr]
169+
return result
156170

157171

158172
class EditorFile:
@@ -189,7 +203,9 @@ class EditorFileRequestHandler(BaseHTTPRequestHandler):
189203

190204
# pylint: disable=invalid-name
191205
def do_POST(self) -> None:
192-
length = int(self.headers.get("content-length"))
206+
content_length = self.headers.get("content-length")
207+
assert isinstance(content_length, str) # Satisfy mypy
208+
length = int(content_length)
193209
in_data = self.rfile.read(length)
194210

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

0 commit comments

Comments
 (0)