import subprocess import sys import tempfile import unittest from pathlib import Path ROOT = Path(__file__).resolve().parents[2] SCRIPT = ROOT / "scripts" / "playbook.py" CUSTOM_DEPLOY_ROOT = "custom/playbook" def run_cli(*args): return subprocess.run( [sys.executable, str(SCRIPT), *args], capture_output=True, text=True, ) def write_config(root: Path, name: str, body: str) -> Path: config_path = root / name config_path.write_text(body, encoding="utf-8") return config_path class SyncStandardsCliTests(unittest.TestCase): def test_sync_standards_creates_agents(self): with tempfile.TemporaryDirectory() as tmp_dir: config_body = f""" [playbook] project_root = "{tmp_dir}" playbook_root = "{CUSTOM_DEPLOY_ROOT}" install_mode = "snapshot" [sync_standards] langs = ["tsl"] """ config_path = Path(tmp_dir) / "playbook.toml" config_path.write_text(config_body, encoding="utf-8") result = run_cli("-config", str(config_path)) agents_index = Path(tmp_dir) / ".agents/tsl/index.md" self.assertEqual(result.returncode, 0) self.assertTrue(agents_index.is_file()) def test_sync_standards_updates_agents_index_when_langs_expand(self): with tempfile.TemporaryDirectory() as tmp_dir: root = Path(tmp_dir) first_config = root / "playbook-first.toml" first_config.write_text( f""" [playbook] project_root = "{tmp_dir}" playbook_root = "{CUSTOM_DEPLOY_ROOT}" install_mode = "snapshot" [sync_standards] langs = ["tsl"] no_backup = true """, encoding="utf-8", ) first_result = run_cli("-config", str(first_config)) self.assertEqual(first_result.returncode, 0) second_config = root / "playbook-second.toml" second_config.write_text( f""" [playbook] project_root = "{tmp_dir}" playbook_root = "{CUSTOM_DEPLOY_ROOT}" install_mode = "snapshot" [sync_standards] langs = ["tsl", "cpp"] no_backup = true """, encoding="utf-8", ) second_result = run_cli("-config", str(second_config)) self.assertEqual(second_result.returncode, 0) agents_index = (root / ".agents" / "index.md").read_text(encoding="utf-8") self.assertIn("`.agents/tsl/index.md`", agents_index) self.assertIn("`.agents/cpp/index.md`", agents_index) def test_sync_standards_agents_index_only_lists_configured_langs(self): with tempfile.TemporaryDirectory() as tmp_dir: root = Path(tmp_dir) config_body = f""" [playbook] project_root = "{tmp_dir}" playbook_root = "{CUSTOM_DEPLOY_ROOT}" install_mode = "snapshot" [sync_standards] langs = ["tsl", "markdown"] """ config_path = write_config(root, "playbook.toml", config_body) result = run_cli("-config", str(config_path)) self.assertEqual(result.returncode, 0, msg=result.stdout + result.stderr) agents_index = (root / ".agents" / "index.md").read_text(encoding="utf-8") self.assertIn("`.agents/tsl/`:TSL 相关规则集", agents_index) self.assertIn("`.agents/markdown/`:Markdown 相关规则集", agents_index) self.assertNotIn("`.agents/cpp/`", agents_index) self.assertNotIn("`.agents/python/`", agents_index) self.assertNotIn("`.agents/typescript/`", agents_index) def test_sync_standards_agents_block_has_blank_lines(self): with tempfile.TemporaryDirectory() as tmp_dir: config_body = f""" [playbook] project_root = "{tmp_dir}" playbook_root = "{CUSTOM_DEPLOY_ROOT}" install_mode = "snapshot" [sync_standards] langs = ["tsl"] """ config_path = Path(tmp_dir) / "playbook.toml" config_path.write_text(config_body, encoding="utf-8") result = run_cli("-config", str(config_path)) self.assertEqual(result.returncode, 0) agents_md = Path(tmp_dir) / "AGENTS.md" lines = agents_md.read_text(encoding="utf-8").splitlines() start_idx = lines.index("") end_idx = lines.index("") block = lines[start_idx : end_idx + 1] self.assertEqual(block[1], "") bullet_idx = next(i for i, line in enumerate(block) if line.startswith("- ")) self.assertEqual(block[bullet_idx - 1], "") if __name__ == "__main__": unittest.main()