Skip to content

Commit 3ed5e34

Browse files
committed
ControlMode(test[xfail]): Add scrollback/timeout placeholders
why: Document remaining control-mode gaps without destabilizing suite. what: - Add xfail scrollback capture-pane regression placeholder with NamedTuple fixture - Add per-command timeout restart xfail documenting need for injectable transport - Note nondeterministic attach_to notification delivery as xfail placeholder
1 parent b975b3f commit 3ed5e34

File tree

2 files changed

+91
-0
lines changed

2 files changed

+91
-0
lines changed

tests/test_control_mode_engine.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -370,3 +370,28 @@ def test_notifications_overflow_then_iter(case: BackpressureFixture) -> None:
370370
if case.expect_iter:
371371
notif = next(engine.iter_notifications(timeout=0.05), None)
372372
assert notif is not None
373+
374+
375+
class TimeoutRestartFixture(t.NamedTuple):
376+
"""Fixture for per-command timeout restart behavior."""
377+
378+
test_id: str
379+
380+
381+
@pytest.mark.xfail(
382+
reason="per-command timeout restart needs injectable control-mode transport",
383+
strict=False,
384+
)
385+
@pytest.mark.parametrize(
386+
"case",
387+
[
388+
TimeoutRestartFixture(test_id="timeout_triggers_restart_then_succeeds"),
389+
],
390+
ids=lambda c: c.test_id,
391+
)
392+
def test_run_result_timeout_triggers_restart(case: TimeoutRestartFixture) -> None:
393+
"""Placeholder: timeout should restart control process and allow next command."""
394+
_ = ControlModeEngine(command_timeout=0.0001)
395+
pytest.xfail(
396+
"control-mode needs injectable process to simulate per-call timeout",
397+
)

tests/test_control_mode_regressions.py

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -589,6 +589,14 @@ class CaptureRangeFixture(t.NamedTuple):
589589
flags: tuple[str, ...] = ()
590590

591591

592+
class CaptureScrollbackFixture(t.NamedTuple):
593+
"""Fixture for capture-pane scrollback handling."""
594+
595+
test_id: str
596+
start: int
597+
expected_tail: str
598+
599+
592600
class InternalNameCollisionFixture(t.NamedTuple):
593601
"""Fixture for internal session name collisions."""
594602

@@ -641,6 +649,52 @@ def test_capture_pane_respects_range(case: CaptureRangeFixture) -> None:
641649
server.kill()
642650

643651

652+
@pytest.mark.engines(["control"])
653+
@pytest.mark.parametrize(
654+
"case",
655+
[
656+
pytest.param(
657+
CaptureScrollbackFixture(
658+
test_id="capture_scrollback_trims_prompt_only",
659+
start=-50,
660+
expected_tail="line3",
661+
),
662+
marks=pytest.mark.xfail(
663+
reason=(
664+
"control-mode capture scrollback races shell output; TODO stabilize"
665+
),
666+
strict=False,
667+
),
668+
),
669+
],
670+
ids=lambda c: c.test_id,
671+
)
672+
def test_capture_pane_scrollback(case: CaptureScrollbackFixture) -> None:
673+
"""capture-pane with small scrollback should include recent lines."""
674+
socket_name = f"libtmux_test_{uuid.uuid4().hex[:8]}"
675+
engine = ControlModeEngine()
676+
server = Server(socket_name=socket_name, engine=engine)
677+
try:
678+
session = server.new_session(
679+
session_name="capture_scrollback",
680+
attach=False,
681+
kill_session=True,
682+
)
683+
pane = session.active_pane
684+
assert pane is not None
685+
pane.send_keys(
686+
'printf "line1\\nline2\\nline3\\n"',
687+
literal=True,
688+
suppress_history=False,
689+
)
690+
lines = pane.capture_pane(start=case.start)
691+
assert lines
692+
assert lines[-1].strip() == case.expected_tail
693+
finally:
694+
with contextlib.suppress(Exception):
695+
server.kill()
696+
697+
644698
@pytest.mark.engines(["control"])
645699
@pytest.mark.xfail(
646700
reason="control-mode capture -N can race shell; TODO fix upstream",
@@ -793,3 +847,15 @@ def test_list_clients_control_flag_filters_attached() -> None:
793847
finally:
794848
with contextlib.suppress(Exception):
795849
server.kill()
850+
851+
852+
@pytest.mark.engines(["control"])
853+
@pytest.mark.xfail(
854+
reason=(
855+
"attach_to notifications are not yet deterministic; need explicit sync point"
856+
),
857+
strict=False,
858+
)
859+
def test_attach_to_emits_notification_deterministically() -> None:
860+
"""Placeholder documenting desired deterministic attach_to notification."""
861+
pytest.xfail("pending deterministic notification capture for attach_to")

0 commit comments

Comments
 (0)