test(8.0): re-home orphaned test files into the gate + guard against recurrence
27 test files matched no vitest config, so they never ran in CI and gave false coverage confidence (the drift the audit flagged). - Re-homed 10 functional suites into the gate (renamed to *.unit.test.ts / *.integration.test.ts): Transaction + TransactionManager, type-utils, integrations/core + odata, comprehensive/public-api-complete, regression (metadata-index-cleanup + v5.7.0-deadlock), vfs/tree-operations + vfs-bulkwrite-race. ~192 previously-dark tests now run and pass. - Deleted 8 bit-rotted/redundant files that fail against 8.0 and never ran: one had a literal syntax error; one used filesystem writer-locks that polluted parallel runs; the rest assert old "Brainy 3.0/v3.0" APIs already covered by the live suites (api/batch-operations + crud-operations-enhanced, brainy-3, comprehensive/core-api + find-triple-intelligence, streaming-pipeline, vfs/vfs-relationships, transaction/integration/typeaware-transactions). - Added a coverage guard (tests/unit/test-suite-coverage-guard.test.ts) that FAILS CI if any *.test.ts ever again falls outside every config, with an explicit, conscious MANUAL_ONLY allowlist for the 9 genuine benchmark / perf / model-load files that are run by hand. Gate green: unit 1712, integration 607. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
5f974abc8a
commit
3f9f140c8c
19 changed files with 69 additions and 3658 deletions
|
|
@ -1,394 +0,0 @@
|
|||
/**
|
||||
* Brainy v3.0 Core API Test Suite
|
||||
* Testing all core CRUD operations and basic functionality
|
||||
*/
|
||||
|
||||
import { describe, it, expect, beforeEach, afterEach } from 'vitest'
|
||||
import { Brainy } from '../../src/brainy.js'
|
||||
import { NounType, VerbType } from '../../src/types/graphTypes.js'
|
||||
|
||||
describe('Brainy v3.0 Core API Tests', () => {
|
||||
let brain: Brainy
|
||||
|
||||
beforeEach(async () => {
|
||||
brain = new Brainy({ requireSubtype: false,
|
||||
storage: { type: 'memory' }
|
||||
})
|
||||
await brain.init()
|
||||
})
|
||||
|
||||
afterEach(async () => {
|
||||
// Note: Brainy doesn't have shutdown() in v3, just let GC handle it
|
||||
brain = null as any
|
||||
})
|
||||
|
||||
describe('1. Add Operations', () => {
|
||||
it('should add a simple text item', async () => {
|
||||
const id = await brain.add({
|
||||
data: 'Hello world',
|
||||
type: NounType.Document
|
||||
})
|
||||
|
||||
expect(id).toBeDefined()
|
||||
expect(typeof id).toBe('string')
|
||||
expect(id.length).toBeGreaterThan(0)
|
||||
})
|
||||
|
||||
it('should add item with custom ID', async () => {
|
||||
const customId = 'custom-123'
|
||||
const id = await brain.add({
|
||||
id: customId,
|
||||
data: 'Custom ID test',
|
||||
type: NounType.Document
|
||||
})
|
||||
|
||||
expect(id).toBe(customId)
|
||||
})
|
||||
|
||||
it('should add item with metadata', async () => {
|
||||
const metadata = {
|
||||
title: 'Test Doc',
|
||||
category: 'testing',
|
||||
score: 95.5,
|
||||
tags: ['test', 'validation']
|
||||
}
|
||||
|
||||
const id = await brain.add({
|
||||
data: 'Document with metadata',
|
||||
metadata,
|
||||
type: NounType.Document
|
||||
})
|
||||
|
||||
const retrieved = await brain.get(id)
|
||||
expect(retrieved?.metadata).toEqual(metadata)
|
||||
})
|
||||
|
||||
it('should add item with pre-computed vector', async () => {
|
||||
const vector = new Array(384).fill(0).map(() => Math.random())
|
||||
const id = await brain.add({
|
||||
data: 'Pre-vectorized content',
|
||||
vector,
|
||||
type: NounType.Thing
|
||||
})
|
||||
|
||||
const retrieved = await brain.get(id)
|
||||
expect(retrieved).toBeDefined()
|
||||
expect(retrieved?.vector).toHaveLength(384)
|
||||
})
|
||||
|
||||
it('should handle concurrent adds', async () => {
|
||||
const promises = Array(10).fill(0).map((_, i) =>
|
||||
brain.add({
|
||||
data: `Concurrent item ${i}`,
|
||||
type: NounType.Document
|
||||
})
|
||||
)
|
||||
|
||||
const ids = await Promise.all(promises)
|
||||
expect(ids).toHaveLength(10)
|
||||
expect(new Set(ids).size).toBe(10) // All unique
|
||||
})
|
||||
|
||||
it('should validate noun types', async () => {
|
||||
// Valid type should work
|
||||
const id = await brain.add({
|
||||
data: 'Valid type',
|
||||
type: NounType.Person
|
||||
})
|
||||
expect(id).toBeDefined()
|
||||
|
||||
// Invalid type should throw
|
||||
await expect(brain.add({
|
||||
data: 'Invalid type test',
|
||||
type: 'InvalidType' as any
|
||||
})).rejects.toThrow()
|
||||
})
|
||||
})
|
||||
|
||||
describe('2. Get Operations', () => {
|
||||
let testId: string
|
||||
|
||||
beforeEach(async () => {
|
||||
testId = await brain.add({
|
||||
data: 'Test document for retrieval',
|
||||
metadata: { test: true },
|
||||
type: NounType.Document
|
||||
})
|
||||
})
|
||||
|
||||
it('should retrieve existing item by ID', async () => {
|
||||
const item = await brain.get(testId)
|
||||
|
||||
expect(item).toBeDefined()
|
||||
expect(item?.id).toBe(testId)
|
||||
expect(item?.metadata?.test).toBe(true)
|
||||
expect(item?.type).toBe(NounType.Document)
|
||||
})
|
||||
|
||||
it('should return null for non-existent ID', async () => {
|
||||
const item = await brain.get('non-existent-id')
|
||||
expect(item).toBeNull()
|
||||
})
|
||||
|
||||
it('should retrieve with vector included', async () => {
|
||||
const item = await brain.get(testId)
|
||||
expect(item?.vector).toBeDefined()
|
||||
expect(item?.vector?.length).toBeGreaterThanOrEqual(384) // Default dimension
|
||||
})
|
||||
})
|
||||
|
||||
describe('3. Update Operations', () => {
|
||||
let testId: string
|
||||
|
||||
beforeEach(async () => {
|
||||
testId = await brain.add({
|
||||
data: 'Original content',
|
||||
metadata: { version: 1 },
|
||||
type: NounType.Document
|
||||
})
|
||||
})
|
||||
|
||||
it('should update existing item data', async () => {
|
||||
const success = await brain.update({
|
||||
id: testId,
|
||||
data: 'Updated content'
|
||||
})
|
||||
|
||||
expect(success).toBe(true)
|
||||
|
||||
const updated = await brain.get(testId)
|
||||
expect(updated).toBeDefined()
|
||||
// Vector should be recalculated after content update
|
||||
})
|
||||
|
||||
it('should update only metadata', async () => {
|
||||
const success = await brain.update({
|
||||
id: testId,
|
||||
metadata: { version: 2, updated: true }
|
||||
})
|
||||
|
||||
expect(success).toBe(true)
|
||||
|
||||
const updated = await brain.get(testId)
|
||||
expect(updated?.metadata).toEqual({ version: 2, updated: true })
|
||||
})
|
||||
|
||||
it('should update both data and metadata', async () => {
|
||||
const success = await brain.update({
|
||||
id: testId,
|
||||
data: 'New content',
|
||||
metadata: { version: 3 }
|
||||
})
|
||||
|
||||
expect(success).toBe(true)
|
||||
|
||||
const updated = await brain.get(testId)
|
||||
expect(updated?.metadata?.version).toBe(3)
|
||||
})
|
||||
|
||||
it('should return false for non-existent ID', async () => {
|
||||
const success = await brain.update({
|
||||
id: 'non-existent',
|
||||
data: 'Will fail'
|
||||
})
|
||||
|
||||
expect(success).toBe(false)
|
||||
})
|
||||
})
|
||||
|
||||
describe('4. Delete Operations', () => {
|
||||
it('should delete existing item', async () => {
|
||||
const id = await brain.add({
|
||||
data: 'To be deleted',
|
||||
type: NounType.Document
|
||||
})
|
||||
|
||||
const success = await brain.remove(id)
|
||||
expect(success).toBe(true)
|
||||
|
||||
const item = await brain.get(id)
|
||||
expect(item).toBeNull()
|
||||
})
|
||||
|
||||
it('should return false for non-existent ID', async () => {
|
||||
const success = await brain.remove('non-existent')
|
||||
expect(success).toBe(false)
|
||||
})
|
||||
|
||||
it('should handle concurrent deletes', async () => {
|
||||
const ids = await Promise.all(
|
||||
Array(5).fill(0).map(() =>
|
||||
brain.add({ data: 'Concurrent delete test', type: NounType.Document })
|
||||
)
|
||||
)
|
||||
|
||||
await Promise.all(ids.map(id => brain.remove(id)))
|
||||
// delete returns void, not boolean
|
||||
|
||||
// Verify all deleted
|
||||
const items = await Promise.all(ids.map(id => brain.get(id)))
|
||||
expect(items.every(item => item === null)).toBe(true)
|
||||
})
|
||||
})
|
||||
|
||||
describe('5. Relationship Operations', () => {
|
||||
let entityA: string
|
||||
let entityB: string
|
||||
|
||||
beforeEach(async () => {
|
||||
entityA = await brain.add({ data: 'Entity A', type: NounType.Person })
|
||||
entityB = await brain.add({ data: 'Entity B', type: NounType.Organization })
|
||||
})
|
||||
|
||||
it('should create relationships between entities', async () => {
|
||||
const verbId = await brain.relate({
|
||||
from: entityA,
|
||||
to: entityB,
|
||||
type: VerbType.MemberOf,
|
||||
metadata: { since: '2023' }
|
||||
})
|
||||
|
||||
expect(verbId).toBeDefined()
|
||||
expect(typeof verbId).toBe('string')
|
||||
})
|
||||
|
||||
it('should retrieve relationships', async () => {
|
||||
await brain.relate({
|
||||
from: entityA,
|
||||
to: entityB,
|
||||
type: VerbType.Creates
|
||||
})
|
||||
|
||||
const relations = await brain.related({ from: entityA })
|
||||
|
||||
expect(relations.length).toBeGreaterThanOrEqual(1)
|
||||
expect(relations[0].from).toBe(entityA)
|
||||
})
|
||||
|
||||
it('should delete relationships', async () => {
|
||||
const verbId = await brain.relate({
|
||||
from: entityA,
|
||||
to: entityB,
|
||||
type: VerbType.Owns
|
||||
})
|
||||
|
||||
const success = await brain.unrelate(verbId)
|
||||
expect(success).toBe(true)
|
||||
|
||||
const relations = await brain.related({ from: entityA })
|
||||
const found = relations.find(r => r.id === verbId)
|
||||
expect(found).toBeUndefined()
|
||||
})
|
||||
})
|
||||
|
||||
describe('6. Batch Operations', () => {
|
||||
it('should add multiple items in batch', async () => {
|
||||
const items = Array(10).fill(0).map((_, i) => ({
|
||||
data: `Batch item ${i}`,
|
||||
metadata: { index: i },
|
||||
type: NounType.Document
|
||||
}))
|
||||
|
||||
const result = await brain.addMany({ items })
|
||||
|
||||
expect(result.successful).toHaveLength(10)
|
||||
expect(result.failed).toHaveLength(0)
|
||||
expect(result.total).toBe(10)
|
||||
})
|
||||
|
||||
it('should delete multiple items in batch', async () => {
|
||||
// First add some items
|
||||
const ids = await Promise.all(
|
||||
Array(5).fill(0).map((_, i) =>
|
||||
brain.add({ data: `Delete batch ${i}`, type: NounType.Document })
|
||||
)
|
||||
)
|
||||
|
||||
// Then delete them in batch
|
||||
const result = await brain.removeMany({ ids })
|
||||
|
||||
expect(result.successful).toHaveLength(5)
|
||||
expect(result.failed).toHaveLength(0)
|
||||
})
|
||||
|
||||
it('should handle partial batch failures', async () => {
|
||||
const items = [
|
||||
{ data: 'Valid item', type: NounType.Document },
|
||||
{ data: 'Invalid item', type: 'InvalidType' as any },
|
||||
{ data: 'Another valid', type: NounType.Document }
|
||||
]
|
||||
|
||||
const result = await brain.addMany({
|
||||
items,
|
||||
continueOnError: true
|
||||
})
|
||||
|
||||
expect(result.successful.length).toBeGreaterThanOrEqual(2)
|
||||
expect(result.failed.length).toBeGreaterThanOrEqual(1)
|
||||
})
|
||||
})
|
||||
|
||||
describe('7. Import/Export Operations', () => {
|
||||
it('should export all data', async () => {
|
||||
// Add some test data
|
||||
const id1 = await brain.add({ data: 'Export test 1', type: NounType.Document })
|
||||
const id2 = await brain.add({ data: 'Export test 2', type: NounType.Document })
|
||||
await brain.relate({ from: id1, to: id2, type: VerbType.References })
|
||||
|
||||
const exported = await brain.export()
|
||||
|
||||
expect(exported).toBeDefined()
|
||||
expect(exported.entities).toBeDefined()
|
||||
expect(exported.relationships).toBeDefined()
|
||||
expect(exported.metadata).toBeDefined()
|
||||
})
|
||||
|
||||
it('should import data', async () => {
|
||||
// Create export data
|
||||
const exportData = {
|
||||
entities: [
|
||||
{ id: 'imp-1', data: 'Imported 1', type: NounType.Document, metadata: {} },
|
||||
{ id: 'imp-2', data: 'Imported 2', type: NounType.Document, metadata: {} }
|
||||
],
|
||||
relationships: [],
|
||||
metadata: { version: '3.0.0' }
|
||||
}
|
||||
|
||||
await brain.import(exportData)
|
||||
|
||||
// Verify imported data
|
||||
const item1 = await brain.get('imp-1')
|
||||
const item2 = await brain.get('imp-2')
|
||||
|
||||
expect(item1).toBeDefined()
|
||||
expect(item2).toBeDefined()
|
||||
})
|
||||
})
|
||||
|
||||
describe('8. Statistics and Insights', () => {
|
||||
beforeEach(async () => {
|
||||
// Add some test data
|
||||
await brain.add({ data: 'Doc 1', type: NounType.Document })
|
||||
await brain.add({ data: 'Person 1', type: NounType.Person })
|
||||
await brain.add({ data: 'Org 1', type: NounType.Organization })
|
||||
})
|
||||
|
||||
it('should provide insights', async () => {
|
||||
const insights = await brain.insights()
|
||||
|
||||
expect(insights).toBeDefined()
|
||||
expect(insights.entities).toBeGreaterThanOrEqual(3)
|
||||
expect(insights.types).toBeDefined()
|
||||
expect(Object.keys(insights.types).length).toBeGreaterThan(0)
|
||||
})
|
||||
|
||||
it('should suggest relevant queries', async () => {
|
||||
const suggestions = await brain.suggest({ limit: 3 })
|
||||
|
||||
expect(suggestions).toBeDefined()
|
||||
expect(suggestions.queries).toBeDefined()
|
||||
expect(Array.isArray(suggestions.queries)).toBe(true)
|
||||
expect(suggestions.queries.length).toBeLessThanOrEqual(3)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
@ -1,367 +0,0 @@
|
|||
/**
|
||||
* Brainy v3.0 Find & Triple Intelligence Test Suite
|
||||
* Testing vector search, metadata filtering, and fusion strategies
|
||||
*/
|
||||
|
||||
import { describe, it, expect, beforeAll, afterAll } from 'vitest'
|
||||
import { Brainy } from '../../src/brainy.js'
|
||||
import { NounType, VerbType } from '../../src/types/graphTypes.js'
|
||||
|
||||
describe('Find and Triple Intelligence', () => {
|
||||
let brain: Brainy
|
||||
let testData: any[]
|
||||
|
||||
beforeAll(async () => {
|
||||
brain = new Brainy({ requireSubtype: false,
|
||||
storage: { type: 'memory' }
|
||||
})
|
||||
await brain.init()
|
||||
|
||||
// Add diverse test data
|
||||
testData = [
|
||||
// Technology items
|
||||
{ data: 'JavaScript is a programming language for web development', metadata: { category: 'tech', language: 'javascript', difficulty: 'medium' }, type: NounType.Document },
|
||||
{ data: 'TypeScript adds static typing to JavaScript', metadata: { category: 'tech', language: 'typescript', difficulty: 'advanced' }, type: NounType.Document },
|
||||
{ data: 'Python is great for data science and AI', metadata: { category: 'tech', language: 'python', difficulty: 'easy' }, type: NounType.Document },
|
||||
{ data: 'React is a JavaScript library for building UIs', metadata: { category: 'tech', framework: 'react', language: 'javascript' }, type: NounType.Document },
|
||||
|
||||
// Science items
|
||||
{ data: 'Quantum computing uses quantum mechanics principles', metadata: { category: 'science', field: 'physics', complexity: 'high' }, type: NounType.Concept },
|
||||
{ data: 'Machine learning enables computers to learn from data', metadata: { category: 'science', field: 'ai', complexity: 'medium' }, type: NounType.Concept },
|
||||
{ data: 'Neural networks are inspired by biological brains', metadata: { category: 'science', field: 'ai', complexity: 'high' }, type: NounType.Concept },
|
||||
|
||||
// Business items
|
||||
{ data: 'Market analysis helps understand consumer behavior', metadata: { category: 'business', domain: 'marketing', importance: 'high' }, type: NounType.Process },
|
||||
{ data: 'Project management ensures successful delivery', metadata: { category: 'business', domain: 'management', importance: 'critical' }, type: NounType.Process },
|
||||
{ data: 'Financial planning is essential for growth', metadata: { category: 'business', domain: 'finance', importance: 'critical' }, type: NounType.Process }
|
||||
]
|
||||
|
||||
// Add all test data
|
||||
for (const item of testData) {
|
||||
await brain.add(item)
|
||||
}
|
||||
})
|
||||
|
||||
afterAll(() => {
|
||||
brain = null as any
|
||||
})
|
||||
|
||||
describe('Vector Search', () => {
|
||||
it('should find similar items by text query', async () => {
|
||||
const results = await brain.find({
|
||||
query: 'JavaScript programming',
|
||||
limit: 3
|
||||
})
|
||||
|
||||
expect(results).toHaveLength(3)
|
||||
expect(results[0].score).toBeGreaterThan(0)
|
||||
expect(results[0].score).toBeLessThanOrEqual(1)
|
||||
|
||||
// Should find JavaScript-related items first
|
||||
const topResult = results[0].entity
|
||||
expect(topResult.metadata?.language).toBeDefined()
|
||||
})
|
||||
|
||||
it('should respect limit parameter', async () => {
|
||||
const results = await brain.find({
|
||||
query: 'technology',
|
||||
limit: 5
|
||||
})
|
||||
|
||||
expect(results.length).toBeLessThanOrEqual(5)
|
||||
})
|
||||
|
||||
it('should find by vector directly', async () => {
|
||||
// Get vector from an existing item
|
||||
const jsItem = await brain.find({ query: 'JavaScript', limit: 1 })
|
||||
const vector = jsItem[0].entity.vector
|
||||
|
||||
const results = await brain.find({
|
||||
vector,
|
||||
limit: 3
|
||||
})
|
||||
|
||||
expect(results).toHaveLength(3)
|
||||
// First result should be very similar (same or nearly same vector)
|
||||
expect(results[0].score).toBeGreaterThan(0.9)
|
||||
})
|
||||
|
||||
it('should return all items when no query provided', async () => {
|
||||
const results = await brain.find({})
|
||||
|
||||
expect(results.length).toBeGreaterThanOrEqual(testData.length)
|
||||
})
|
||||
})
|
||||
|
||||
describe('Metadata Filtering', () => {
|
||||
it('should filter by single metadata field', async () => {
|
||||
const results = await brain.find({
|
||||
where: { category: 'tech' }
|
||||
})
|
||||
|
||||
expect(results.length).toBeGreaterThan(0)
|
||||
results.forEach(r => {
|
||||
expect(r.entity.metadata?.category).toBe('tech')
|
||||
})
|
||||
})
|
||||
|
||||
it('should filter by multiple metadata fields', async () => {
|
||||
const results = await brain.find({
|
||||
where: {
|
||||
category: 'tech',
|
||||
language: 'javascript'
|
||||
}
|
||||
})
|
||||
|
||||
results.forEach(r => {
|
||||
expect(r.entity.metadata?.category).toBe('tech')
|
||||
expect(r.entity.metadata?.language).toBe('javascript')
|
||||
})
|
||||
})
|
||||
|
||||
it('should support $gte operator', async () => {
|
||||
const results = await brain.find({
|
||||
where: {
|
||||
importance: { $gte: 'high' }
|
||||
}
|
||||
})
|
||||
|
||||
results.forEach(r => {
|
||||
const importance = r.entity.metadata?.importance
|
||||
if (importance) {
|
||||
expect(['high', 'critical']).toContain(importance)
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
it('should support $contains operator for arrays', async () => {
|
||||
// Add item with array metadata
|
||||
await brain.add({
|
||||
data: 'Test with tags',
|
||||
metadata: { tags: ['test', 'validation', 'qa'] },
|
||||
type: NounType.Document
|
||||
})
|
||||
|
||||
const results = await brain.find({
|
||||
where: {
|
||||
tags: { $contains: 'test' }
|
||||
}
|
||||
})
|
||||
|
||||
const found = results.find(r =>
|
||||
Array.isArray(r.entity.metadata?.tags) &&
|
||||
r.entity.metadata.tags.includes('test')
|
||||
)
|
||||
expect(found).toBeDefined()
|
||||
})
|
||||
|
||||
it('should handle complex nested filters', async () => {
|
||||
const results = await brain.find({
|
||||
where: {
|
||||
$or: [
|
||||
{ category: 'tech', language: 'javascript' },
|
||||
{ category: 'science', field: 'ai' }
|
||||
]
|
||||
}
|
||||
})
|
||||
|
||||
results.forEach(r => {
|
||||
const meta = r.entity.metadata
|
||||
const matchesTech = meta?.category === 'tech' && meta?.language === 'javascript'
|
||||
const matchesScience = meta?.category === 'science' && meta?.field === 'ai'
|
||||
expect(matchesTech || matchesScience).toBe(true)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('Type Filtering', () => {
|
||||
it('should filter by single noun type', async () => {
|
||||
const results = await brain.find({
|
||||
type: NounType.Document
|
||||
})
|
||||
|
||||
results.forEach(r => {
|
||||
expect(r.entity.type).toBe(NounType.Document)
|
||||
})
|
||||
})
|
||||
|
||||
it('should filter by multiple noun types', async () => {
|
||||
const results = await brain.find({
|
||||
type: [NounType.Document, NounType.Concept]
|
||||
})
|
||||
|
||||
results.forEach(r => {
|
||||
expect([NounType.Document, NounType.Concept]).toContain(r.entity.type)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('Combined Search (Triple Intelligence)', () => {
|
||||
it('should combine vector search with metadata filtering', async () => {
|
||||
const results = await brain.find({
|
||||
query: 'programming',
|
||||
where: { category: 'tech' },
|
||||
limit: 5
|
||||
})
|
||||
|
||||
expect(results.length).toBeGreaterThan(0)
|
||||
results.forEach(r => {
|
||||
expect(r.entity.metadata?.category).toBe('tech')
|
||||
})
|
||||
})
|
||||
|
||||
it('should combine vector, metadata, and type filtering', async () => {
|
||||
const results = await brain.find({
|
||||
query: 'artificial intelligence',
|
||||
where: { category: 'science' },
|
||||
type: NounType.Concept,
|
||||
limit: 5
|
||||
})
|
||||
|
||||
results.forEach(r => {
|
||||
expect(r.entity.metadata?.category).toBe('science')
|
||||
expect(r.entity.type).toBe(NounType.Concept)
|
||||
})
|
||||
})
|
||||
|
||||
it('should support fusion strategies', async () => {
|
||||
const results = await brain.find({
|
||||
query: 'JavaScript',
|
||||
where: { category: 'tech' },
|
||||
fusion: {
|
||||
strategy: 'adaptive',
|
||||
weights: { vector: 0.7, field: 0.3 }
|
||||
}
|
||||
})
|
||||
|
||||
expect(results).toBeDefined()
|
||||
expect(results.length).toBeGreaterThan(0)
|
||||
})
|
||||
|
||||
it('should handle fusion with graph intelligence', async () => {
|
||||
// Create some relationships
|
||||
const items = await brain.find({ limit: 3 })
|
||||
if (items.length >= 2) {
|
||||
await brain.relate({
|
||||
from: items[0].id,
|
||||
to: items[1].id,
|
||||
type: VerbType.References
|
||||
})
|
||||
}
|
||||
|
||||
const results = await brain.find({
|
||||
query: 'technology',
|
||||
connected: { to: items[0]?.id },
|
||||
fusion: {
|
||||
strategy: 'adaptive',
|
||||
weights: { vector: 0.5, graph: 0.3, field: 0.2 }
|
||||
}
|
||||
})
|
||||
|
||||
expect(results).toBeDefined()
|
||||
})
|
||||
})
|
||||
|
||||
describe('Performance', () => {
|
||||
it('should handle large result sets efficiently', async () => {
|
||||
const start = Date.now()
|
||||
const results = await brain.find({ limit: 100 })
|
||||
const elapsed = Date.now() - start
|
||||
|
||||
expect(elapsed).toBeLessThan(1000) // Should complete in under 1 second
|
||||
expect(results.length).toBeLessThanOrEqual(100)
|
||||
})
|
||||
|
||||
it('should cache repeated searches', async () => {
|
||||
const query = { query: 'caching test', limit: 5 }
|
||||
|
||||
// First search
|
||||
const results1 = await brain.find(query)
|
||||
|
||||
// Second search (should hit cache)
|
||||
const results2 = await brain.find(query)
|
||||
|
||||
expect(results1).toEqual(results2)
|
||||
// Note: Cache might not always be faster in tests due to overhead
|
||||
// But results should be identical
|
||||
})
|
||||
})
|
||||
|
||||
describe('Edge Cases', () => {
|
||||
it('should handle empty query gracefully', async () => {
|
||||
const results = await brain.find({ query: '' })
|
||||
expect(results).toBeDefined()
|
||||
expect(Array.isArray(results)).toBe(true)
|
||||
})
|
||||
|
||||
it('should handle non-matching filters', async () => {
|
||||
const results = await brain.find({
|
||||
where: { nonExistentField: 'value' }
|
||||
})
|
||||
|
||||
expect(results).toBeDefined()
|
||||
expect(Array.isArray(results)).toBe(true)
|
||||
})
|
||||
|
||||
it('should handle very long queries', async () => {
|
||||
const longQuery = 'test '.repeat(1000) // 5000 characters
|
||||
const results = await brain.find({ query: longQuery, limit: 1 })
|
||||
|
||||
expect(results).toBeDefined()
|
||||
expect(Array.isArray(results)).toBe(true)
|
||||
})
|
||||
|
||||
it('should handle special characters in queries', async () => {
|
||||
const specialQuery = '!@#$%^&*()_+-=[]{}|;\':",./<>?'
|
||||
const results = await brain.find({ query: specialQuery, limit: 1 })
|
||||
|
||||
expect(results).toBeDefined()
|
||||
expect(Array.isArray(results)).toBe(true)
|
||||
})
|
||||
|
||||
it('should handle unicode in queries', async () => {
|
||||
const unicodeQuery = '你好世界 🌍 مرحبا بالعالم'
|
||||
const results = await brain.find({ query: unicodeQuery, limit: 1 })
|
||||
|
||||
expect(results).toBeDefined()
|
||||
expect(Array.isArray(results)).toBe(true)
|
||||
})
|
||||
})
|
||||
|
||||
describe('Similarity Search', () => {
|
||||
it('should find similar items to a given ID', async () => {
|
||||
const items = await brain.find({ limit: 1 })
|
||||
if (items.length > 0) {
|
||||
const results = await brain.similar({
|
||||
to: items[0].id,
|
||||
limit: 3
|
||||
})
|
||||
|
||||
expect(results).toHaveLength(3)
|
||||
// First result might be the item itself
|
||||
results.forEach(r => {
|
||||
expect(r.score).toBeGreaterThanOrEqual(0)
|
||||
expect(r.score).toBeLessThanOrEqual(1)
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
it('should exclude the source item from similar results', async () => {
|
||||
const items = await brain.find({ limit: 1 })
|
||||
if (items.length > 0) {
|
||||
const results = await brain.similar({
|
||||
to: items[0].id,
|
||||
limit: 5
|
||||
})
|
||||
|
||||
// Check if source is excluded (implementation dependent)
|
||||
const selfMatch = results.find(r => r.id === items[0].id)
|
||||
if (selfMatch) {
|
||||
// If included, should be first with score ~1
|
||||
expect(results[0].id).toBe(items[0].id)
|
||||
expect(results[0].score).toBeGreaterThan(0.99)
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
})
|
||||
Loading…
Add table
Add a link
Reference in a new issue