feat: project management module — create, log, read, list, server persistence
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,8 @@
|
||||
import pytest
|
||||
|
||||
@pytest.fixture
|
||||
def tmp_workbench(tmp_path):
|
||||
"""Provide a temporary workbench directory."""
|
||||
wb = tmp_path / "workbench"
|
||||
wb.mkdir()
|
||||
return wb
|
||||
@@ -0,0 +1,81 @@
|
||||
import json
|
||||
from workbench.project import (
|
||||
create_project, project_exists, project_path,
|
||||
append_log, read_log, list_projects, log_session_event,
|
||||
write_server_info, read_server_info, clear_server_info,
|
||||
WORKBENCH_DIR,
|
||||
)
|
||||
|
||||
|
||||
def test_create_project(tmp_workbench):
|
||||
path = create_project("io102", "Heathkit IO-102", workbench_dir=tmp_workbench)
|
||||
assert path.exists()
|
||||
assert (path / "index.html").exists()
|
||||
assert (path / "session.md").exists()
|
||||
assert (path / "session.jsonl").exists()
|
||||
assert (path / "cost-log.jsonl").exists()
|
||||
assert (path / "state.json").exists()
|
||||
assert (path / "assets").is_dir()
|
||||
md = (path / "session.md").read_text()
|
||||
assert "Heathkit IO-102" in md
|
||||
|
||||
|
||||
def test_create_project_idempotent(tmp_workbench):
|
||||
create_project("io102", "First", workbench_dir=tmp_workbench)
|
||||
append_log("io102", "test entry", workbench_dir=tmp_workbench)
|
||||
create_project("io102", "Second", workbench_dir=tmp_workbench)
|
||||
entries = read_log("io102", workbench_dir=tmp_workbench)
|
||||
assert len(entries) == 1
|
||||
|
||||
|
||||
def test_project_exists(tmp_workbench):
|
||||
assert not project_exists("io102", workbench_dir=tmp_workbench)
|
||||
create_project("io102", "Test", workbench_dir=tmp_workbench)
|
||||
assert project_exists("io102", workbench_dir=tmp_workbench)
|
||||
|
||||
|
||||
def test_append_and_read_log(tmp_workbench):
|
||||
create_project("io102", "Test", workbench_dir=tmp_workbench)
|
||||
append_log("io102", "R412 measured 1.05M", data={"ohms": 1050000}, workbench_dir=tmp_workbench)
|
||||
append_log("io102", "R413 OK", workbench_dir=tmp_workbench)
|
||||
entries = read_log("io102", tail=10, workbench_dir=tmp_workbench)
|
||||
assert len(entries) == 2
|
||||
assert entries[0]["entry"] == "R412 measured 1.05M"
|
||||
assert entries[0]["ohms"] == 1050000
|
||||
|
||||
|
||||
def test_read_log_tail(tmp_workbench):
|
||||
create_project("io102", "Test", workbench_dir=tmp_workbench)
|
||||
for i in range(30):
|
||||
append_log("io102", f"Entry {i}", workbench_dir=tmp_workbench)
|
||||
entries = read_log("io102", tail=5, workbench_dir=tmp_workbench)
|
||||
assert len(entries) == 5
|
||||
assert entries[0]["entry"] == "Entry 25"
|
||||
|
||||
|
||||
def test_list_projects(tmp_workbench):
|
||||
assert list_projects(workbench_dir=tmp_workbench) == []
|
||||
create_project("io102", "First", workbench_dir=tmp_workbench)
|
||||
create_project("psu-rebuild", "Second", workbench_dir=tmp_workbench)
|
||||
projects = list_projects(workbench_dir=tmp_workbench)
|
||||
assert [p["name"] for p in projects] == ["io102", "psu-rebuild"]
|
||||
|
||||
|
||||
def test_log_session_event(tmp_workbench):
|
||||
create_project("io102", "Test", workbench_dir=tmp_workbench)
|
||||
log_session_event("io102", "session_start", workbench_dir=tmp_workbench)
|
||||
cost_log = (tmp_workbench / "io102" / "cost-log.jsonl").read_text().strip()
|
||||
entry = json.loads(cost_log.split("\n")[-1])
|
||||
assert entry["event"] == "session_start"
|
||||
|
||||
|
||||
def test_server_info_write_read_clear(tmp_workbench):
|
||||
create_project("io102", "Test", workbench_dir=tmp_workbench)
|
||||
write_server_info("io102", pid=12345, port=8070, workbench_dir=tmp_workbench)
|
||||
info = read_server_info("io102", workbench_dir=tmp_workbench)
|
||||
assert info is not None
|
||||
assert info["pid"] == 12345
|
||||
assert info["port"] == 8070
|
||||
assert "started" in info
|
||||
clear_server_info("io102", workbench_dir=tmp_workbench)
|
||||
assert read_server_info("io102", workbench_dir=tmp_workbench) is None
|
||||
Reference in New Issue
Block a user