import importlib.util import sys import unittest from pathlib import Path from _helpers import REPO_ROOT, TempDirMixin def load_task_board_module(): script_path = REPO_ROOT / "scripts" / "gen_task_board.py" spec = importlib.util.spec_from_file_location("gen_task_board", script_path) module = importlib.util.module_from_spec(spec) sys.modules[spec.name] = module spec.loader.exec_module(module) return module class TaskBoardTests(TempDirMixin, unittest.TestCase): def write_task( self, tasks_dir, task_id, title, phase, deps, status, created="2026-07-08", ): deps_text = "[" + ", ".join(deps) + "]" path = Path(tasks_dir) / f"{task_id}.md" path.write_text( "\n".join( [ "---", f"id: {task_id}", f"title: {title}", f"phase: {phase}", f"deps: {deps_text}", f"status: {status}", f"created: {created}", "---", "", "## 问题 / 背景", "", ] ), encoding="utf-8", ) return path def test_generate_board_from_task_frontmatter_and_skips_invalid_files(self): module = load_task_board_module() with self.make_temp_dir() as temp_dir: tasks_dir = Path(temp_dir) / "tasks" tasks_dir.mkdir() output_path = Path(temp_dir) / "tasks-board.md" self.write_task(tasks_dir, "T-550", "已完成任务", 7, [], "DONE") self.write_task(tasks_dir, "T-551", "可领取任务", 8, ["T-550"], "TODO") self.write_task(tasks_dir, "T-552", "依赖未完成任务", 8, ["T-999"], "TODO") self.write_task(tasks_dir, "T-553", "进行中任务", 8, [], "DOING") (tasks_dir / "T-554.md").write_text( "---\nid: T-554\ntitle: 缺字段任务\n---\n", encoding="utf-8", ) tasks, warnings, output = module.generate_board(tasks_dir, output_path) self.assertEqual(["T-550", "T-551", "T-552", "T-553"], [task.id for task in tasks]) self.assertEqual(1, len(warnings)) self.assertIn("T-554.md", warnings[0]) self.assertTrue(output_path.exists()) content = output_path.read_text(encoding="utf-8") self.assertEqual(output, content) self.assertIn("请勿手改", content) self.assertIn("下一个可领取:T-551(可领取任务)", content) self.assertIn("| T-550 | 已完成任务 | - | DONE |", content) self.assertIn("| T-551 | 可领取任务 | T-550 | TODO |", content) self.assertIn("TODO 2", content) self.assertIn("DOING 1", content) self.assertNotIn("T-554", content) self.assert_removed(temp_dir) if __name__ == "__main__": unittest.main()