import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest' import { Brainy } from '../../../src/brainy' import { TripleIntelligenceEngine, TripleQuery, TripleResult } from '../../../src/triple/TripleIntelligence' import { NounType, VerbType } from '../../../src/types/graphTypes' describe('TripleIntelligenceEngine - Comprehensive Coverage', () => { let brain: Brainy let tripleEngine: TripleIntelligenceEngine let testData: Map beforeEach(async () => { brain = new Brainy({ storage: { type: 'memory' } }) await brain.init() tripleEngine = new TripleIntelligenceEngine(brain) testData = new Map() // Create comprehensive test dataset const entities = [ { id: 'person1', data: 'Alice Johnson - Senior Machine Learning Engineer at TechCorp', type: NounType.Person, metadata: { role: 'engineer', level: 'senior', department: 'AI', skills: ['Python', 'TensorFlow', 'PyTorch'], experience: 8, salary: 150000 } }, { id: 'person2', data: 'Bob Smith - Junior Software Developer at StartupCo', type: NounType.Person, metadata: { role: 'developer', level: 'junior', department: 'Engineering', skills: ['JavaScript', 'React', 'Node.js'], experience: 2, salary: 70000 } }, { id: 'person3', data: 'Carol Davis - Principal Data Scientist at DataCorp', type: NounType.Person, metadata: { role: 'scientist', level: 'principal', department: 'Research', skills: ['Python', 'R', 'SQL', 'Spark'], experience: 12, salary: 180000 } }, { id: 'org1', data: 'TechCorp - Leading AI and technology company', type: NounType.Organization, metadata: { industry: 'technology', size: 'large', employees: 5000, revenue: 1000000000, founded: 2010 } }, { id: 'org2', data: 'StartupCo - Innovative fintech startup', type: NounType.Organization, metadata: { industry: 'fintech', size: 'small', employees: 50, revenue: 5000000, founded: 2020 } }, { id: 'org3', data: 'DataCorp - Big data analytics firm', type: NounType.Organization, metadata: { industry: 'analytics', size: 'medium', employees: 500, revenue: 100000000, founded: 2015 } }, { id: 'doc1', data: 'Machine Learning Best Practices - Comprehensive guide to ML', type: NounType.Document, metadata: { category: 'technical', pages: 450, author: 'Alice Johnson', year: 2023, topics: ['ML', 'AI', 'Deep Learning'] } }, { id: 'project1', data: 'Project Apollo - Next-generation AI platform', type: NounType.Project, metadata: { status: 'active', budget: 2000000, team_size: 15, duration_months: 18, technologies: ['Python', 'Kubernetes', 'TensorFlow'] } } ] // Add all entities and store their IDs for (const entity of entities) { const id = await brain.add(entity) testData.set(entity.id, id) } // Add relationships (if graph functionality works) try { await brain.relate({ from: testData.get('person1')!, to: testData.get('org1')!, type: VerbType.WorksFor, metadata: { since: 2018 } }) await brain.relate({ from: testData.get('person2')!, to: testData.get('org2')!, type: VerbType.WorksFor, metadata: { since: 2022 } }) await brain.relate({ from: testData.get('person3')!, to: testData.get('org3')!, type: VerbType.WorksFor, metadata: { since: 2015 } }) await brain.relate({ from: testData.get('person1')!, to: testData.get('doc1')!, type: VerbType.Created, metadata: { date: '2023-01-15' } }) await brain.relate({ from: testData.get('project1')!, to: testData.get('org1')!, type: VerbType.BelongsTo, metadata: { primary: true } }) } catch (error) { console.warn('Graph relationships not available:', error) } }) afterEach(async () => { await brain.close() }) describe('1. Vector Intelligence', () => { it('should find similar items using text similarity', async () => { const query: TripleQuery = { similar: 'artificial intelligence and machine learning', limit: 5 } const results = await tripleEngine.find(query) expect(results).toBeDefined() expect(results.length).toBeGreaterThan(0) expect(results.length).toBeLessThanOrEqual(5) // Should find ML/AI related entities first const topResult = results[0] expect(topResult.fusionScore).toBeGreaterThan(0.5) }) it('should find items using "like" parameter', async () => { const query: TripleQuery = { like: 'data science and analytics', limit: 3 } const results = await tripleEngine.find(query) expect(results).toBeDefined() expect(results.length).toBeLessThanOrEqual(3) // Check that results have proper scores results.forEach(result => { expect(result.fusionScore).toBeDefined() expect(result.fusionScore).toBeGreaterThan(0) expect(result.fusionScore).toBeLessThanOrEqual(1) }) }) it('should handle vector input directly', async () => { // Get vector from an existing entity const entity = await brain.get(testData.get('person1')!) const vector = entity?.vector if (vector) { const query: TripleQuery = { similar: vector, limit: 3 } const results = await tripleEngine.find(query) expect(results).toBeDefined() expect(results.length).toBeGreaterThan(0) // First result should be the same entity (most similar to itself) expect(results[0].id).toBe(testData.get('person1')) } }) }) describe('2. Field Intelligence (Metadata Filtering)', () => { it('should filter by exact field match', async () => { const query: TripleQuery = { where: { level: 'senior' }, limit: 10 } const results = await tripleEngine.find(query) expect(results).toBeDefined() expect(results.length).toBe(1) // Only Alice is senior expect(results[0].id).toBe(testData.get('person1')) }) it('should filter by multiple fields (AND logic)', async () => { const query: TripleQuery = { where: { industry: 'technology', size: 'large' }, limit: 10 } const results = await tripleEngine.find(query) expect(results).toBeDefined() expect(results.length).toBe(1) // Only TechCorp matches both expect(results[0].id).toBe(testData.get('org1')) }) it('should handle range queries (greater than)', async () => { const query: TripleQuery = { where: { experience: { $gt: 5 } }, limit: 10 } const results = await tripleEngine.find(query) expect(results).toBeDefined() expect(results.length).toBe(2) // Alice (8) and Carol (12) const experienceLevels = results.map(r => r.metadata?.experience).filter(Boolean) experienceLevels.forEach(exp => { expect(exp).toBeGreaterThan(5) }) }) it('should handle range queries (between values)', async () => { const query: TripleQuery = { where: { salary: { $gte: 70000, $lte: 160000 } }, limit: 10 } const results = await tripleEngine.find(query) expect(results).toBeDefined() // Bob (70k) and Alice (150k) should match expect(results.length).toBe(2) }) it('should handle array contains queries', async () => { const query: TripleQuery = { where: { skills: { $contains: 'Python' } }, limit: 10 } const results = await tripleEngine.find(query) expect(results).toBeDefined() expect(results.length).toBe(2) // Alice and Carol have Python }) it('should handle OR logic with $in operator', async () => { const query: TripleQuery = { where: { size: { $in: ['small', 'medium'] } }, limit: 10 } const results = await tripleEngine.find(query) expect(results).toBeDefined() expect(results.length).toBe(2) // StartupCo and DataCorp }) }) describe('3. Graph Intelligence (Relationship Queries)', () => { it('should find entities connected to a specific node', async () => { const query: TripleQuery = { connected: { to: testData.get('org1'), // TechCorp direction: 'in' }, limit: 10 } try { const results = await tripleEngine.find(query) expect(results).toBeDefined() // Should find Alice and Project Apollo (connected to TechCorp) expect(results.length).toBeGreaterThanOrEqual(1) } catch (error) { // Graph functionality might not be implemented expect(error).toBeDefined() } }) it('should traverse relationships with specific types', async () => { const query: TripleQuery = { connected: { from: testData.get('person1'), // Alice type: [VerbType.Created, VerbType.WorksFor], direction: 'out' }, limit: 10 } try { const results = await tripleEngine.find(query) expect(results).toBeDefined() // Should find doc1 and org1 if (results.length > 0) { expect(results.length).toBeLessThanOrEqual(2) } } catch (error) { expect(error).toBeDefined() } }) it('should handle multi-hop traversal with depth', async () => { const query: TripleQuery = { connected: { from: testData.get('person1'), maxDepth: 2, direction: 'both' }, limit: 20 } try { const results = await tripleEngine.find(query) expect(results).toBeDefined() // Should find direct and indirect connections } catch (error) { expect(error).toBeDefined() } }) }) describe('4. Fusion Intelligence (Combined Queries)', () => { it('should combine vector and field search', async () => { const query: TripleQuery = { similar: 'software engineering', where: { level: 'junior' }, mode: 'fusion', limit: 5 } const results = await tripleEngine.find(query) expect(results).toBeDefined() // Should prioritize Bob (junior + software developer) if (results.length > 0) { expect(results[0].id).toBe(testData.get('person2')) expect(results[0].vectorScore).toBeDefined() expect(results[0].fieldScore).toBeDefined() expect(results[0].fusionScore).toBeDefined() } }) it('should combine all three intelligence types', async () => { const query: TripleQuery = { similar: 'AI technology', where: { size: 'large' }, connected: { to: testData.get('person1') }, mode: 'fusion', limit: 10 } try { const results = await tripleEngine.find(query) expect(results).toBeDefined() if (results.length > 0) { // Check all score components exist const firstResult = results[0] expect(firstResult.vectorScore).toBeDefined() expect(firstResult.graphScore).toBeDefined() expect(firstResult.fieldScore).toBeDefined() expect(firstResult.fusionScore).toBeDefined() // Fusion score should be weighted combination expect(firstResult.fusionScore).toBeGreaterThan(0) expect(firstResult.fusionScore).toBeLessThanOrEqual(1) } } catch (error) { // Graph might not work expect(error).toBeDefined() } }) }) describe('5. Query Optimization', () => { it('should optimize selective field queries to start with field filter', async () => { const query: TripleQuery = { similar: 'technology', where: { id: testData.get('org1') }, // Very selective explain: true, limit: 1 } const results = await tripleEngine.find(query) if (results.length > 0 && results[0].explanation) { expect(results[0].explanation.plan).toContain('field') // Should start with field filter for efficiency } }) it('should parallelize when beneficial', async () => { const query: TripleQuery = { similar: 'engineering', connected: { to: testData.get('org1') }, explain: true, limit: 10 } const startTime = Date.now() const results = await tripleEngine.find(query) const duration = Date.now() - startTime expect(results).toBeDefined() expect(duration).toBeLessThan(100) // Should be fast due to parallelization if (results.length > 0 && results[0].explanation) { // Check if plan indicates parallel execution expect(results[0].explanation.plan).toBeDefined() } }) it('should handle single-signal optimization', async () => { // Only vector search, no fusion needed const query: TripleQuery = { similar: 'data analysis', limit: 5 } const startTime = Date.now() const results = await tripleEngine.find(query) const duration = Date.now() - startTime expect(results).toBeDefined() expect(duration).toBeLessThan(50) // Should be very fast (no fusion overhead) // Should only have fusion score (which equals vector score) results.forEach(r => { expect(r.fusionScore).toBeDefined() // Should not have separate component scores for single-signal if (!r.graphScore && !r.fieldScore) { expect(r.vectorScore || r.fusionScore).toBeGreaterThan(0) } }) }) }) describe('6. Advanced Features', () => { it('should apply score boosting', async () => { const query: TripleQuery = { similar: 'technology company', boost: 'recent', // Boost recently added items limit: 5 } const results = await tripleEngine.find(query) expect(results).toBeDefined() // Results should be boosted based on recency // (Implementation dependent) }) it('should respect threshold parameter', async () => { const query: TripleQuery = { similar: 'quantum computing', // Unlikely to match well threshold: 0.8, // High threshold limit: 10 } const results = await tripleEngine.find(query) expect(results).toBeDefined() // All results should meet threshold results.forEach(r => { expect(r.fusionScore).toBeGreaterThanOrEqual(0.8) }) }) it('should handle pagination with offset', async () => { const query1: TripleQuery = { similar: 'technology', limit: 2, offset: 0 } const query2: TripleQuery = { similar: 'technology', limit: 2, offset: 2 } const [results1, results2] = await Promise.all([ tripleEngine.find(query1), tripleEngine.find(query2) ]) expect(results1).toBeDefined() expect(results2).toBeDefined() // Results should not overlap const ids1 = new Set(results1.map(r => r.id)) const ids2 = new Set(results2.map(r => r.id)) ids2.forEach(id => { expect(ids1.has(id)).toBe(false) }) }) it('should provide query explanation when requested', async () => { const query: TripleQuery = { similar: 'AI research', where: { experience: { $gt: 5 } }, explain: true, limit: 5 } const results = await tripleEngine.find(query) expect(results).toBeDefined() if (results.length > 0) { const explanation = results[0].explanation if (explanation) { expect(explanation.plan).toBeDefined() expect(explanation.timing).toBeDefined() expect(typeof explanation.timing).toBe('object') if (explanation.boosts) { expect(Array.isArray(explanation.boosts)).toBe(true) } } } }) }) describe('7. Error Handling and Edge Cases', () => { it('should handle empty query gracefully', async () => { const query: TripleQuery = { limit: 5 } const results = await tripleEngine.find(query) expect(results).toBeDefined() expect(Array.isArray(results)).toBe(true) }) it('should handle non-existent field filters', async () => { const query: TripleQuery = { where: { nonExistentField: 'value' }, limit: 10 } const results = await tripleEngine.find(query) expect(results).toBeDefined() expect(results.length).toBe(0) // No matches }) it('should handle invalid connected node IDs', async () => { const query: TripleQuery = { connected: { to: 'invalid-id-12345' }, limit: 10 } try { const results = await tripleEngine.find(query) expect(results).toBeDefined() expect(results.length).toBe(0) // No connections to invalid ID } catch (error) { // Might throw if graph not implemented expect(error).toBeDefined() } }) it('should handle conflicting query modes gracefully', async () => { const query: TripleQuery = { similar: 'test', where: { type: 'Person' }, mode: 'metadata', // Conflicts with vector search limit: 5 } const results = await tripleEngine.find(query) expect(results).toBeDefined() // Should either ignore vector or switch to fusion mode }) }) describe('8. Performance Tests', () => { it('should handle large result sets efficiently', async () => { const query: TripleQuery = { similar: 'technology', limit: 100 // Large limit } const startTime = Date.now() const results = await tripleEngine.find(query) const duration = Date.now() - startTime expect(results).toBeDefined() expect(duration).toBeLessThan(500) // Should still be fast }) it('should cache query plans for repeated queries', async () => { const query: TripleQuery = { similar: 'machine learning', where: { level: 'senior' }, limit: 5 } // First execution const start1 = Date.now() await tripleEngine.find(query) const duration1 = Date.now() - start1 // Second execution (should use cached plan) const start2 = Date.now() await tripleEngine.find(query) const duration2 = Date.now() - start2 // Second should be faster or similar (cached plan) expect(duration2).toBeLessThanOrEqual(duration1 + 10) }) it('should handle concurrent queries', async () => { const queries: TripleQuery[] = [ { similar: 'AI', limit: 5 }, { where: { type: NounType.Person }, limit: 5 }, { similar: 'technology', where: { size: 'large' }, limit: 5 } ] const startTime = Date.now() const results = await Promise.all( queries.map(q => tripleEngine.find(q)) ) const duration = Date.now() - startTime expect(results).toBeDefined() expect(results.length).toBe(3) expect(duration).toBeLessThan(200) // Should handle concurrent queries efficiently results.forEach(resultSet => { expect(Array.isArray(resultSet)).toBe(true) }) }) }) })