diff --git a/tests/test_issue23_24_startup_path.py b/tests/test_issue23_24_startup_path.py index ce6ecff..f2255e5 100644 --- a/tests/test_issue23_24_startup_path.py +++ b/tests/test_issue23_24_startup_path.py @@ -303,7 +303,7 @@ def test_s11_this_branch_does_not_change_the_generated_shim(mam_sandbox): too (one sanitize definition written in with `declare -f`, agent attach resolved, no silent wrong name), so the base is that commit.""" repo = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) - base = os.environ.get("MAM_BASE_SHA", "5cd72d2") + base = os.environ.get("MAM_BASE_SHA", "0fc162e") show = subprocess.run(["git", "show", "%s:.agents/skills/lib.sh" % base], capture_output=True, text=True, cwd=repo) if show.returncode != 0: diff --git a/tests/test_issue71_herdr_names.py b/tests/test_issue71_herdr_names.py index c4eb511..cf25803 100644 --- a/tests/test_issue71_herdr_names.py +++ b/tests/test_issue71_herdr_names.py @@ -30,6 +30,7 @@ LONG = "lab-issue71-a-very-long-branch-name-creator-claude" # > 32 characters UPPER = "Lab-Upper-creator-claude" PLAIN = "lab-plain-creator-claude" # needs no conversion UNI = "\u0130stanbul-creator-claude" # str.lower() differs from tr here +NL = "newline-creator-claude\n" # $(...) would drop the line break STOP = "bash .agents/skills/multi-agent-mux-stop/scripts/stop_session.sh" @@ -78,7 +79,7 @@ def _assert_new_form(row, server): assert "kill_command" not in row and "start_command" not in row -@pytest.mark.parametrize("name", [LONG, UPPER, PLAIN, UNI]) +@pytest.mark.parametrize("name", [LONG, UPPER, PLAIN, UNI, NL]) @pytest.mark.parametrize("server", ["default", "mam-iso71"]) def test_create_writes_the_attach_command(mam_sandbox, mock_herdr, mock_agents, name, server): _set_mock(mock_herdr, strict_agent_names=True) @@ -161,9 +162,10 @@ def test_wrapper_attach_calls_herdr_with_the_herdr_name(mam_sandbox, mock_herdr, # --- one sanitize rule ---------------------------------------------------------- NAMES = ["", "plain", "Upper-Case", "9lead", "-dash", "has space/and.dot", "x" * 32, "y" * 33, - LONG, LONG.upper(), "creator-claude-fix-issue-99-long-branch", "-n", "-e", "a\\nb"] + LONG, LONG.upper(), "creator-claude-fix-issue-99-long-branch", "-n", "-e", "a\\nb", + NL, "a\nb", "\n", "x\r\ny", "Up\nper"] UNI_NAMES = [UNI, "caf\u00e9-creator-claude", "\u00fc" * 40, "kelvin-\u212a", "\u65e5\u672c-creator-claude", - "\u0130" * 20 + "-creator-claude"] + "\u0130" * 20 + "-creator-claude", "\u00fc\n"] def test_lib_sh_has_one_definition(): @@ -509,6 +511,28 @@ def test_stop_does_not_take_an_unreadable_row_for_no_row(mam_sandbox, mock_herdr assert "orphan74" in json.loads(Path(mock_herdr).read_text())["agents"] +@pytest.mark.parametrize("broken", ["yaml-without-db", "db"]) +def test_stop_does_not_take_an_unreadable_registry_for_no_row(mam_sandbox, mock_herdr, broken): + """load_state_json's {} on a read error is not "no row": a registered session is not closed row-less.""" + name = "orphan75-creator-claude" + _seed(mam_sandbox, [{"name": name, "status": "running", "role": "creator", "agent": "claude", + "pane": {"cwd": str(mam_sandbox), "cmd": "claude"}}]) + mam = mam_sandbox / ".mam" + if broken == "yaml-without-db": + for f in mam.glob("agent-sessions.db*"): + f.unlink() + (mam / "agent-sessions.yaml").write_text("herdr_sessions: [\n - {name: " + name + "\n") + else: + for f in mam.glob("agent-sessions.db-*"): + f.unlink() + (mam / "agent-sessions.db").write_bytes(b"this is not a database" * 64) + _set_mock(mock_herdr, agents={name: _agent(mam_sandbox, "w1:p76")}) + res = _stop(mam_sandbox, name) + assert res.returncode == 1, res.stdout + res.stderr + assert "cannot read" in res.stderr and "no registry row" not in res.stdout + assert name in json.loads(Path(mock_herdr).read_text())["agents"] + + def test_stop_without_a_row_purges_nothing(mam_sandbox, mock_herdr, registry_with_a_row): _set_mock(mock_herdr, agents={"orphan72": _agent(mam_sandbox, "w1:p73")}) res = _stop(mam_sandbox, "orphan72", "--purge-conversation", "--yes") diff --git a/tests/test_layout.py b/tests/test_layout.py index 857dc56..3a753b0 100644 --- a/tests/test_layout.py +++ b/tests/test_layout.py @@ -239,7 +239,8 @@ def test_lib_sh_no_local_in_shim_heredoc(): with open(lib_path, "r", encoding="utf-8") as f: content = f.read() - start_idx = content.find("cat <<'EOF' > \"$tmp_file\"") + # Issue #71: the shim is written as { printf ...; declare -f ...; cat <<'EOF' ... } > "$tmp_file" + start_idx = content.find("cat <<'EOF'\n") end_idx = content.find("\nEOF\n", start_idx) assert start_idx != -1 and end_idx != -1