engram / tests /test_manifest.py
eigengram's picture
test: upload 220 tests
2ece486 verified
"""Tests for kvcos.engram.manifest — knowledge index registry."""
import json
import tempfile
from pathlib import Path
import pytest
from kvcos.engram.manifest import ChunkRecord, Manifest, SourceRecord, _content_hash
@pytest.fixture
def tmp_manifest(tmp_path):
"""Create a Manifest with a temporary path."""
return Manifest.load(tmp_path / "manifest.json")
class TestContentHash:
def test_deterministic(self):
assert _content_hash("hello") == _content_hash("hello")
def test_different_content(self):
assert _content_hash("hello") != _content_hash("world")
class TestManifestLoad:
def test_load_nonexistent_creates_empty(self, tmp_path):
m = Manifest.load(tmp_path / "does_not_exist.json")
assert m.total_sources == 0
assert m.total_chunks == 0
def test_load_existing(self, tmp_path):
# Write a manifest, then load it
m = Manifest.load(tmp_path / "manifest.json")
m = m.register(
source_path="/test/file.md",
content_hash="abc123",
project="test",
file_size=100,
chunks=[ChunkRecord(
eng_path="/test/file.eng",
chunk_index=0,
chunk_total=1,
char_start=0,
char_end=100,
indexed_at=1000.0,
)],
)
# Load again from disk
m2 = Manifest.load(tmp_path / "manifest.json")
assert m2.total_sources == 1
assert m2.total_chunks == 1
class TestManifestRegister:
def test_register_new(self, tmp_manifest):
chunks = [ChunkRecord(
eng_path="/out/test.eng",
chunk_index=0,
chunk_total=1,
char_start=0,
char_end=50,
indexed_at=1000.0,
)]
m = tmp_manifest.register(
source_path="/src/test.md",
content_hash="hash1",
project="myproject",
file_size=50,
chunks=chunks,
)
assert m.total_sources == 1
assert m.total_chunks == 1
assert "myproject" in m.projects
def test_register_overwrites_existing(self, tmp_manifest):
chunks1 = [ChunkRecord(
eng_path="/out/v1.eng", chunk_index=0, chunk_total=1,
char_start=0, char_end=50, indexed_at=1000.0,
)]
m = tmp_manifest.register(
"/src/test.md", "hash1", "proj", 50, chunks1,
)
assert m.total_chunks == 1
chunks2 = [
ChunkRecord("/out/v2_1.eng", 0, 2, 0, 25, 2000.0),
ChunkRecord("/out/v2_2.eng", 1, 2, 25, 50, 2000.0),
]
m = m.register("/src/test.md", "hash2", "proj", 50, chunks2)
assert m.total_sources == 1 # still 1 source
assert m.total_chunks == 2 # now 2 chunks
def test_register_returns_new_manifest(self, tmp_manifest):
"""Register returns a new Manifest (immutability)."""
m1 = tmp_manifest
m2 = m1.register("/src/a.md", "h", "p", 10, [])
assert m1.total_sources == 0 # original unchanged
assert m2.total_sources == 1
class TestManifestNeedsReindex:
def test_unknown_file_needs_index(self, tmp_manifest):
assert tmp_manifest.needs_reindex("/new/file.md", "any_hash")
def test_same_hash_no_reindex(self, tmp_manifest):
m = tmp_manifest.register("/src/a.md", "hash1", "p", 10, [])
assert not m.needs_reindex("/src/a.md", "hash1")
def test_different_hash_needs_reindex(self, tmp_manifest):
m = tmp_manifest.register("/src/a.md", "hash1", "p", 10, [])
assert m.needs_reindex("/src/a.md", "hash2")
class TestManifestUnregister:
def test_unregister_existing(self, tmp_manifest):
m = tmp_manifest.register("/src/a.md", "h", "p", 10, [])
m = m.unregister("/src/a.md")
assert m.total_sources == 0
def test_unregister_nonexistent(self, tmp_manifest):
m = tmp_manifest.unregister("/not/here.md")
assert m.total_sources == 0
class TestManifestQueries:
def test_get_project_records(self, tmp_manifest):
m = tmp_manifest
m = m.register("/a.md", "h1", "proj_a", 10, [])
m = m.register("/b.md", "h2", "proj_b", 20, [])
m = m.register("/c.md", "h3", "proj_a", 30, [])
a_recs = m.get_project_records("proj_a")
assert len(a_recs) == 2
def test_summary(self, tmp_manifest):
m = tmp_manifest.register("/a.md", "h", "p", 10, [
ChunkRecord("/a.eng", 0, 1, 0, 10, 1000.0),
])
s = m.summary()
assert s["total_sources"] == 1
assert s["total_chunks"] == 1
assert "p" in s["projects"]
def test_contains(self, tmp_manifest):
m = tmp_manifest.register("/a.md", "h", "p", 10, [])
assert "/a.md" in m
assert "/b.md" not in m
def test_len(self, tmp_manifest):
m = tmp_manifest.register("/a.md", "h", "p", 10, [])
assert len(m) == 1
class TestManifestPersistence:
def test_atomic_write(self, tmp_path):
m = Manifest.load(tmp_path / "manifest.json")
m = m.register("/a.md", "h", "p", 10, [])
# File should exist
assert (tmp_path / "manifest.json").exists()
# Content should be valid JSON
data = json.loads((tmp_path / "manifest.json").read_text())
assert data["version"] == 1
assert len(data["sources"]) == 1