diff --git a/tests/integration/find-connected-order.test.ts b/tests/integration/find-connected-order.test.ts index b04e7f99..3b7560e4 100644 --- a/tests/integration/find-connected-order.test.ts +++ b/tests/integration/find-connected-order.test.ts @@ -67,6 +67,13 @@ describe('find({ connected }) is graph-first: neighbours → filter → page', ( }) afterAll(async () => { + // CLOSE IT. Dropping the reference does not close a brain — it only makes + // it unreachable from here. The instance stays open and registered, its + // unref'd cadence timer keeps running, and because the gate config runs the + // whole suite in ONE process (pool: 'forks', singleFork: true) it goes on + // narrating its flushes into every test file that runs after this one. + // A test that leaks a brain is a defect of the test. + await brain?.close() brain = null as any }) @@ -137,13 +144,34 @@ describe('find({ connected }) is graph-first: neighbours → filter → page', ( }) it('walks the vector leg over the neighbours only', async () => { + // The SAME query without the vector leg, first. Both legs draw from the + // one neighbour set, so this is the control: it says whether a short answer + // came from the adjacency/filter (both legs short) or from the vector walk + // alone (only the vector leg short). Cheap, and it turns a bare count + // mismatch into a named half — this case has gone red on the gate box + // while passing in isolation and beside its own predecessor, so the next + // red must arrive already carrying the half it belongs to. + const control = await brain.find({ + connected: { from: anchor, direction: 'out' }, + where: { kind: 'note' }, + limit: 5 + }) + const results = await brain.find({ vector: sharedVector, connected: { from: anchor, direction: 'out' }, where: { kind: 'note' }, limit: 5 }) - expect(results).toHaveLength(5) + + expect( + results.length, + `the vector leg returned ${results.length} of a requested 5. The same query ` + + `WITHOUT the vector returned ${control.length}: if that is also short the ` + + `neighbour set or the filter is the cause, and if it is 5 the vector walk is — ` + + `note every row in this corpus carries an identical vector, so the walk is ` + + `ranking an exact tie.` + ).toBe(5) for (const r of results) expect(neighbourIds.has(r.entity.id)).toBe(true) })