build-small-hackathon/hackathon-advisor
16
1from __future__ import annotations2 3from hashlib import sha2564import json5from pathlib import Path6 7from hackathon_advisor.data import Project8from scripts import build_project_index9 10 11def test_build_project_index_reuses_matching_digest_vectors(monkeypatch, tmp_path: Path) -> None:12 project_row = {13 "id": "build-small-hackathon/reused-project",14 "title": "Reused Project",15 "summary": "compact local model demo",16 "tags": ["gradio"],17 "models": [],18 "datasets": [],19 "likes": 0,20 "sdk": "gradio",21 "license": "",22 "created_at": "",23 "last_modified": "",24 "host": "",25 "url": "https://example.test",26 }27 project = Project.from_dict(project_row)28 digest = sha256(project.searchable_text.encode("utf-8")).hexdigest()29 project_path = tmp_path / "projects.json"30 reuse_path = tmp_path / "reuse.json"31 project_path.write_text(32 json.dumps({"generated_at": "2026-06-08T00:00:00+00:00", "source": "test", "projects": [project_row]}),33 encoding="utf-8",34 )35 reuse_path.write_text(36 json.dumps(37 {38 "embedding": {39 "model_repo": "test/repo",40 "model_file": "model.gguf",41 "n_ctx": build_project_index.DEFAULT_N_CTX,42 },43 "documents": [{"project_id": project.id, "text_digest": digest, "vector": [1.0, 0.0, 0.0]}],44 }45 ),46 encoding="utf-8",47 )48 49 def fail_embedder(**_kwargs):50 raise AssertionError("matching digest vectors should not initialize llama.cpp")51 52 monkeypatch.setattr(build_project_index, "LlamaCppEmbedder", fail_embedder)53 54 payload = build_project_index.build_payload(55 project_path,56 model_repo="test/repo",57 model_file="model.gguf",58 build_source="test",59 builder="test",60 reuse_index_path=reuse_path,61 )62 63 assert payload["document_count"] == 164 assert payload["documents"][0]["project_id"] == project.id65 assert payload["documents"][0]["text_digest"] == digest66 assert payload["documents"][0]["vector"] == [1.0, 0.0, 0.0]67 68 69def test_build_project_index_rejects_vectors_when_embedding_config_changes(monkeypatch, tmp_path: Path) -> None:70 project_row = {71 "id": "build-small-hackathon/rebuilt-project",72 "title": "Rebuilt Project",73 "summary": "compact local model demo",74 "tags": ["gradio"],75 "models": [],76 "datasets": [],77 "likes": 0,78 "sdk": "gradio",79 "license": "",80 "created_at": "",81 "last_modified": "",82 "host": "",83 "url": "https://example.test",84 }85 project = Project.from_dict(project_row)86 digest = sha256(project.searchable_text.encode("utf-8")).hexdigest()87 project_path = tmp_path / "projects.json"88 reuse_path = tmp_path / "reuse.json"89 project_path.write_text(90 json.dumps({"generated_at": "2026-06-08T00:00:00+00:00", "source": "test", "projects": [project_row]}),91 encoding="utf-8",92 )93 reuse_path.write_text(94 json.dumps(95 {96 "embedding": {97 "model_repo": "test/repo",98 "model_file": "model.gguf",99 "n_ctx": 768,100 },101 "documents": [{"project_id": project.id, "text_digest": digest, "vector": [1.0, 0.0, 0.0]}],102 }103 ),104 encoding="utf-8",105 )106 107 class FakeEmbedder:108 def __init__(self, **kwargs) -> None:109 assert kwargs["n_ctx"] == 2048110 111 def embed(self, _text: str) -> list[float]:112 return [0.0, 1.0, 0.0]113 114 monkeypatch.setattr(build_project_index, "LlamaCppEmbedder", FakeEmbedder)115 116 payload = build_project_index.build_payload(117 project_path,118 model_repo="test/repo",119 model_file="model.gguf",120 n_ctx=2048,121 build_source="test",122 builder="test",123 reuse_index_path=reuse_path,124 )125 126 assert payload["document_count"] == 1127 assert payload["documents"][0]["project_id"] == project.id128 assert payload["documents"][0]["text_digest"] == digest129 assert payload["documents"][0]["vector"] == [0.0, 1.0, 0.0]130 