test(8.0): integration rot pass — 77→17 failures (parallel per-file hardening)
Cleared ~60 rotted-test failures across 17 integration files: get() now passes
{includeVectors:true} where the vector is used; close() teardown added (cures
heartbeat-bleed timeouts); removed-API call-sites rewritten to the 8.0 surface
(addRelationship→relate, COW internals dropped); Result/Entity shape assertions
updated; deterministic-embedder semantic assertions rewritten as self-retrieval
(or moved to Tier-2 where irreducible); perf thresholds relaxed; 384-dim fixtures.
Adds the Tier-2 (real-model) scaffolding: tests/setup-semantic.ts +
tests/configs/vitest.semantic.config.ts + test:semantic; test:ci now runs
unit+integration (anti-rot gate, goes live once green).
Remaining 17 failures are REAL 8.0 library bugs the pass surfaced (fixed next,
not papered over): dual-bound where-filter dropping a bound; counts not
rehydrating after restart; related() offset pagination; relate() non-idempotent
updatedAt; unscoped VFS path-cache. Plus find-unified finish + a few stragglers.
This commit is contained in:
parent
c600468bb5
commit
e5997a1516
20 changed files with 1187 additions and 789 deletions
|
|
@ -99,8 +99,10 @@ describe('Unified Find() Integration Tests', () => {
|
|||
})
|
||||
|
||||
it('should perform vector search by direct vector', async () => {
|
||||
const aliceEntity = await brain.get('alice')
|
||||
// get() is metadata-only by default (vector === []); request the vector explicitly.
|
||||
const aliceEntity = await brain.get('alice', { includeVectors: true })
|
||||
expect(aliceEntity).toBeDefined()
|
||||
expect(aliceEntity!.vector).toHaveLength(384)
|
||||
|
||||
const results = await brain.find({
|
||||
vector: aliceEntity!.vector,
|
||||
|
|
@ -174,11 +176,13 @@ describe('Unified Find() Integration Tests', () => {
|
|||
})
|
||||
|
||||
it('should filter graph results by entity type', async () => {
|
||||
// Filtering traversal RESULTS by NounType is the top-level `type` param composed
|
||||
// with `connected` (GraphConstraints.type/via filter EDGE VerbTypes, not node types).
|
||||
const results = await brain.find({
|
||||
type: NounType.Person,
|
||||
connected: {
|
||||
from: 'alice',
|
||||
direction: 'both',
|
||||
type: 'person' as NounType
|
||||
direction: 'both'
|
||||
},
|
||||
limit: 10
|
||||
})
|
||||
|
|
@ -224,8 +228,9 @@ describe('Unified Find() Integration Tests', () => {
|
|||
})
|
||||
|
||||
it('should filter by numeric comparison', async () => {
|
||||
// 8.0 uses BFO operators (gte/lte/gt/lt), not Mongo-style $gte.
|
||||
const results = await brain.find({
|
||||
where: { age: { $gte: 30 } }
|
||||
where: { age: { gte: 30 } }
|
||||
})
|
||||
|
||||
expect(results.length).toBeGreaterThan(0)
|
||||
|
|
@ -238,15 +243,18 @@ describe('Unified Find() Integration Tests', () => {
|
|||
})
|
||||
|
||||
it('should filter by array contains', async () => {
|
||||
// Add entity with tags
|
||||
// Add entity with a multi-element array field.
|
||||
await brain.add({
|
||||
data: 'Tagged entity',
|
||||
metadata: { tags: ['test', 'integration', 'qa'] },
|
||||
type: NounType.Document
|
||||
})
|
||||
|
||||
// 8.0 uses the BFO `contains` operator for array membership (not Mongo `$contains`).
|
||||
// Correct input: tags = ['test', 'integration', 'qa'], querying for 'test'.
|
||||
// Expected: the entity is returned (its tags array contains 'test').
|
||||
const results = await brain.find({
|
||||
where: { tags: { $contains: 'test' } }
|
||||
where: { tags: { contains: 'test' } }
|
||||
})
|
||||
|
||||
expect(results.length).toBeGreaterThan(0)
|
||||
|
|
@ -257,9 +265,10 @@ describe('Unified Find() Integration Tests', () => {
|
|||
})
|
||||
|
||||
it('should support complex logical operators', async () => {
|
||||
// 8.0 logical operators are anyOf (OR) / allOf (AND) / not, not Mongo $or/$and.
|
||||
const results = await brain.find({
|
||||
where: {
|
||||
$or: [
|
||||
anyOf: [
|
||||
{ name: 'Alice' },
|
||||
{ name: 'Bob' }
|
||||
]
|
||||
|
|
@ -326,7 +335,7 @@ describe('Unified Find() Integration Tests', () => {
|
|||
it('should combine vector search with metadata filtering', async () => {
|
||||
const results = await brain.find({
|
||||
query: 'person',
|
||||
where: { age: { $gte: 25 } },
|
||||
where: { age: { gte: 25 } },
|
||||
limit: 5
|
||||
})
|
||||
|
||||
|
|
@ -358,7 +367,7 @@ describe('Unified Find() Integration Tests', () => {
|
|||
from: 'alice',
|
||||
direction: 'both'
|
||||
},
|
||||
where: { age: { $lte: 30 } },
|
||||
where: { age: { lte: 30 } },
|
||||
limit: 5
|
||||
})
|
||||
|
||||
|
|
@ -375,8 +384,8 @@ describe('Unified Find() Integration Tests', () => {
|
|||
direction: 'both'
|
||||
},
|
||||
where: {
|
||||
age: { $gte: 25 },
|
||||
name: { $ne: 'Alice' } // Exclude Alice
|
||||
age: { gte: 25 },
|
||||
name: { notEquals: 'Alice' } // Exclude Alice
|
||||
},
|
||||
limit: 5
|
||||
})
|
||||
|
|
@ -398,8 +407,8 @@ describe('Unified Find() Integration Tests', () => {
|
|||
direction: 'both'
|
||||
},
|
||||
where: {
|
||||
age: { $gte: 25 },
|
||||
$or: [
|
||||
age: { gte: 25 },
|
||||
anyOf: [
|
||||
{ name: 'Bob' },
|
||||
{ name: 'Charlie' }
|
||||
]
|
||||
|
|
@ -435,14 +444,14 @@ describe('Unified Find() Integration Tests', () => {
|
|||
const results1 = await brain.find({
|
||||
query: 'person social',
|
||||
connected: { from: 'alice' },
|
||||
where: { age: { $gte: 25 } },
|
||||
where: { age: { gte: 25 } },
|
||||
limit: 3
|
||||
})
|
||||
|
||||
const results2 = await brain.find({
|
||||
query: 'person social',
|
||||
connected: { from: 'alice' },
|
||||
where: { age: { $gte: 25 } },
|
||||
where: { age: { gte: 25 } },
|
||||
limit: 3
|
||||
})
|
||||
|
||||
|
|
@ -461,7 +470,7 @@ describe('Unified Find() Integration Tests', () => {
|
|||
it('should implement correct RRF formula', async () => {
|
||||
const results = await brain.find({
|
||||
query: 'person',
|
||||
where: { age: { $gte: 25 } },
|
||||
where: { age: { gte: 25 } },
|
||||
limit: 3
|
||||
})
|
||||
|
||||
|
|
@ -494,19 +503,25 @@ describe('Unified Find() Integration Tests', () => {
|
|||
expect(results1.length).toBe(results2.length)
|
||||
})
|
||||
|
||||
it('should handle different search type weights', async () => {
|
||||
it('should expose fusion provenance on results', async () => {
|
||||
const results = await brain.find({
|
||||
query: 'person',
|
||||
connected: { from: 'alice' },
|
||||
where: { age: { $gte: 25 } },
|
||||
where: { age: { gte: 25 } },
|
||||
limit: 5
|
||||
})
|
||||
|
||||
expect(results.length).toBeGreaterThan(0)
|
||||
// Should have search type metadata
|
||||
// 8.0 Result shape carries fusion provenance: a normalized score, the full entity,
|
||||
// and (for query-driven hybrid search) a matchSource of 'text' | 'semantic' | 'both'.
|
||||
results.forEach((result: any) => {
|
||||
expect(result).toHaveProperty('searchTypes')
|
||||
expect(Array.isArray(result.searchTypes)).toBe(true)
|
||||
expect(result).toHaveProperty('id')
|
||||
expect(result).toHaveProperty('score')
|
||||
expect(result).toHaveProperty('entity')
|
||||
expect(result.score).toBeGreaterThan(0)
|
||||
if (result.matchSource !== undefined) {
|
||||
expect(['text', 'semantic', 'both']).toContain(result.matchSource)
|
||||
}
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
@ -524,7 +539,7 @@ describe('Unified Find() Integration Tests', () => {
|
|||
})
|
||||
|
||||
const fieldResults = await brain.find({
|
||||
where: { age: { $gte: 25 } },
|
||||
where: { age: { gte: 25 } },
|
||||
limit: 3
|
||||
})
|
||||
|
||||
|
|
@ -571,7 +586,7 @@ describe('Unified Find() Integration Tests', () => {
|
|||
const results = await brain.find({
|
||||
query: 'person',
|
||||
connected: { from: 'alice' },
|
||||
where: { age: { $gte: 25 } },
|
||||
where: { age: { gte: 25 } },
|
||||
limit: 3
|
||||
})
|
||||
|
||||
|
|
@ -598,7 +613,7 @@ describe('Unified Find() Integration Tests', () => {
|
|||
const query = {
|
||||
query: 'person social',
|
||||
connected: { from: 'alice' },
|
||||
where: { age: { $gte: 25 } },
|
||||
where: { age: { gte: 25 } },
|
||||
limit: 5
|
||||
}
|
||||
|
||||
|
|
@ -642,7 +657,7 @@ describe('Unified Find() Integration Tests', () => {
|
|||
return brain.find({
|
||||
query: 'person',
|
||||
connected: { from: 'alice' },
|
||||
where: { age: { $gte: 25 } },
|
||||
where: { age: { gte: 25 } },
|
||||
limit: 5
|
||||
})
|
||||
})
|
||||
|
|
@ -679,7 +694,7 @@ describe('Unified Find() Integration Tests', () => {
|
|||
return brain.find({
|
||||
query: 'person',
|
||||
connected: { from: 'alice' },
|
||||
where: { age: { $gte: 25 } },
|
||||
where: { age: { gte: 25 } },
|
||||
limit: 3
|
||||
})
|
||||
})
|
||||
|
|
@ -693,7 +708,7 @@ describe('Unified Find() Integration Tests', () => {
|
|||
it('should use fast paths for single search types', async () => {
|
||||
const vectorQuery = { query: 'person', limit: 3 }
|
||||
const graphQuery = { connected: { from: 'alice' }, limit: 3 }
|
||||
const fieldQuery = { where: { age: { $gte: 25 } }, limit: 3 }
|
||||
const fieldQuery = { where: { age: { gte: 25 } }, limit: 3 }
|
||||
|
||||
const [vectorResults, graphResults, fieldResults] = await Promise.all([
|
||||
measureExecutionTime(() => brain.find(vectorQuery)),
|
||||
|
|
@ -781,7 +796,7 @@ describe('Unified Find() Integration Tests', () => {
|
|||
connected: {
|
||||
from: 'nonexistent_entity' // Should find no results
|
||||
},
|
||||
where: { age: { $gte: 25 } }, // Should find results
|
||||
where: { age: { gte: 25 } }, // Should find results
|
||||
limit: 5
|
||||
})
|
||||
|
||||
|
|
@ -839,11 +854,11 @@ describe('Unified Find() Integration Tests', () => {
|
|||
it('should handle complex metadata queries', async () => {
|
||||
const results = await brain.find({
|
||||
where: {
|
||||
$and: [
|
||||
{ age: { $gte: 20 } },
|
||||
{ age: { $lte: 40 } },
|
||||
allOf: [
|
||||
{ age: { gte: 20 } },
|
||||
{ age: { lte: 40 } },
|
||||
{
|
||||
$or: [
|
||||
anyOf: [
|
||||
{ name: 'Alice' },
|
||||
{ name: 'Bob' },
|
||||
{ name: 'Charlie' }
|
||||
|
|
@ -870,11 +885,11 @@ describe('Unified Find() Integration Tests', () => {
|
|||
const queries = [
|
||||
{ query: 'Alice', limit: 3 },
|
||||
{ connected: { from: 'alice' }, limit: 3 },
|
||||
{ where: { age: { $gte: 25 } }, limit: 3 },
|
||||
{ where: { age: { gte: 25 } }, limit: 3 },
|
||||
{
|
||||
query: 'person',
|
||||
connected: { from: 'alice' },
|
||||
where: { age: { $gte: 25 } },
|
||||
where: { age: { gte: 25 } },
|
||||
limit: 3
|
||||
}
|
||||
]
|
||||
|
|
@ -1045,7 +1060,7 @@ describe('Unified Find() Integration Tests', () => {
|
|||
return brain.find({
|
||||
query: 'person',
|
||||
connected: { from: 'alice' },
|
||||
where: { age: { $gte: 25 } },
|
||||
where: { age: { gte: 25 } },
|
||||
limit: 10
|
||||
})
|
||||
})
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue