"""Shared test fixtures.""" from __future__ import annotations import subprocess from typing import Any from flow.core.runtime import CommandRunner class FakeRunner(CommandRunner): """CommandRunner that captures calls instead of executing. Response matching uses ordered subsequence semantics: a response keyed by ``("ps", "{{.Names}}")`` matches any command whose argv contains those tokens in that order (other tokens may appear before, between, or after). This is stricter than set containment -- ``("a", "b")`` does NOT match ``["b", "a"]`` -- and matches argv semantics more accurately. """ def __init__(self, responses: dict[tuple[str, ...], Any] | None = None): self.calls: list[list[str]] = [] self.timeouts: list[float | None] = [] self._responses: dict[tuple[str, ...], Any] = responses or {} @staticmethod def _match(parts: list[str], key: tuple[str, ...]) -> bool: it = iter(parts) return all(k in it for k in key) def run(self, argv, *, cwd=None, env=None, capture_output=True, check=False, timeout=None): parts = list(argv) self.calls.append(parts) self.timeouts.append(timeout) for key, resp in self._responses.items(): if self._match(parts, key): return resp return subprocess.CompletedProcess(parts, 0, stdout="", stderr="") def run_shell(self, command, *, cwd=None, env=None, capture_output=True, check=False, timeout=None): self.calls.append(["__shell__", command]) self.timeouts.append(timeout) return subprocess.CompletedProcess(command, 0, stdout="", stderr="")