Skip to content

Commit

Permalink
Make AppSession compatible with pytest's capsys fixture + docs.
Browse files Browse the repository at this point in the history
  • Loading branch information
jonathanslenders committed Jun 4, 2024
1 parent 6a58564 commit 2530c04
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 3 deletions.
15 changes: 15 additions & 0 deletions docs/pages/advanced_topics/unit_testing.rst
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,21 @@ single fixture that does it for every test. Something like this:
with create_app_session(input=pipe_input, output=DummyOutput()):
yield pipe_input
For compatibility with pytest's ``capsys`` fixture, we have to create a new
:class:`~prompt_toolkit.application.current.AppSession` for every test. This
can be done in an autouse fixture. Pytest replaces ``sys.stdout`` with a new
object in every test that uses ``capsys`` and the following will ensure that
the new :class:`~prompt_toolkit.application.current.AppSession` will each time
refer to the latest output.

.. code:: python
from prompt_toolkit.application import create_app_session
@fixture(autouse=True, scope="function")
def _pt_app_session()
with create_app_session():
yield
Type checking
-------------
Expand Down
12 changes: 9 additions & 3 deletions src/prompt_toolkit/application/current.py
Original file line number Diff line number Diff line change
Expand Up @@ -147,11 +147,17 @@ def create_app_session(
Like in the case of an Telnet/SSH server.
"""
# If no input/output is specified, fall back to the current input/output,
# whatever that is.
# if there was one that was set/created for the current session.
# (Note that we check `_input`/`_output` and not `input`/`output`. This is
# because we don't want to accidently create a new input/output objects
# here and store it in the "parent" `AppSession`. Especially, when
# combining pytest's `capsys` fixture and `create_app_session`, sys.stdin
# and sys.stderr are patched for every test, so we don't want to leak
# those outputs object across `AppSession`s.)
if input is None:
input = get_app_session().input
input = get_app_session()._input
if output is None:
output = get_app_session().output
output = get_app_session()._output

# Create new `AppSession` and activate.
session = AppSession(input=input, output=output)
Expand Down

0 comments on commit 2530c04

Please sign in to comment.