diff --git a/tests/test_loc_baseline.py b/tests/test_loc_baseline.py index f2ae2d0..78e547a 100644 --- a/tests/test_loc_baseline.py +++ b/tests/test_loc_baseline.py @@ -128,8 +128,8 @@ def test_create_and_update_lifecycle_is_non_increasing_and_atomic(self) -> None: "(0 lowered, 1 removed, 0 unchanged).\n" )) - def test_fail_closed_and_analysis_never_writes(self) -> None: - with tempfile.TemporaryDirectory() as temp, tempfile.TemporaryDirectory() as outside_temp: + def test_invalid_baseline_schema_fails_closed_and_preserves_bytes(self) -> None: + with tempfile.TemporaryDirectory() as temp: root = Path(temp) init_git(root) write_lines(root / "legacy.py", 7) @@ -153,22 +153,48 @@ def test_fail_closed_and_analysis_never_writes(self) -> None: self.assertNotIn("guards", self.read_json(invalid_version)) self.assertEqual(baseline.read_bytes(), wrong_version_type) - baseline.unlink() + def test_analysis_without_baseline_omits_ratchet_fields_and_never_writes(self) -> None: + with tempfile.TemporaryDirectory() as temp: + root = Path(temp) + init_git(root) + write_lines(root / "legacy.py", 7) + baseline = root / BASELINE no_baseline = self.run_guard(root, ".", "--warn", "3", "--fail", "5", "--json") self.assertNotIn("baselineLoc", self.findings(no_baseline)[0]) self.assertNotIn("ratchetStatus", self.findings(no_baseline)[0]) self.assertFalse(baseline.exists()) + + ordinary = self.run_guard(root, ".", "--warn", "3", "--fail", "5") + self.assertEqual(ordinary.returncode, 2) + self.assertFalse(baseline.exists()) + + def test_create_rejects_scope_outside_analysis_root_without_writing(self) -> None: + with tempfile.TemporaryDirectory() as temp, tempfile.TemporaryDirectory() as outside_temp: + root = Path(temp) + init_git(root) + write_lines(root / "legacy.py", 7) + baseline = root / BASELINE outside = Path(outside_temp) / "empty" outside.mkdir() escaped = self.run_guard(root, str(outside), "--create-loc-baseline") self.assertEqual(escaped.returncode, 3) self.assertFalse(baseline.exists()) + + def test_create_rejects_incompatible_arguments_without_stdout(self) -> None: + with tempfile.TemporaryDirectory() as temp: + root = Path(temp) + init_git(root) + write_lines(root / "legacy.py", 7) incompatible = self.run_guard(root, ".", "--create-loc-baseline", "--json") self.assertEqual((incompatible.returncode, incompatible.stdout), (3, "")) - ordinary = self.run_guard(root, ".", "--warn", "3", "--fail", "5") - self.assertEqual(ordinary.returncode, 2) - self.assertFalse(baseline.exists()) + def test_dangling_baseline_symlink_fails_closed_without_target_creation(self) -> None: + with tempfile.TemporaryDirectory() as temp, tempfile.TemporaryDirectory() as outside_temp: + root = Path(temp) + init_git(root) + write_lines(root / "legacy.py", 7) + baseline = root / BASELINE + baseline.parent.mkdir() missing_target = Path(outside_temp) / "missing-baseline.json" try: baseline.symlink_to(missing_target) @@ -185,8 +211,13 @@ def test_fail_closed_and_analysis_never_writes(self) -> None: self.assertNotIn("guards", self.read_json(dangling)) self.assertTrue(baseline.is_symlink()) self.assertFalse(missing_target.exists()) - baseline.unlink() + def test_baseline_rejects_allowed_large_files_overlap(self) -> None: + with tempfile.TemporaryDirectory() as temp: + root = Path(temp) + init_git(root) + write_lines(root / "legacy.py", 7) + baseline = root / BASELINE baseline.parent.mkdir(exist_ok=True) baseline.write_text(json.dumps({ "version": 1, @@ -201,9 +232,9 @@ def test_fail_closed_and_analysis_never_writes(self) -> None: self.assertEqual(overlap.returncode, 3) self.assertIn("overlaps allowedLargeFiles", overlap.stdout) - with tempfile.TemporaryDirectory() as temp, tempfile.TemporaryDirectory() as outside_temp: + def test_create_deduplicates_explicit_source_symlink(self) -> None: + with tempfile.TemporaryDirectory() as temp: root = Path(temp) - outside = Path(outside_temp) init_git(root) write_lines(root / "legacy.py", 7) try: @@ -217,8 +248,13 @@ def test_fail_closed_and_analysis_never_writes(self) -> None: self.assertEqual(direct_and_link.returncode, 0) stored = json.loads((root / BASELINE).read_text(encoding="utf-8"))["loc"]["files"] self.assertEqual(stored, [{"path": "legacy.py", "allowedLoc": 7}]) - (root / BASELINE).unlink() - (root / ".agent-tools").rmdir() + + def test_create_rejects_symlinked_storage_directory_without_external_write(self) -> None: + with tempfile.TemporaryDirectory() as temp, tempfile.TemporaryDirectory() as outside_temp: + root = Path(temp) + outside = Path(outside_temp) + init_git(root) + write_lines(root / "legacy.py", 7) try: (root / ".agent-tools").symlink_to(outside, target_is_directory=True) except OSError: