Files
.pouch/tests/test_ship_record.py
T
laily af6e139d30 feat: rename bugfix-ship/requirement-flow to short-ship/long-ship with shared ship records
short-ship and long-ship share one ship-id record under .pouch/ship/<id>/.
specifier writes PRDs into spec/; delivery-loop appends evidence pointers.
Old names stay as deprecation stubs so existing installs keep working.
2026-10-13 23:11:58 +08:00

160 lines
5.3 KiB
Python

from __future__ import annotations
import subprocess
import sys
import tempfile
import unittest
from pathlib import Path
REPO_ROOT = Path(__file__).resolve().parents[1]
CREATE = REPO_ROOT / "skills" / "ship" / "scripts" / "create_ship.py"
VALIDATE = REPO_ROOT / "skills" / "ship" / "scripts" / "validate_ship.py"
APPEND = REPO_ROOT / "skills" / "ship" / "scripts" / "append_evidence.py"
def _run(script: Path, *args: str, cwd: Path | None = None) -> subprocess.CompletedProcess[str]:
return subprocess.run(
[sys.executable, str(script), *args],
check=False,
capture_output=True,
text=True,
cwd=cwd,
)
class YamlEmptyCollectionsTests(unittest.TestCase):
def test_roundtrip_empty_list_and_dict(self) -> None:
from pouch.yaml_io import safe_dump, safe_load
data = {"items": [], "meta": {}}
loaded = safe_load(safe_dump(data))
self.assertEqual(loaded, data)
class CreateAndValidateTests(unittest.TestCase):
def test_create_short_ship_validates(self) -> None:
with tempfile.TemporaryDirectory() as tmp:
root = Path(tmp)
result = _run(
CREATE,
"--project-root",
str(root),
"--ship-id",
"add-export-button",
"--kind",
"short",
"--title",
"列表页增加导出按钮",
)
self.assertEqual(result.returncode, 0, result.stderr)
ship_dir = root / ".pouch" / "ship" / "add-export-button"
self.assertTrue((ship_dir / "current.yaml").is_file())
self.assertTrue((ship_dir / "spec.md").is_file())
self.assertFalse((ship_dir / "spec").is_dir())
check = _run(VALIDATE, str(ship_dir))
self.assertEqual(check.returncode, 0, check.stderr)
def test_create_long_ship_has_spec_dir(self) -> None:
with tempfile.TemporaryDirectory() as tmp:
root = Path(tmp)
result = _run(
CREATE,
"--project-root",
str(root),
"--ship-id",
"tenant-permissions",
"--kind",
"long",
"--title",
"多租户权限",
)
self.assertEqual(result.returncode, 0, result.stderr)
ship_dir = root / ".pouch" / "ship" / "tenant-permissions"
self.assertTrue((ship_dir / "spec").is_dir())
check = _run(VALIDATE, str(ship_dir))
self.assertEqual(check.returncode, 0, check.stderr)
def test_rejects_date_id(self) -> None:
with tempfile.TemporaryDirectory() as tmp:
result = _run(
CREATE,
"--project-root",
tmp,
"--ship-id",
"20261013",
"--kind",
"short",
"--title",
"nope",
)
self.assertNotEqual(result.returncode, 0)
self.assertIn("日期", result.stderr)
def test_append_test_run_pointer(self) -> None:
with tempfile.TemporaryDirectory() as tmp:
root = Path(tmp)
created = _run(
CREATE,
"--project-root",
str(root),
"--ship-id",
"add-export-button",
"--kind",
"short",
"--title",
"列表页增加导出按钮",
)
self.assertEqual(created.returncode, 0, created.stderr)
run_dir = root / ".pouch" / "tester" / "runs"
run_dir.mkdir(parents=True)
run_path = run_dir / "20261013T010000Z-smoke-ab12.yaml"
run_path.write_text("runId: demo\n", encoding="utf-8")
ship_dir = root / ".pouch" / "ship" / "add-export-button"
appended = _run(
APPEND,
str(ship_dir),
"--kind",
"testRun",
"--path",
".pouch/tester/runs/20261013T010000Z-smoke-ab12.yaml",
"--result",
"pass",
"--suite",
"smoke",
)
self.assertEqual(appended.returncode, 0, appended.stderr)
text = (ship_dir / "current.yaml").read_text(encoding="utf-8")
self.assertIn("20261013T010000Z-smoke-ab12.yaml", text)
def test_missing_pointer_file_fails(self) -> None:
with tempfile.TemporaryDirectory() as tmp:
root = Path(tmp)
_run(
CREATE,
"--project-root",
str(root),
"--ship-id",
"add-export-button",
"--kind",
"short",
"--title",
"列表页增加导出按钮",
)
ship_dir = root / ".pouch" / "ship" / "add-export-button"
appended = _run(
APPEND,
str(ship_dir),
"--kind",
"testRun",
"--path",
".pouch/tester/runs/missing.yaml",
"--result",
"pass",
)
self.assertNotEqual(appended.returncode, 0)
self.assertIn("不存在", appended.stderr)
if __name__ == "__main__":
unittest.main()