tests/test_adapters.py
2.0 KB · 62 lines · python Raw
1 """Tests for InMemoryAdapter."""
2
3 from __future__ import annotations
4
5 import hashlib
6
7 import pytest
8
9 from pqc_rag_signing import ChunkSigner, InMemoryAdapter
10 from pqc_rag_signing.adapters.memory import cosine_similarity
11
12
13 def _embed(text: str, dim: int = 16) -> list[float]:
14 h = hashlib.sha256(text.encode()).digest()
15 return [(b - 128) / 128.0 for b in h[:dim]]
16
17
18 def test_upsert_and_count(signer: ChunkSigner) -> None:
19 chunks = signer.sign_chunks(["a", "b", "c"], source="s.txt")
20 store = InMemoryAdapter()
21 store.upsert(chunks, [_embed(c.text) for c in chunks])
22 assert store.count() == 3
23
24
25 def test_query_returns_top_k(signer: ChunkSigner) -> None:
26 texts = ["quantum computers", "apples are red", "post-quantum crypto"]
27 chunks = signer.sign_chunks(texts, source="s.txt")
28 store = InMemoryAdapter()
29 store.upsert(chunks, [_embed(c.text) for c in chunks])
30 results = store.query(_embed("quantum"), top_k=2)
31 assert len(results) == 2
32 # Confirm result objects are SignedChunks with full envelope
33 for r in results:
34 assert r.signature
35 assert r.public_key
36 assert r.content_hash
37
38
39 def test_query_preserves_chunk_envelope(signer: ChunkSigner) -> None:
40 chunks = signer.sign_chunks(["hello"], source="s.txt")
41 store = InMemoryAdapter()
42 store.upsert(chunks, [_embed(c.text) for c in chunks])
43 [retrieved] = store.query(_embed("hello"), top_k=1)
44 # Verification must still succeed after round-tripping through the store.
45 result = ChunkSigner.verify_chunk(retrieved)
46 assert result.valid
47
48
49 def test_mismatched_embeddings_raises(signer: ChunkSigner) -> None:
50 chunks = signer.sign_chunks(["a", "b"], source="s.txt")
51 store = InMemoryAdapter()
52 with pytest.raises(ValueError):
53 store.upsert(chunks, [_embed("a")])
54
55
56 def test_cosine_similarity_edge_cases() -> None:
57 assert cosine_similarity([], []) == 0.0
58 assert cosine_similarity([1.0, 0.0], [1.0, 0.0, 0.0]) == 0.0
59 # Identical vectors -> 1.0
60 v = [1.0, 2.0, 3.0]
61 assert cosine_similarity(v, v) == pytest.approx(1.0)
62