mirror of
https://github.com/codestable/CodeStable.git
synced 2026-09-19 09:03:09 +08:00
30fecaae5e
收敛 CodeStable 主入口、runtime preflight、goal driver 与 skill 工程化评测闭环。 - 根 cs 对行动请求同轮直转,咨询与介绍保持非执行 - feature/issue/refactor/epic/docs 按仓库事实恢复,旧 stage skill 保留兼容薄壳 - repo-local runtime 支持版本检测、安全自动同步和显式 refresh-runtime - 完成 Codex/Claude marketplace 1.0.2、升级文档和回归/评测证据 验证:215 tests passed;package/runtime/diff checks passed;独立 review 与 QA 无 unresolved blocking/important findings。
145 lines
3.6 KiB
Python
145 lines
3.6 KiB
Python
from __future__ import annotations
|
|
|
|
import json
|
|
import subprocess
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
|
|
TOOLS_DIR = Path(__file__).resolve().parents[1] / "plugins/codestable/skills/cs-onboard/tools"
|
|
DOD_RUNNER = TOOLS_DIR / "codestable-dod-runner.py"
|
|
|
|
|
|
def run_dod(tmp_path: Path, checklist_yaml: str, existing_json_out: str | None = None) -> dict:
|
|
repo = tmp_path / "proj"
|
|
(repo / ".codestable").mkdir(parents=True, exist_ok=True) # repo_root() marker
|
|
checklist = repo / "checklist.yaml"
|
|
checklist.write_text(checklist_yaml, encoding="utf-8")
|
|
out = repo / "dod-results.json"
|
|
if existing_json_out is not None:
|
|
out.write_text(existing_json_out, encoding="utf-8")
|
|
subprocess.run(
|
|
[sys.executable, str(DOD_RUNNER), "--checklist", str(checklist), "--json-out", str(out)],
|
|
cwd=repo,
|
|
text=True,
|
|
capture_output=True,
|
|
env={"PYTHONDONTWRITEBYTECODE": "1", "PATH": __import__("os").environ.get("PATH", "")},
|
|
)
|
|
return json.loads(out.read_text(encoding="utf-8"))
|
|
|
|
|
|
def test_top_level_dod_commands_are_run(tmp_path: Path) -> None:
|
|
"""Regression: top-level `dod.commands` (the authoritative schema) must be
|
|
executed, not skipped."""
|
|
data = run_dod(
|
|
tmp_path,
|
|
"""feature: x
|
|
steps:
|
|
- action: a
|
|
status: done
|
|
dod:
|
|
commands:
|
|
- id: CMD-001
|
|
command: "true"
|
|
core: true
|
|
- id: CMD-002
|
|
command: "false"
|
|
core: true
|
|
""",
|
|
)
|
|
assert data["status"] == "failed" # CMD-002 (core) exits non-zero
|
|
assert {e["id"] for e in data["evidence"]} == {"CMD-001", "CMD-002"}
|
|
|
|
|
|
def test_step_level_dod_commands_still_supported(tmp_path: Path) -> None:
|
|
data = run_dod(
|
|
tmp_path,
|
|
"""feature: x
|
|
steps:
|
|
- action: a
|
|
status: done
|
|
dod:
|
|
commands:
|
|
- id: S-1
|
|
command: "true"
|
|
core: true
|
|
""",
|
|
)
|
|
assert data["status"] == "passed"
|
|
assert [e["id"] for e in data["evidence"]] == ["S-1"]
|
|
|
|
|
|
def test_top_level_takes_precedence_no_duplicate(tmp_path: Path) -> None:
|
|
"""When both top-level and step-level dod.commands exist, top-level is the
|
|
single source — commands must NOT be executed twice."""
|
|
data = run_dod(
|
|
tmp_path,
|
|
"""feature: x
|
|
dod:
|
|
commands:
|
|
- id: CMD-001
|
|
command: "true"
|
|
core: true
|
|
- id: CMD-002
|
|
command: "true"
|
|
core: true
|
|
steps:
|
|
- action: a
|
|
status: done
|
|
dod:
|
|
commands:
|
|
- id: CMD-001
|
|
command: "true"
|
|
core: true
|
|
- id: CMD-002
|
|
command: "true"
|
|
core: true
|
|
""",
|
|
)
|
|
assert data["status"] == "passed"
|
|
ids = [e["id"] for e in data["evidence"]]
|
|
assert ids == ["CMD-001", "CMD-002"] # each once, no duplicate
|
|
|
|
|
|
def test_non_core_failure_is_warning_not_block(tmp_path: Path) -> None:
|
|
data = run_dod(
|
|
tmp_path,
|
|
"""feature: x
|
|
dod:
|
|
commands:
|
|
- id: NC-1
|
|
command: "false"
|
|
core: false
|
|
""",
|
|
)
|
|
assert data["status"] == "passed"
|
|
assert any("NC-1" in w for w in data["warnings"])
|
|
|
|
|
|
def test_no_commands_is_skipped(tmp_path: Path) -> None:
|
|
data = run_dod(
|
|
tmp_path,
|
|
"""feature: x
|
|
steps:
|
|
- action: a
|
|
status: done
|
|
""",
|
|
)
|
|
assert data["status"] == "skipped"
|
|
|
|
|
|
def test_existing_json_out_is_hidden_from_dod_commands(tmp_path: Path) -> None:
|
|
data = run_dod(
|
|
tmp_path,
|
|
"""feature: x
|
|
dod:
|
|
commands:
|
|
- id: CMD-001
|
|
command: "test ! -e dod-results.json"
|
|
core: true
|
|
""",
|
|
existing_json_out='{"status":"stale"}\n',
|
|
)
|
|
assert data["status"] == "passed"
|
|
assert data["evidence"][0]["exit_code"] == 0
|