@@ -13,7 +13,7 @@ import type { ModelProfile } from "../../core/ModelProfile";
1313import type { VectorBackend } from "../../VectorBackend" ;
1414
1515class TestVectorBackend implements VectorBackend {
16- readonly kind = "test " as const ;
16+ readonly kind = "wasm " as const ;
1717
1818 async dotMany (
1919 query : Float32Array ,
@@ -61,6 +61,44 @@ describe("cortex query (minimal)", () => {
6161 ( globalThis as any ) . IDBKeyRange = FakeIDBKeyRange ;
6262 } ) ;
6363
64+ it ( "returns empty results for an empty corpus" , async ( ) => {
65+ const metadataStore = await IndexedDbMetadataStore . open ( freshDbName ( ) ) ;
66+ const vectorStore = new MemoryVectorStore ( ) ;
67+
68+ const backend = new DeterministicDummyEmbeddingBackend ( { dimension : 4 } ) ;
69+ const vectorBackend = new TestVectorBackend ( ) ;
70+
71+ const runner = new EmbeddingRunner ( async ( ) => ( {
72+ backend,
73+ selectedKind : "dummy" as const ,
74+ reason : "forced" as const ,
75+ supportedKinds : [ "dummy" as const ] ,
76+ measurements : [ ] ,
77+ } ) ) ;
78+
79+ const profile : ModelProfile = {
80+ modelId : "test-model" ,
81+ embeddingDimension : 4 ,
82+ contextWindowTokens : 64 ,
83+ truncationTokens : 48 ,
84+ maxChunkTokens : 5 ,
85+ source : "metadata" ,
86+ } ;
87+
88+ const result = await query ( "anything" , {
89+ modelProfile : profile ,
90+ embeddingRunner : runner ,
91+ vectorStore,
92+ metadataStore,
93+ vectorBackend,
94+ topK : 5 ,
95+ } ) ;
96+
97+ expect ( result . pages ) . toHaveLength ( 0 ) ;
98+ expect ( result . scores ) . toHaveLength ( 0 ) ;
99+ expect ( result . metadata . returned ) . toBe ( 0 ) ;
100+ } ) ;
101+
64102 it ( "returns the most relevant page and updates activity" , async ( ) => {
65103 const metadataStore = await IndexedDbMetadataStore . open ( freshDbName ( ) ) ;
66104 const vectorStore = new MemoryVectorStore ( ) ;
@@ -120,4 +158,60 @@ describe("cortex query (minimal)", () => {
120158 expect ( activity ?. queryHitCount ) . toBe ( 1 ) ;
121159 expect ( activity ?. lastQueryAt ) . toBeDefined ( ) ;
122160 } ) ;
161+
162+ it ( "returns results in descending score order (relevance)" , async ( ) => {
163+ const metadataStore = await IndexedDbMetadataStore . open ( freshDbName ( ) ) ;
164+ const vectorStore = new MemoryVectorStore ( ) ;
165+ const keyPair = await generateKeyPair ( ) ;
166+
167+ const backend = new DeterministicDummyEmbeddingBackend ( { dimension : 4 } ) ;
168+ const vectorBackend = new TestVectorBackend ( ) ;
169+
170+ const runner = new EmbeddingRunner ( async ( ) => ( {
171+ backend,
172+ selectedKind : "dummy" as const ,
173+ reason : "forced" as const ,
174+ supportedKinds : [ "dummy" as const ] ,
175+ measurements : [ ] ,
176+ } ) ) ;
177+
178+ const profile : ModelProfile = {
179+ modelId : "test-model" ,
180+ embeddingDimension : 4 ,
181+ contextWindowTokens : 64 ,
182+ truncationTokens : 48 ,
183+ maxChunkTokens : 5 ,
184+ source : "metadata" ,
185+ } ;
186+
187+ const text = "One two three four five six seven eight nine ten." ;
188+ const ingestResult = await ingestText ( text , {
189+ modelProfile : profile ,
190+ embeddingRunner : runner ,
191+ vectorStore,
192+ metadataStore,
193+ keyPair,
194+ } ) ;
195+
196+ expect ( ingestResult . pages . length ) . toBeGreaterThanOrEqual ( 2 ) ;
197+
198+ const targetPage = ingestResult . pages [ 0 ] ;
199+
200+ const result = await query ( targetPage . content , {
201+ modelProfile : profile ,
202+ embeddingRunner : runner ,
203+ vectorStore,
204+ metadataStore,
205+ vectorBackend,
206+ topK : ingestResult . pages . length ,
207+ } ) ;
208+
209+ // Results must include the page whose content matches the query.
210+ expect ( result . pages . map ( ( p ) => p . pageId ) ) . toContain ( targetPage . pageId ) ;
211+
212+ // Scores must be in non-increasing order.
213+ for ( let i = 1 ; i < result . scores . length ; i ++ ) {
214+ expect ( result . scores [ i ] ) . toBeLessThanOrEqual ( result . scores [ i - 1 ] ) ;
215+ }
216+ } ) ;
123217} ) ;
0 commit comments