import tempfile import unittest from pathlib import Path from audit_database import migration_manifest, compare_snapshots class MigrationAuditTest(unittest.TestCase): def test_manifest_is_numerically_sorted_and_ignores_line_endings(self): with tempfile.TemporaryDirectory() as folder: root = Path(folder) (root / "V10__ten.sql").write_bytes(b"SELECT 10;\r\n") (root / "V2__two.sql").write_bytes(b"SELECT 2;\n") before = migration_manifest(root) self.assertEqual([2, 10], [r["version"] for r in before]) (root / "V10__ten.sql").write_bytes(b"SELECT 10;\n") self.assertEqual(before, migration_manifest(root)) (root / "V10__ten.sql").write_bytes(b"SELECT 11;\n") self.assertNotEqual(before, migration_manifest(root)) def test_duplicate_versions_are_rejected(self): with tempfile.TemporaryDirectory() as folder: root = Path(folder) for name in ("V2__a.sql", "V2__b.sql"): (root / name).write_text("SELECT 1;", encoding="utf-8") with self.assertRaisesRegex(ValueError, "迁移版本重复"): migration_manifest(root) def test_structure_drift_is_detected_without_count_or_timestamp_noise(self): self.assertEqual([], compare_snapshots({"integrity": {"n": 1}}, {"integrity": {"n": 0}})) self.assertEqual(["indexes"], compare_snapshots({"indexes": []}, {"indexes": ["new"]})) if __name__ == "__main__": unittest.main()