✅ MAJOR BREAKTHROUGH - Session 5 Success: - Unit tests: 18/19 passing with mocked AI (<500MB RAM) - Integration tests: Real AI models loading successfully - Core features: Real embeddings, CRUD operations verified - Architecture: All 11 augmentations, worker threads operational 📋 CRITICAL FINDINGS: - Real AI models load and cache correctly - 384D embeddings generate properly - Core CRUD operations work with real transformers - Memory management effective for production ⚠️ RELEASE BLOCKER IDENTIFIED: - Search operations timeout in test environment - Affects: search(), find(), clustering functionality - Root cause: Likely worker communication during HNSW search - Priority: MUST fix before 2.0.0 release 🎯 NEXT SESSION PRIORITIES: 1. Debug and fix search timeout issue 2. Verify search/find/clustering work in production 3. Final documentation cleanup 4. Release preparation Confidence: 90% ready (pending search functionality verification)
239 lines
No EOL
8.1 KiB
JavaScript
Executable file
239 lines
No EOL
8.1 KiB
JavaScript
Executable file
#!/usr/bin/env node
|
||
|
||
/**
|
||
* Core Functionality Test - MUST PASS for Release
|
||
*
|
||
* This test verifies ALL core Brainy features work correctly.
|
||
* Uses minimal memory approach to avoid ONNX issues.
|
||
*/
|
||
|
||
import { BrainyData } from './dist/index.js'
|
||
|
||
console.log('🧠 Brainy 2.0 Core Functionality Verification')
|
||
console.log('=' + '='.repeat(55))
|
||
|
||
const tests = {
|
||
passed: 0,
|
||
failed: 0,
|
||
total: 0,
|
||
results: []
|
||
}
|
||
|
||
function test(name, testFn) {
|
||
tests.total++
|
||
return new Promise(async (resolve) => {
|
||
try {
|
||
await testFn()
|
||
console.log(`✅ ${name}`)
|
||
tests.passed++
|
||
tests.results.push({ name, status: 'PASS' })
|
||
resolve(true)
|
||
} catch (error) {
|
||
console.log(`❌ ${name}`)
|
||
console.log(` Error: ${error.message}`)
|
||
tests.failed++
|
||
tests.results.push({ name, status: 'FAIL', error: error.message })
|
||
resolve(false)
|
||
}
|
||
})
|
||
}
|
||
|
||
async function runTests() {
|
||
console.log('📊 Memory before start:')
|
||
const startMem = process.memoryUsage()
|
||
console.log(` Heap: ${(startMem.heapUsed / 1024 / 1024).toFixed(2)} MB`)
|
||
console.log(` RSS: ${(startMem.rss / 1024 / 1024).toFixed(2)} MB`)
|
||
|
||
// Create Brainy instance with custom embedding function to avoid ONNX
|
||
const brain = new BrainyData({
|
||
storage: { forceMemoryStorage: true },
|
||
verbose: false,
|
||
// Use a simple embedding function to avoid ONNX memory issues
|
||
embeddingFunction: async (data) => {
|
||
// Simple deterministic embedding based on text hash
|
||
const str = typeof data === 'string' ? data : JSON.stringify(data)
|
||
const vector = new Array(384).fill(0)
|
||
for (let i = 0; i < str.length && i < 384; i++) {
|
||
vector[i] = (str.charCodeAt(i) % 256) / 256
|
||
}
|
||
// Add some randomness based on string content
|
||
for (let i = 0; i < 384; i++) {
|
||
vector[i] += Math.sin(str.length * i * 0.01) * 0.1
|
||
}
|
||
return vector
|
||
}
|
||
})
|
||
|
||
console.log('\n🚀 Initializing Brainy...')
|
||
await brain.init()
|
||
console.log('✅ Initialization completed')
|
||
|
||
console.log('\n📝 Testing Core Operations...')
|
||
|
||
// Test 1: Basic CRUD Operations
|
||
await test('addNoun() should create items', async () => {
|
||
const id = await brain.addNoun({ name: 'JavaScript', type: 'language', year: 1995 })
|
||
if (typeof id !== 'string' || id.length === 0) {
|
||
throw new Error('addNoun should return non-empty string ID')
|
||
}
|
||
})
|
||
|
||
await test('getNoun() should retrieve items', async () => {
|
||
const id = await brain.addNoun({ name: 'Python', type: 'language', year: 1991 })
|
||
const item = await brain.getNoun(id)
|
||
if (!item || item.metadata?.name !== 'Python') {
|
||
throw new Error('getNoun should return correct item')
|
||
}
|
||
})
|
||
|
||
await test('updateNoun() should modify items', async () => {
|
||
const id = await brain.addNoun({ name: 'TypeScript', type: 'language', year: 2012 })
|
||
await brain.updateNoun(id, { popularity: 'high' })
|
||
const updated = await brain.getNoun(id)
|
||
if (updated?.metadata?.popularity !== 'high') {
|
||
throw new Error('updateNoun should update metadata')
|
||
}
|
||
})
|
||
|
||
await test('deleteNoun() should remove items', async () => {
|
||
const id = await brain.addNoun({ name: 'ToDelete', type: 'test' })
|
||
await brain.deleteNoun(id)
|
||
const deleted = await brain.getNoun(id)
|
||
if (deleted !== null) {
|
||
throw new Error('deleteNoun should remove item completely')
|
||
}
|
||
})
|
||
|
||
// Test 2: Search Operations (with simple embeddings)
|
||
await test('search() should find similar items', async () => {
|
||
// Add some test data
|
||
await brain.addNoun({ name: 'React', type: 'framework', category: 'frontend' })
|
||
await brain.addNoun({ name: 'Vue', type: 'framework', category: 'frontend' })
|
||
await brain.addNoun({ name: 'Express', type: 'framework', category: 'backend' })
|
||
|
||
const results = await brain.search('frontend framework', 5)
|
||
if (!Array.isArray(results) || results.length === 0) {
|
||
throw new Error('search should return array of results')
|
||
}
|
||
})
|
||
|
||
// Test 3: Brain Patterns (Metadata Filtering)
|
||
await test('Brain Patterns should filter by metadata', async () => {
|
||
await brain.addNoun({ name: 'Django', type: 'framework', year: 2005, language: 'Python' })
|
||
await brain.addNoun({ name: 'FastAPI', type: 'framework', year: 2018, language: 'Python' })
|
||
await brain.addNoun({ name: 'Rails', type: 'framework', year: 2004, language: 'Ruby' })
|
||
|
||
const pythonFrameworks = await brain.search('*', 10, {
|
||
metadata: {
|
||
type: 'framework',
|
||
language: 'Python'
|
||
}
|
||
})
|
||
|
||
if (!Array.isArray(pythonFrameworks) || pythonFrameworks.length < 2) {
|
||
throw new Error('Brain Patterns should filter correctly')
|
||
}
|
||
})
|
||
|
||
// Test 4: Range Queries
|
||
await test('Range queries should work', async () => {
|
||
await brain.addNoun({ name: 'OldTech', year: 1990 })
|
||
await brain.addNoun({ name: 'ModernTech1', year: 2015 })
|
||
await brain.addNoun({ name: 'ModernTech2', year: 2020 })
|
||
|
||
const modernItems = await brain.search('*', 10, {
|
||
metadata: {
|
||
year: { greaterThan: 2010 }
|
||
}
|
||
})
|
||
|
||
if (!Array.isArray(modernItems) || modernItems.length < 2) {
|
||
throw new Error('Range queries should filter by year')
|
||
}
|
||
})
|
||
|
||
// Test 5: Statistics
|
||
await test('getStatistics() should provide stats', async () => {
|
||
const stats = await brain.getStatistics()
|
||
if (typeof stats.totalItems !== 'number' || stats.totalItems <= 0) {
|
||
throw new Error('getStatistics should return valid stats')
|
||
}
|
||
})
|
||
|
||
// Test 6: getAllNouns
|
||
await test('getAllNouns() should return all items', async () => {
|
||
const allItems = await brain.getAllNouns()
|
||
if (!Array.isArray(allItems) || allItems.length <= 0) {
|
||
throw new Error('getAllNouns should return array of items')
|
||
}
|
||
})
|
||
|
||
// Test 7: Clear operations
|
||
await test('clearAll() should clear database', async () => {
|
||
await brain.clearAll({ force: true })
|
||
const afterClear = await brain.getAllNouns()
|
||
if (afterClear.length !== 0) {
|
||
throw new Error('clearAll should remove all items')
|
||
}
|
||
})
|
||
|
||
// Test 8: find() method (NLP-style)
|
||
await test('find() should work with natural language', async () => {
|
||
// Add test data
|
||
await brain.addNoun({ name: 'JavaScript', description: 'Popular programming language for web development' })
|
||
await brain.addNoun({ name: 'Python', description: 'Versatile programming language for data science' })
|
||
|
||
const results = await brain.find('programming languages for web development')
|
||
if (!Array.isArray(results)) {
|
||
throw new Error('find should return array of results')
|
||
}
|
||
})
|
||
|
||
// Final memory check
|
||
console.log('\n💾 Final Memory Usage:')
|
||
const endMem = process.memoryUsage()
|
||
console.log(` Heap Used: ${(endMem.heapUsed / 1024 / 1024).toFixed(2)} MB`)
|
||
console.log(` RSS: ${(endMem.rss / 1024 / 1024).toFixed(2)} MB`)
|
||
console.log(` Growth: ${((endMem.heapUsed - startMem.heapUsed) / 1024 / 1024).toFixed(2)} MB`)
|
||
|
||
return tests
|
||
}
|
||
|
||
async function main() {
|
||
try {
|
||
const results = await runTests()
|
||
|
||
console.log('\n' + '='.repeat(56))
|
||
console.log('📊 TEST RESULTS SUMMARY')
|
||
console.log('='.repeat(56))
|
||
console.log(`✅ Passed: ${results.passed}`)
|
||
console.log(`❌ Failed: ${results.failed}`)
|
||
console.log(`📊 Total: ${results.total}`)
|
||
|
||
if (results.failed === 0) {
|
||
console.log('\n🎉 SUCCESS! All core functionality verified!')
|
||
console.log('\n✅ Ready for:')
|
||
console.log(' - CRUD operations (add/get/update/delete)')
|
||
console.log(' - Search with embeddings')
|
||
console.log(' - Brain Patterns metadata filtering')
|
||
console.log(' - Range queries')
|
||
console.log(' - Natural language find()')
|
||
console.log(' - Statistics and monitoring')
|
||
console.log('\n🚀 Brainy 2.0 core is WORKING!')
|
||
process.exit(0)
|
||
} else {
|
||
console.log('\n⚠️ FAILED TESTS:')
|
||
results.results
|
||
.filter(r => r.status === 'FAIL')
|
||
.forEach(r => console.log(` - ${r.name}: ${r.error}`))
|
||
console.log('\n💥 Core functionality has issues - fix before release!')
|
||
process.exit(1)
|
||
}
|
||
} catch (error) {
|
||
console.error('\n💥 Test suite crashed:', error.message)
|
||
console.error(error.stack)
|
||
process.exit(1)
|
||
}
|
||
}
|
||
|
||
main() |