Files
.pouch/tests/test_pouch_catalog.py
T
2026-09-08 15:25:58 +08:00

124 lines
4.9 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]
CATALOG = REPO_ROOT / "skills" / "pouch" / "scripts" / "catalog.py"
SUGGEST = REPO_ROOT / "skills" / "pouch" / "scripts" / "suggest_skills.py"
def _run(script: Path, *args: str) -> subprocess.CompletedProcess[str]:
return subprocess.run(
[sys.executable, str(script), *args],
check=False,
capture_output=True,
text=True,
)
class CatalogTests(unittest.TestCase):
def test_repo_skills_have_lede_and_example(self) -> None:
result = _run(CATALOG, "--skills-dir", str(REPO_ROOT / "skills"))
self.assertEqual(result.returncode, 0, result.stderr)
for name in (
"ack",
"builder",
"deployer",
"host-sec-check",
"manage-release",
"note-style",
"pouch",
):
self.assertIn(f"| {name} |", result.stdout)
self.assertIn("/ack 初始化", result.stdout)
self.assertIn("用 builder 初始化这个项目", result.stdout)
self.assertNotIn("触发词", result.stdout)
def test_missing_readme_fails(self) -> None:
with tempfile.TemporaryDirectory() as tmp:
skill = Path(tmp) / "demo"
skill.mkdir()
(skill / "SKILL.md").write_text(
"---\nname: demo\ndescription: d\n---\n# demo\n",
encoding="utf-8",
)
result = _run(CATALOG, "--skills-dir", tmp)
self.assertEqual(result.returncode, 1)
self.assertIn("缺少 README.md", result.stderr)
def test_extracts_first_sentence_and_skips_hash_comments(self) -> None:
with tempfile.TemporaryDirectory() as tmp:
skill = Path(tmp) / "demo"
skill.mkdir()
(skill / "SKILL.md").write_text(
"---\nname: demo\ndescription: d\n---\n# demo\n",
encoding="utf-8",
)
(skill / "README.md").write_text(
"# demo\n\n"
"这是一句话说明。后面还有一句不该进短清单。\n\n"
"## 使用示例\n\n"
"```text\n"
"# 注释\n"
"用 demo 做这件事。\n"
"```\n",
encoding="utf-8",
)
result = _run(CATALOG, "--skills-dir", tmp)
self.assertEqual(result.returncode, 0, result.stderr)
self.assertIn("这是一句话说明。", result.stdout)
self.assertNotIn("不该进短清单", result.stdout)
self.assertIn("用 demo 做这件事。", result.stdout)
class SuggestSkillsTests(unittest.TestCase):
def test_pouch_repo_is_not_an_app(self) -> None:
result = _run(SUGGEST, str(REPO_ROOT))
self.assertEqual(result.returncode, 0, result.stderr)
self.assertIn("this_is_pouch_repo: true", result.stdout)
self.assertNotIn("suggested:", result.stdout)
def test_dockerfile_suggests_builder(self) -> None:
with tempfile.TemporaryDirectory() as tmp:
root = Path(tmp)
(root / "Dockerfile").write_text("FROM scratch\n", encoding="utf-8")
result = _run(SUGGEST, str(root))
self.assertEqual(result.returncode, 0, result.stderr)
self.assertIn("this_is_pouch_repo: false", result.stdout)
self.assertIn("builder", result.stdout)
self.assertIn("Dockerfile", result.stdout)
self.assertIn("用 builder 初始化", result.stdout)
self.assertIn("不要 `pouch init builder`", result.stdout)
def test_existing_makefile_builder_is_already(self) -> None:
with tempfile.TemporaryDirectory() as tmp:
root = Path(tmp)
(root / "makefile.builder").write_text("build:\n", encoding="utf-8")
result = _run(SUGGEST, str(root))
self.assertEqual(result.returncode, 0, result.stderr)
self.assertIn("already:", result.stdout)
self.assertIn("builder", result.stdout)
self.assertIn("init: (none)", result.stdout)
def test_compose_and_ack_dir(self) -> None:
with tempfile.TemporaryDirectory() as tmp:
root = Path(tmp)
(root / "compose.yaml").write_text("services: {}\n", encoding="utf-8")
(root / ".pouch" / "ack").mkdir(parents=True)
result = _run(SUGGEST, str(root))
self.assertEqual(result.returncode, 0, result.stderr)
self.assertIn("deployer", result.stdout)
self.assertIn("compose.yaml", result.stdout)
self.assertIn("ack", result.stdout)
self.assertIn(".pouch/ack", result.stdout)
self.assertIn("用 deployer 初始化", result.stdout)
self.assertNotIn("/ack 初始化", result.stdout)
if __name__ == "__main__":
unittest.main()