"""台账测试:dry-run 隔离、跨 run 续跑、字段合并。""" from __future__ import annotations import os import tempfile import unittest from qtimport.store import Store class StoreTest(unittest.TestCase): def setUp(self) -> None: self.folder = tempfile.TemporaryDirectory() self.store = Store(os.path.join(self.folder.name, "t.db")) def tearDown(self) -> None: self.store.close() self.folder.cleanup() def _job(self, run_id: str, stage: str, worksheet_id: int | None = 1) -> None: self.store.upsert_job( run_id, project_id="p1", project_name="P", system_name="2026 Sprint 10", source_file="f.xlsx", action="create", stage=stage, worksheet_id=worksheet_id, ) def test_latest_stage_across_runs(self) -> None: self.store.start_run("r1", "s", "d", dry_run=False) self._job("r1", "WS_CREATED") self.store.start_run("r2", "s", "d", dry_run=False) self._job("r2", "WS_FILLED") self.assertEqual(self.store.latest_stage("p1", "2026 Sprint 10"), "WS_FILLED") def test_dry_run_does_not_pollute_ledger(self) -> None: self.store.start_run("real", "s", "d", dry_run=False) self._job("real", "WS_FILLED") self.store.start_run("dry", "s", "d", dry_run=True) self._job("dry", "TFS_PUSHED") self.assertEqual( self.store.latest_stage("p1", "2026 Sprint 10"), "WS_FILLED", "dry-run 不能把项目标成已推送", ) def test_worksheet_id_survives_partial_update(self) -> None: self.store.start_run("r1", "s", "d", dry_run=False) self._job("r1", "WS_CREATED", worksheet_id=777) self._job("r1", "WS_FILLED", worksheet_id=None) job = self.store.latest_job("p1", "2026 Sprint 10") self.assertEqual(job["worksheet_id"], 777) self.assertEqual(job["stage"], "WS_FILLED") def test_skipped_row_does_not_mask_progress(self) -> None: """跳过行不带进度:不能把「已推送」覆盖成「SKIPPED」,否则下次会重推 TFS。""" self.store.start_run("r1", "s", "d", dry_run=False) self._job("r1", "TFS_PUSHED") self.store.start_run("r2", "s", "d", dry_run=False) self._job("r2", "SKIPPED") job = self.store.latest_job("p1", "2026 Sprint 10") self.assertEqual(job["stage"], "TFS_PUSHED") def test_events_ordered(self) -> None: self.store.start_run("r1", "s", "d", dry_run=False) self.store.add_event("r1", stage="A", action="ok", detail="1") self.store.add_event("r1", stage="B", action="ok", detail="2") self.assertEqual([e["stage"] for e in self.store.events("r1")], ["A", "B"]) if __name__ == "__main__": unittest.main()