import json from tamq.cli import build_parser, main, normalize_argv import pytest def test_help_and_version(capsys): with pytest.raises(SystemExit) as exc: main(["--version"]) assert exc.value.code == 0 assert "0.1.0" in capsys.readouterr().out assert main([]) == 0 assert "usage:" in capsys.readouterr().out def test_attach_delegates_to_tmux(monkeypatch): calls = [] monkeypatch.delenv("TMUX", raising=False) monkeypatch.setattr("tamq.cli.subprocess.run", lambda args, check=False: calls.append((args, check)) or type("R", (), {"returncode": 0})()) assert main(["attach", "--session", "demo"]) == 0 assert calls == [(["tmux", "attach-session", "-t", "demo"], False)] def test_attach_switches_client_when_already_in_tmux(monkeypatch): calls = [] monkeypatch.setenv("TMUX", "/tmp/tmux,1,0") monkeypatch.setattr("tamq.cli.subprocess.run", lambda args, check=False: calls.append(args) or type("R", (), {"returncode": 0})()) assert main(["attach"]) == 0 assert calls == [["tmux", "switch-client", "-t", "tamq"]] def test_start_parser_supports_command_and_cmd_alias(): parser = build_parser() canonical = parser.parse_args(["start", "--command", "codex --quiet", "a", "b"]) compatibility = parser.parse_args(["start", "--cmd", "claude", "a"]) neutral = parser.parse_args(["start", "a", "b"]) assert canonical.initial_command == "codex --quiet" assert canonical.repos == ["a", "b"] assert compatibility.initial_command == "claude" assert neutral.initial_command is None def test_repository_first_and_command_first_start_shorthand(): assert normalize_argv(["flex-auth", "audit-core"]) == [ "start", "flex-auth", "audit-core", ] assert normalize_argv(["--command", "codex", "flex-auth"]) == [ "start", "--command", "codex", "flex-auth", ] assert normalize_argv(["status"]) == ["status"] assert normalize_argv(["--verbose", "flex-auth", "audit-core"]) == [ "--verbose", "start", "flex-auth", "audit-core", ] def test_detached_no_service_start_skips_socket_registration(monkeypatch, capsys): endpoint = type( "Endpoint", (), { "endpoint_id": "tmux-amq-42", "instance_key": "tmux-amq-42-boot", "pid": 42, "session": "tamq", "repos": ["a", "b"], }, )() class Manager: def preflight(self, repos, command): assert repos == ["a", "b"] assert command is None return "plan" def ensure_plan(self, plan, *, tap=True): assert plan == "plan" assert tap is False return endpoint monkeypatch.setattr("tamq.cli.TmuxManager", Manager) monkeypatch.setattr("tamq.cli.preflight_runtime_paths", lambda: None) monkeypatch.setattr("tamq.cli.request", lambda payload: pytest.fail("socket request must not run")) monkeypatch.setattr("tamq.cli.attach_session", lambda session: pytest.fail("detached start must not attach")) assert main(["start", "--detach", "--no-service", "a", "b"]) == 0 summary = json.loads(capsys.readouterr().out) assert summary["service"] is False assert summary["messaging"] is False assert summary["repos"] == ["a", "b"] def test_interactive_no_service_start_attaches(monkeypatch, capsys): endpoint = type( "Endpoint", (), { "endpoint_id": "tmux-amq-42", "instance_key": "tmux-amq-42-boot", "session": "tamq", "repos": ["a"], }, )() class Manager: def preflight(self, repos, command): return "plan" def ensure_plan(self, plan, *, tap=True): assert tap is False return endpoint attached = [] monkeypatch.setattr("tamq.cli.TmuxManager", Manager) monkeypatch.setattr("tamq.cli.preflight_runtime_paths", lambda: None) monkeypatch.setattr("tamq.cli.attach_session", lambda session: attached.append(session) or 0) assert main(["start", "--no-service", "a"]) == 0 assert attached == ["tamq"] assert json.loads(capsys.readouterr().out)["repos"] == ["a"] def test_registration_failure_rolls_back_created_windows(monkeypatch, capsys): endpoint = type( "Endpoint", (), { "endpoint_id": "tmux-amq-42", "instance_key": "tmux-amq-42-boot", "pid": 42, "session": "tamq", "repos": ["a"], }, )() rolled_back = [] class Manager: def preflight(self, repos, command): return "plan" def ensure_plan(self, plan, *, tap=True): assert tap is False return endpoint def rollback(self, value): rolled_back.append(value) async def failed_registration(payload): return {"ok": False, "error": "denied"} monkeypatch.setattr("tamq.cli.TmuxManager", Manager) monkeypatch.setattr("tamq.cli.preflight_runtime_paths", lambda: None) monkeypatch.setattr("tamq.cli.ensure_manual_service", lambda: True) monkeypatch.setattr("tamq.cli.request", failed_registration) assert main(["start", "--detach", "a"]) == 1 assert rolled_back == [endpoint] assert "endpoint registration failed: denied" in capsys.readouterr().err def test_tap_requires_explicit_command_and_service(capsys): assert main(["start", "--tap", "a"]) == 2 assert "--tap requires an explicit --command" in capsys.readouterr().err assert main(["start", "--tap", "--no-service", "--command", "sh", "a"]) == 2 assert "--tap cannot be combined with --no-service" in capsys.readouterr().err