mirror of
https://github.com/JuliusBrussee/caveman.git
synced 2026-08-11 13:21:09 +02:00
- Move caveman-compress/ source (SKILL.md, scripts/, README.md, SECURITY.md) to skills/caveman-compress/. - Delete skills/compress/ — the CI-generated rename mirror that caused dual-source confusion. - Move plugins/caveman/skills/compress/ to plugins/caveman/skills/caveman-compress/. Plugin keeps the consolidated name; CI no longer rewrites the frontmatter. - Replace the two sed-heavy CI sync steps with one verbatim cp -r from source to plugin. - Update verify_repo.py, test_compress_safety.py, test_validate_inline.py, GEMINI.md, AGENTS.md, CONTRIBUTING.md, README.md, and the workflow paths to reference the new location. - Use Path.resolve().parents[N] for the benchmark.py repo-root walk now that the directory depth changed. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
86 lines
3.8 KiB
Python
86 lines
3.8 KiB
Python
"""Tests for the data-loss guards in `compress_file` (issue #237).
|
|
|
|
The compress orchestrator used to overwrite the input even when Claude
|
|
returned an empty string or a no-op echo, and used to write a backup
|
|
without verifying that the bytes survived the round-trip. These tests
|
|
pin the new defensive checks: nothing on disk changes when the compressed
|
|
output is empty or identical to the input, and a backup-write that drops
|
|
bytes is detected before the input is overwritten.
|
|
"""
|
|
|
|
import sys
|
|
import tempfile
|
|
import unittest
|
|
from pathlib import Path
|
|
from unittest import mock
|
|
|
|
REPO_ROOT = Path(__file__).resolve().parent.parent
|
|
sys.path.insert(0, str(REPO_ROOT / "skills" / "caveman-compress"))
|
|
|
|
from scripts import compress as compress_mod # noqa: E402
|
|
|
|
|
|
class CompressSafetyTests(unittest.TestCase):
|
|
def _file_with(self, dirpath: Path, text: str) -> Path:
|
|
path = dirpath / "task.md"
|
|
path.write_text(text)
|
|
return path
|
|
|
|
def test_empty_input_refused(self):
|
|
with tempfile.TemporaryDirectory() as tmp:
|
|
path = self._file_with(Path(tmp), "")
|
|
with mock.patch.object(compress_mod, "call_claude") as call:
|
|
ok = compress_mod.compress_file(path)
|
|
self.assertFalse(ok)
|
|
call.assert_not_called()
|
|
self.assertEqual(path.read_text(), "")
|
|
self.assertFalse((Path(tmp) / "task.original.md").exists())
|
|
|
|
def test_empty_compressed_output_does_not_touch_disk(self):
|
|
with tempfile.TemporaryDirectory() as tmp:
|
|
original = "# Heading\n\nSome long natural language paragraph that should be compressed.\n"
|
|
path = self._file_with(Path(tmp), original)
|
|
with mock.patch.object(compress_mod, "call_claude", return_value=""):
|
|
ok = compress_mod.compress_file(path)
|
|
self.assertFalse(ok)
|
|
self.assertEqual(path.read_text(), original)
|
|
self.assertFalse((Path(tmp) / "task.original.md").exists())
|
|
|
|
def test_whitespace_only_compressed_output_does_not_touch_disk(self):
|
|
with tempfile.TemporaryDirectory() as tmp:
|
|
original = "# Heading\n\nProse that should change.\n"
|
|
path = self._file_with(Path(tmp), original)
|
|
with mock.patch.object(compress_mod, "call_claude", return_value=" \n "):
|
|
ok = compress_mod.compress_file(path)
|
|
self.assertFalse(ok)
|
|
self.assertEqual(path.read_text(), original)
|
|
self.assertFalse((Path(tmp) / "task.original.md").exists())
|
|
|
|
def test_identical_compressed_output_does_not_touch_disk(self):
|
|
with tempfile.TemporaryDirectory() as tmp:
|
|
original = "# Heading\n\nProse.\n"
|
|
path = self._file_with(Path(tmp), original)
|
|
with mock.patch.object(compress_mod, "call_claude", return_value=original):
|
|
ok = compress_mod.compress_file(path)
|
|
self.assertFalse(ok)
|
|
self.assertEqual(path.read_text(), original)
|
|
self.assertFalse((Path(tmp) / "task.original.md").exists())
|
|
|
|
def test_real_compression_writes_backup_and_target(self):
|
|
with tempfile.TemporaryDirectory() as tmp:
|
|
original = "# Heading\n\nThe quick brown fox jumps over the lazy dog.\n"
|
|
compressed = "# Heading\n\nFox jump dog.\n"
|
|
path = self._file_with(Path(tmp), original)
|
|
with mock.patch.object(compress_mod, "call_claude", return_value=compressed), \
|
|
mock.patch.object(compress_mod, "validate") as v:
|
|
v.return_value = mock.Mock(is_valid=True, errors=[], warnings=[])
|
|
ok = compress_mod.compress_file(path)
|
|
self.assertTrue(ok)
|
|
self.assertEqual(path.read_text(), compressed)
|
|
backup = Path(tmp) / "task.original.md"
|
|
self.assertEqual(backup.read_text(), original)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|