import subprocess import sys import tempfile import unittest import platform from pathlib import Path ROOT = Path(__file__).resolve().parents[1] SCRIPT = ROOT / "scripts" / "plan_progress.py" def run_cli(*args, cwd=None): return subprocess.run( [sys.executable, str(SCRIPT), *args], capture_output=True, text=True, cwd=cwd, ) class PlanProgressCliTests(unittest.TestCase): def _current_env(self) -> str: system = platform.system().lower() mapping = {"windows": "windows", "linux": "linux", "darwin": "darwin"} if system not in mapping: self.skipTest(f"Unsupported environment: {system}") return mapping[system] def test_select_seeds_progress_when_missing(self): with tempfile.TemporaryDirectory() as tmp_dir: root = Path(tmp_dir) plans_dir = root / "docs" / "plans" plans_dir.mkdir(parents=True) (plans_dir / "2026-01-01-old.md").write_text("old", encoding="utf-8") (plans_dir / "2026-01-02-new.md").write_text("new", encoding="utf-8") result = run_cli( "select", "-plans", "docs/plans", "-progress", "memory-bank/progress.md", cwd=root, ) self.assertEqual(result.returncode, 0, msg=result.stderr) self.assertEqual(result.stdout.strip(), "docs/plans/2026-01-01-old.md") progress = root / "memory-bank" / "progress.md" text = progress.read_text(encoding="utf-8") self.assertIn("", text) self.assertIn("", text) self.assertIn("`2026-01-01-old.md` pending", text) self.assertIn("`2026-01-02-new.md` pending", text) def test_select_returns_first_pending_in_order(self): with tempfile.TemporaryDirectory() as tmp_dir: root = Path(tmp_dir) plans_dir = root / "docs" / "plans" plans_dir.mkdir(parents=True) (plans_dir / "2026-01-01-a.md").write_text("a", encoding="utf-8") (plans_dir / "2026-01-02-b.md").write_text("b", encoding="utf-8") progress = root / "memory-bank" / "progress.md" progress.parent.mkdir(parents=True) progress.write_text( "\n".join( [ "# Plan 状态", "", "", "- [ ] `2026-01-02-b.md` pending", "- [ ] `2026-01-01-a.md` pending", "", "", ] ), encoding="utf-8", ) result = run_cli( "select", "-plans", "docs/plans", "-progress", "memory-bank/progress.md", cwd=root, ) self.assertEqual(result.returncode, 0, msg=result.stderr) self.assertEqual(result.stdout.strip(), "docs/plans/2026-01-02-b.md") def test_select_returns_env_blocked_plan_without_flag(self): with tempfile.TemporaryDirectory() as tmp_dir: root = Path(tmp_dir) plans_dir = root / "docs" / "plans" plans_dir.mkdir(parents=True) (plans_dir / "2026-01-05-env.md").write_text("env", encoding="utf-8") progress = root / "memory-bank" / "progress.md" progress.parent.mkdir(parents=True) env = self._current_env() progress.write_text( "\n".join( [ "# Plan 状态", "", "", f"- [ ] `2026-01-05-env.md` blocked: env:{env}:Task1", "", "", ] ), encoding="utf-8", ) result = run_cli( "select", "-plans", "docs/plans", "-progress", "memory-bank/progress.md", cwd=root, ) self.assertEqual(result.returncode, 0, msg=result.stderr) self.assertEqual(result.stdout.strip(), "docs/plans/2026-01-05-env.md") def test_record_updates_line(self): with tempfile.TemporaryDirectory() as tmp_dir: root = Path(tmp_dir) progress = root / "memory-bank" / "progress.md" progress.parent.mkdir(parents=True) progress.write_text( "\n".join( [ "# Plan 状态", "", "", "- [ ] `2026-01-03-demo.md` pending", "", "", ] ), encoding="utf-8", ) result = run_cli( "record", "-plan", "docs/plans/2026-01-03-demo.md", "-status", "done", "-progress", "memory-bank/progress.md", cwd=root, ) self.assertEqual(result.returncode, 0, msg=result.stderr) text = progress.read_text(encoding="utf-8") self.assertIn("- [x] `2026-01-03-demo.md` done", text) self.assertEqual(text.count("2026-01-03-demo.md"), 1) if __name__ == "__main__": unittest.main()