Files
claude-code-api/tests/test_paths.py
T

102 lines
3.2 KiB
Python

"""Unit tests for `jsonl_paths` — pure string transforms + light fs lookup."""
from __future__ import annotations
import pytest
from claude_code_api.paths import (
claude_home,
encode_project_key,
find_jsonl_by_session_id,
projects_root,
resolve_jsonl_path,
session_dir,
)
# ----- encode_project_key -----------------------------------------------------
@pytest.mark.parametrize(
("cwd", "expected"),
[
# Observed in this repo: bare alnum + slashes + literal dashes.
(
"/Users/h/projects/playgrounds/claude-code-sdk",
"-Users-h-projects-playgrounds-claude-code-sdk",
),
# Observed: dot-prefixed dir produces doubled dash, dash-containing
# path segments survive unchanged.
(
"/Users/h/.t3/worktrees/cars-system/t3code-9d8591ad",
"-Users-h--t3-worktrees-cars-system-t3code-9d8591ad",
),
# Trailing slash collapses to a trailing dash — claude would not
# normally see this, but the encoder is deterministic.
("/Users/h/", "-Users-h-"),
# Root.
("/", "-"),
# Spaces, parentheses, other punct all become dashes.
("/tmp/My Project (v2)", "-tmp-My-Project--v2-"),
],
)
def test_encode_known_paths(cwd: str, expected: str) -> None:
assert encode_project_key(cwd) == expected
def test_encode_rejects_relative() -> None:
with pytest.raises(ValueError, match="absolute"):
encode_project_key("relative/path")
def test_encode_rejects_empty() -> None:
with pytest.raises(ValueError, match="empty"):
encode_project_key("")
# ----- resolve_jsonl_path / session_dir --------------------------------------
def test_resolve_jsonl_path_under_fake_home(tmp_path):
sid = "deadbeef-0000-4000-8000-000000000001"
p = resolve_jsonl_path("/foo/bar", sid, home=tmp_path)
assert p == tmp_path / ".claude" / "projects" / "-foo-bar" / f"{sid}.jsonl"
def test_session_dir_matches_resolve_parent(tmp_path):
sid = "deadbeef-0000-4000-8000-000000000002"
assert resolve_jsonl_path("/a/b", sid, home=tmp_path).parent == session_dir(
"/a/b", home=tmp_path
)
def test_resolve_rejects_empty_session_id(tmp_path):
with pytest.raises(ValueError, match="session_id"):
resolve_jsonl_path("/foo", "", home=tmp_path)
def test_claude_home_and_projects_root_honor_override(tmp_path):
assert claude_home(tmp_path) == tmp_path / ".claude"
assert projects_root(tmp_path) == tmp_path / ".claude" / "projects"
# ----- find_jsonl_by_session_id ---------------------------------------------
def test_find_returns_none_when_root_missing(tmp_path):
# No `.claude/projects` under tmp_path.
assert find_jsonl_by_session_id("nope", home=tmp_path) is None
def test_find_locates_existing_session(tmp_path):
sid = "abcdef00-1111-4000-8000-000000000000"
p = resolve_jsonl_path("/some/cwd", sid, home=tmp_path)
p.parent.mkdir(parents=True)
p.write_text("{}\n")
found = find_jsonl_by_session_id(sid, home=tmp_path)
assert found == p
def test_find_rejects_empty_session_id(tmp_path):
with pytest.raises(ValueError, match="session_id"):
find_jsonl_by_session_id("", home=tmp_path)