Import AITURK IDE 1.0.0-beta.1 from Hermes 63279301; preserve MIT license
This commit is contained in:
@@ -0,0 +1,231 @@
|
||||
"""Tests for `--resume latest` and `--in DIR` launch sugar.
|
||||
|
||||
`hermes --tui --resume latest --in ./dir` (and the classic-CLI equivalents)
|
||||
resolve "latest" through the same workspace-scoped MRU lookup as `-c`, with
|
||||
`--in` re-homing the process before any session resolution happens.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from argparse import Namespace
|
||||
|
||||
import pytest
|
||||
|
||||
|
||||
def _args(**overrides):
|
||||
base = {
|
||||
"cli": False,
|
||||
"continue_last": None,
|
||||
"in_dir": None,
|
||||
"model": None,
|
||||
"no_restore_cwd": False,
|
||||
"provider": None,
|
||||
"query": None,
|
||||
"resume": None,
|
||||
"safe_mode": False,
|
||||
"toolsets": None,
|
||||
"tui": True,
|
||||
"tui_dev": False,
|
||||
"worktree": False,
|
||||
}
|
||||
base.update(overrides)
|
||||
return Namespace(**base)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def main_mod(monkeypatch):
|
||||
import hermes_cli.main as mod
|
||||
|
||||
monkeypatch.setattr(mod, "_has_any_provider_configured", lambda: True)
|
||||
monkeypatch.setattr(mod, "_sync_bundled_skills_for_startup", lambda: False)
|
||||
monkeypatch.setattr(mod, "_pin_kanban_board_env", lambda: None)
|
||||
return mod
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def launched(main_mod, monkeypatch):
|
||||
"""Capture the _launch_tui call instead of exec'ing Node."""
|
||||
captured = {}
|
||||
|
||||
def fake_launch(resume_session_id=None, **kwargs):
|
||||
captured["resume"] = resume_session_id
|
||||
captured.update(kwargs)
|
||||
raise SystemExit(0)
|
||||
|
||||
monkeypatch.setattr(main_mod, "_launch_tui", fake_launch)
|
||||
return captured
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# argparse surface
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
def test_top_level_parser_accepts_in_and_resume_latest():
|
||||
from hermes_cli._parser import build_top_level_parser
|
||||
|
||||
parser, _subparsers, _chat = build_top_level_parser()
|
||||
args = parser.parse_args(["--tui", "--resume", "latest", "--in", "./dir"])
|
||||
assert args.tui is True
|
||||
assert args.resume == "latest"
|
||||
assert args.in_dir == "./dir"
|
||||
|
||||
|
||||
def test_chat_subparser_accepts_in_flag():
|
||||
from hermes_cli._parser import build_top_level_parser
|
||||
|
||||
parser, _subparsers, _chat = build_top_level_parser()
|
||||
args = parser.parse_args(["chat", "--in", "/tmp", "--resume", "latest"])
|
||||
assert args.in_dir == "/tmp"
|
||||
assert args.resume == "latest"
|
||||
|
||||
|
||||
def test_top_level_in_value_not_mistaken_for_subcommand(monkeypatch):
|
||||
# `hermes --in chat` — "chat" is the flag's value, not the subcommand.
|
||||
import sys
|
||||
|
||||
import hermes_cli.main as mod
|
||||
|
||||
monkeypatch.setattr(sys, "argv", ["hermes", "--in", "chat", "--resume", "latest"])
|
||||
assert mod._first_positional_argv() is None
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# --resume latest resolution
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
def test_resume_latest_resolves_to_mru_session(main_mod, launched, monkeypatch):
|
||||
monkeypatch.setattr(
|
||||
main_mod, "_resolve_last_session", lambda source="cli": "20260807_120000_abc123"
|
||||
)
|
||||
# Keyword must NOT fall through to title resolution.
|
||||
monkeypatch.setattr(
|
||||
main_mod,
|
||||
"_resolve_session_by_name_or_id",
|
||||
lambda val: val if val != "latest" else pytest.fail("'latest' hit title resolution"),
|
||||
)
|
||||
|
||||
with pytest.raises(SystemExit) as exc:
|
||||
main_mod.cmd_chat(_args(resume="latest"))
|
||||
assert exc.value.code == 0
|
||||
assert launched["resume"] == "20260807_120000_abc123"
|
||||
|
||||
|
||||
def test_resume_latest_tui_falls_back_to_cli_source(main_mod, launched, monkeypatch):
|
||||
calls = []
|
||||
|
||||
def fake_resolve(source="cli"):
|
||||
calls.append(source)
|
||||
return "cli_session_1" if source == "cli" else None
|
||||
|
||||
monkeypatch.setattr(main_mod, "_resolve_last_session", fake_resolve)
|
||||
monkeypatch.setattr(main_mod, "_resolve_session_by_name_or_id", lambda v: v)
|
||||
|
||||
with pytest.raises(SystemExit) as exc:
|
||||
main_mod.cmd_chat(_args(resume="latest"))
|
||||
assert exc.value.code == 0
|
||||
assert calls == ["tui", "cli"]
|
||||
assert launched["resume"] == "cli_session_1"
|
||||
|
||||
|
||||
def test_resume_latest_is_case_insensitive(main_mod, launched, monkeypatch):
|
||||
monkeypatch.setattr(main_mod, "_resolve_last_session", lambda source="cli": "sess_1")
|
||||
monkeypatch.setattr(main_mod, "_resolve_session_by_name_or_id", lambda v: v)
|
||||
|
||||
with pytest.raises(SystemExit):
|
||||
main_mod.cmd_chat(_args(resume="Latest"))
|
||||
assert launched["resume"] == "sess_1"
|
||||
|
||||
|
||||
def test_resume_latest_no_sessions_exits_with_error(main_mod, monkeypatch, capsys):
|
||||
monkeypatch.setattr(main_mod, "_resolve_last_session", lambda source="cli": None)
|
||||
|
||||
with pytest.raises(SystemExit) as exc:
|
||||
main_mod.cmd_chat(_args(resume="latest"))
|
||||
assert exc.value.code == 1
|
||||
out = capsys.readouterr().out
|
||||
assert "No previous TUI session found" in out
|
||||
|
||||
|
||||
def test_resume_real_id_untouched_by_latest_keyword(main_mod, launched, monkeypatch):
|
||||
monkeypatch.setattr(
|
||||
main_mod,
|
||||
"_resolve_last_session",
|
||||
lambda source="cli": pytest.fail("MRU lookup must not run for explicit IDs"),
|
||||
)
|
||||
monkeypatch.setattr(main_mod, "_resolve_session_by_name_or_id", lambda v: v)
|
||||
|
||||
with pytest.raises(SystemExit):
|
||||
main_mod.cmd_chat(_args(resume="20260807_120000_abc123"))
|
||||
assert launched["resume"] == "20260807_120000_abc123"
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# --in DIR
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
def test_in_dir_chdirs_before_session_resolution(main_mod, launched, monkeypatch, tmp_path):
|
||||
import os
|
||||
|
||||
target = tmp_path / "projdir"
|
||||
target.mkdir()
|
||||
start = os.getcwd()
|
||||
seen_cwd = {}
|
||||
|
||||
def fake_resolve(source="cli"):
|
||||
seen_cwd["at_resolve"] = os.getcwd()
|
||||
return "sess_scoped"
|
||||
|
||||
monkeypatch.setattr(main_mod, "_resolve_last_session", fake_resolve)
|
||||
monkeypatch.setattr(main_mod, "_resolve_session_by_name_or_id", lambda v: v)
|
||||
|
||||
try:
|
||||
with pytest.raises(SystemExit):
|
||||
main_mod.cmd_chat(_args(resume="latest", in_dir=str(target)))
|
||||
finally:
|
||||
os.chdir(start)
|
||||
|
||||
assert seen_cwd["at_resolve"] == str(target.resolve())
|
||||
assert launched["resume"] == "sess_scoped"
|
||||
|
||||
|
||||
def test_in_dir_sets_no_restore_cwd(main_mod, launched, monkeypatch, tmp_path):
|
||||
import os
|
||||
|
||||
target = tmp_path / "pin-here"
|
||||
target.mkdir()
|
||||
start = os.getcwd()
|
||||
|
||||
args = _args(resume=None, in_dir=str(target))
|
||||
try:
|
||||
with pytest.raises(SystemExit):
|
||||
main_mod.cmd_chat(args)
|
||||
finally:
|
||||
os.chdir(start)
|
||||
|
||||
assert args.no_restore_cwd is True
|
||||
|
||||
|
||||
def test_in_dir_missing_directory_exits(main_mod, monkeypatch, tmp_path, capsys):
|
||||
with pytest.raises(SystemExit) as exc:
|
||||
main_mod.cmd_chat(_args(in_dir=str(tmp_path / "nope")))
|
||||
assert exc.value.code == 1
|
||||
assert "--in directory not found" in capsys.readouterr().out
|
||||
|
||||
|
||||
def test_in_dir_expands_user_home(main_mod, launched, monkeypatch, tmp_path):
|
||||
import os
|
||||
|
||||
home = tmp_path / "home"
|
||||
(home / "proj").mkdir(parents=True)
|
||||
monkeypatch.setenv("HOME", str(home))
|
||||
start = os.getcwd()
|
||||
|
||||
try:
|
||||
with pytest.raises(SystemExit):
|
||||
main_mod.cmd_chat(_args(in_dir="~/proj"))
|
||||
assert os.getcwd() == str((home / "proj").resolve())
|
||||
finally:
|
||||
os.chdir(start)
|
||||
Reference in New Issue
Block a user