| """Integrity guard: matching manifest passes, any change bricks.""" |
|
|
| |
|
|
| from __future__ import annotations |
|
|
| import json |
| from pathlib import Path |
|
|
| import pytest |
|
|
| from affix_huggingface.integrity import ( |
| MANIFEST_NAME, |
| IntegrityError, |
| build_manifest, |
| verify_tree, |
| ) |
|
|
|
|
| def _package(root: Path) -> Path: |
| pkg = root / "pkg" |
| pkg.mkdir() |
| (pkg / "__init__.py").write_text("VALUE = 1\n", encoding="utf-8") |
| (pkg / "core.py").write_text("def run():\n return True\n", encoding="utf-8") |
| (pkg / "py.typed").write_text("\n", encoding="utf-8") |
| return pkg |
|
|
|
|
| def _write_manifest(pkg: Path) -> None: |
| manifest = build_manifest(pkg) |
| (pkg / MANIFEST_NAME).write_text(json.dumps(manifest), encoding="utf-8") |
|
|
|
|
| def test_unbuilt_tree_without_manifest_is_not_enforced(tmp_path: Path) -> None: |
| pkg = _package(tmp_path) |
| verify_tree(pkg) |
|
|
|
|
| def test_matching_manifest_passes(tmp_path: Path) -> None: |
| pkg = _package(tmp_path) |
| _write_manifest(pkg) |
| verify_tree(pkg) |
|
|
|
|
| def test_editing_a_file_bricks(tmp_path: Path) -> None: |
| pkg = _package(tmp_path) |
| _write_manifest(pkg) |
| (pkg / "core.py").write_text("def run():\n return False\n", encoding="utf-8") |
| with pytest.raises(IntegrityError, match="modified"): |
| verify_tree(pkg) |
|
|
|
|
| def test_adding_a_file_bricks(tmp_path: Path) -> None: |
| pkg = _package(tmp_path) |
| _write_manifest(pkg) |
| (pkg / "extra.py").write_text("x = 1\n", encoding="utf-8") |
| with pytest.raises(IntegrityError, match="unexpected"): |
| verify_tree(pkg) |
|
|
|
|
| def test_removing_a_file_bricks(tmp_path: Path) -> None: |
| pkg = _package(tmp_path) |
| _write_manifest(pkg) |
| (pkg / "core.py").unlink() |
| with pytest.raises(IntegrityError, match="missing"): |
| verify_tree(pkg) |
|
|
|
|
| def test_corrupt_manifest_bricks(tmp_path: Path) -> None: |
| pkg = _package(tmp_path) |
| (pkg / MANIFEST_NAME).write_text("{ not json", encoding="utf-8") |
| with pytest.raises(IntegrityError, match="malformed"): |
| verify_tree(pkg) |
|
|
|
|
| def test_manifest_excludes_itself_and_pyc(tmp_path: Path) -> None: |
| pkg = _package(tmp_path) |
| _write_manifest(pkg) |
| cache = pkg / "__pycache__" |
| cache.mkdir() |
| (cache / "core.cpython-312.pyc").write_bytes(b"\x00\x01") |
| verify_tree(pkg) |
|
|