UNPKG

bigbasealpha

Version:

Professional Grade Custom Database System - A sophisticated, dependency-free database with encryption, caching, indexing, and web dashboard

682 lines (540 loc) 21.7 kB
import { test, describe } from 'node:test'; import assert from 'node:assert'; import { existsSync } from 'fs'; import { rm } from 'fs/promises'; import { mkdirSync } from 'fs'; import BigBaseAlpha from '../src/alpha.js'; describe('BigBaseAlpha Core Tests', () => { let db; const testPath = './test_db'; async function setup() { // Clean up previous test data if (existsSync(testPath)) { await rm(testPath, { recursive: true }); } // Klasör yoksa oluştur try { mkdirSync(testPath, { recursive: true }); } catch (e) {} db = new BigBaseAlpha({ path: testPath, format: 'json', encryption: false, caching: true, indexing: true, auditLog: false, streaming: { enabled: false }, apiGateway: { enabled: false }, blockchain: { enabled: false }, eventSourcing: { enabled: false } }); await db.init(); } // Cleanup after each test async function cleanup() { if (db) { await db.close(); } if (existsSync(testPath)) { await rm(testPath, { recursive: true }); } } test('Database initialization', async () => { await setup(); assert.ok(db.isInitialized, 'Database should be initialized'); assert.ok(existsSync(testPath), 'Database directory should exist'); await cleanup(); }); test('Collection creation', async () => { try { await setup(); const result = await db.createCollection('users'); assert.ok(result, 'Collection creation should return success'); const collections = db.listCollections(); assert.ok(collections.includes('users'), 'Users collection should exist'); await cleanup(); } catch (error) { console.error('\n❌ Collection creation test failed:'); console.error('Error:', error.message); console.error('Stack:', error.stack); throw error; } }); test('Document insertion', async () => { try { await setup(); await db.createCollection('users'); const userData = { name: 'John Doe', email: 'john@example.com', age: 30 }; const inserted = await db.insert('users', userData); assert.ok(inserted._id, 'Document should have an ID'); assert.strictEqual(inserted.name, userData.name); assert.strictEqual(inserted.email, userData.email); assert.ok(inserted._created, 'Document should have creation timestamp'); await cleanup(); } catch (error) { console.error('\n❌ Document insertion test failed:'); console.error('Error:', error.message); console.error('Stack:', error.stack); throw error; } }); test('Document retrieval', async () => { try { await setup(); await db.createCollection('users'); const userData = { name: 'Jane Doe', email: 'jane@example.com' }; const inserted = await db.insert('users', userData); const retrieved = await db.findOne('users', { _id: inserted._id }); assert.ok(retrieved, 'Document should be found'); assert.strictEqual(retrieved._id, inserted._id); assert.strictEqual(retrieved.name, userData.name); await cleanup(); } catch (error) { console.error('\n❌ Document retrieval test failed:'); console.error('Error:', error.message); console.error('Stack:', error.stack); throw error; } }); test('Document update', async () => { await setup(); await db.createCollection('users'); const userData = { name: 'Bob Smith', email: 'bob@example.com', age: 25 }; const inserted = await db.insert('users', userData); const updates = { age: 26, city: 'New York' }; const updated = await db.update('users', inserted._id, updates); assert.strictEqual(updated.age, 26); assert.strictEqual(updated.city, 'New York'); assert.strictEqual(updated.name, userData.name); // Should preserve existing fields assert.ok(updated._modified > updated._created); // Should update modification time await cleanup(); }); test('Document deletion', async () => { await setup(); await db.createCollection('users'); const userData = { name: 'Alice Johnson', email: 'alice@example.com' }; const inserted = await db.insert('users', userData); const deleted = await db.delete('users', inserted._id); assert.ok(deleted, 'Delete should return true'); const retrieved = await db.findOne('users', { _id: inserted._id }); assert.strictEqual(retrieved, null, 'Document should no longer exist'); await cleanup(); }); test('Query operations', async () => { await setup(); await db.createCollection('products'); // Insert test data const products = [ { name: 'Laptop', category: 'Electronics', price: 999, inStock: true }, { name: 'Phone', category: 'Electronics', price: 599, inStock: true }, { name: 'Chair', category: 'Furniture', price: 199, inStock: false }, { name: 'Desk', category: 'Furniture', price: 299, inStock: true } ]; for (const product of products) { await db.insert('products', product); } // Test equality query const electronics = await db.find('products', { category: 'Electronics' }); assert.strictEqual(electronics.length, 2); // Test range query const affordableItems = await db.find('products', { price: { $lt: 300 } }); assert.strictEqual(affordableItems.length, 2); // Test compound query const availableElectronics = await db.find('products', { category: 'Electronics', inStock: true }); assert.strictEqual(availableElectronics.length, 2); // Test sorting const sortedByPrice = await db.find('products', {}, { sort: { price: 1 } }); assert.strictEqual(sortedByPrice[0].name, 'Chair'); // Cheapest first // Test limiting const firstTwo = await db.find('products', {}, { limit: 2 }); assert.strictEqual(firstTwo.length, 2); await cleanup(); }); test('Schema validation', async () => { await setup(); const schema = { name: { type: 'string', required: true }, email: { type: 'string', required: true }, age: { type: 'number' } }; await db.createCollection('users', schema); // Valid data should work const validUser = { name: 'John', email: 'john@example.com', age: 30 }; const inserted = await db.insert('users', validUser); assert.ok(inserted._id); // Missing required field should fail try { await db.insert('users', { email: 'incomplete@example.com' }); assert.fail('Should have thrown validation error'); } catch (error) { assert.ok(error.message.toLowerCase().includes('required')); } // Wrong type should fail try { await db.insert('users', { name: 'John', email: 'john@example.com', age: 'thirty' }); assert.fail('Should have thrown validation error'); } catch (error) { assert.ok(error.message.includes('type')); } await cleanup(); }); test('Statistics tracking', async () => { await setup(); await db.createCollection('test'); const initialStats = db.getStats(); assert.strictEqual(initialStats.totalInserts, 0); assert.strictEqual(initialStats.totalReads, 0); // Perform operations const doc = await db.insert('test', { data: 'test' }); await db.findOne('test', { _id: doc._id }); await db.update('test', doc._id, { data: 'updated' }); const finalStats = db.getStats(); assert.strictEqual(finalStats.totalInserts, 1); assert.ok(finalStats.totalReads > 0); assert.strictEqual(finalStats.totalUpdates, 1); assert.ok(finalStats.totalOperations > 0); await cleanup(); }); test('Backup and restore', async () => { await setup(); await db.createCollection('backup_test'); // Add some data const testData = [ { name: 'Item 1', value: 100 }, { name: 'Item 2', value: 200 } ]; for (const item of testData) { await db.insert('backup_test', item); } // Create backup const backupPath = './test_backup.bba'; const createdPath = await db.backup(backupPath); assert.ok(existsSync(createdPath), 'Backup file should exist'); // Clean up backup file if (existsSync(backupPath)) { await rm(backupPath); } await cleanup(); }); test('Concurrent operations', async () => { await setup(); await db.createCollection('concurrent_test'); // Perform multiple operations concurrently const operations = []; for (let i = 0; i < 10; i++) { operations.push(db.insert('concurrent_test', { value: i })); } const results = await Promise.all(operations); // All operations should succeed assert.strictEqual(results.length, 10); results.forEach((result, index) => { assert.ok(result._id); assert.strictEqual(result.value, index); }); // Verify all documents are in collection const allDocs = await db.find('concurrent_test'); assert.strictEqual(allDocs.length, 10); await cleanup(); }); }); describe('Security Tests', () => { let db; const testPath = './security_test_db'; async function setup() { if (existsSync(testPath)) { await rm(testPath, { recursive: true }); } // Klasör yoksa oluştur try { mkdirSync(testPath, { recursive: true }); } catch (e) {} db = new BigBaseAlpha({ path: testPath, encryption: true, auditLog: false, streaming: { enabled: false }, apiGateway: { enabled: false }, blockchain: { enabled: false }, eventSourcing: { enabled: false } }); await db.init(); } async function cleanup() { if (db) { await db.close(); } if (existsSync(testPath)) { await rm(testPath, { recursive: true }); } } test('Password hashing', async () => { await setup(); const password = 'mySecretPassword123'; const hash = await db.security.hash(password); assert.ok(hash); assert.notStrictEqual(hash, password); assert.ok(hash.length > 20); // Verify password const isValid = await db.security.verifyHash(password, hash); assert.ok(isValid); // Wrong password should not verify const isInvalid = await db.security.verifyHash('wrongPassword', hash); assert.strictEqual(isInvalid, false); await cleanup(); }); test('API key generation and validation', async () => { await setup(); const apiKey = db.security.generateApiKey(); assert.ok(apiKey); assert.ok(apiKey.startsWith('bba_')); // Should validate correctly const isValid = db.security.validateApiKey(apiKey); assert.ok(isValid); // Invalid key should not validate const isInvalid = db.security.validateApiKey('invalid_key'); assert.strictEqual(isInvalid, false); await cleanup(); }); test('Document encryption', async () => { await setup(); await db.createCollection('secure_data'); const sensitiveData = { username: 'testuser', password: 'secret123', apiKey: 'sk_test_12345', publicInfo: 'This is not sensitive' }; const inserted = await db.insert('secure_data', sensitiveData); // Sensitive fields should be encrypted in storage assert.ok(inserted._encrypted); // When retrieved, should be decrypted const retrieved = await db.findOne('secure_data', { _id: inserted._id }); assert.strictEqual(retrieved.username, sensitiveData.username); assert.strictEqual(retrieved.password, sensitiveData.password); assert.strictEqual(retrieved.publicInfo, sensitiveData.publicInfo); await cleanup(); }); }); describe('Performance Tests', () => { let db; const testPath = './perf_test_db'; async function setup() { if (existsSync(testPath)) { await rm(testPath, { recursive: true }); } // Klasör yoksa oluştur try { mkdirSync(testPath, { recursive: true }); } catch (e) {} db = new BigBaseAlpha({ path: testPath, caching: true, indexing: true, auditLog: false, streaming: { enabled: false }, apiGateway: { enabled: false }, blockchain: { enabled: false }, eventSourcing: { enabled: false } }); await db.init(); } async function cleanup() { if (db) { await db.close(); } if (existsSync(testPath)) { await rm(testPath, { recursive: true }); } } test('Bulk insert performance', async () => { await setup(); await db.createCollection('perf_test', { id: { type: 'number', index: true }, name: { type: 'string', index: true }, category: { type: 'string', index: true } }); const startTime = Date.now(); const batchSize = 1000; // Insert documents in batches const operations = []; for (let i = 0; i < batchSize; i++) { operations.push(db.insert('perf_test', { id: i, name: `Item ${i}`, category: `Category ${i % 10}`, data: `This is test data for item ${i}` })); } await Promise.all(operations); const endTime = Date.now(); const duration = endTime - startTime; const opsPerSecond = Math.round((batchSize / duration) * 1000); console.log(` Bulk insert: ${batchSize} documents in ${duration}ms (${opsPerSecond} ops/sec)`); // Verify all documents were inserted const count = await db.find('perf_test'); assert.strictEqual(count.length, batchSize); await cleanup(); }); test('Query performance with indexing', async () => { await setup(); await db.createCollection('query_test', { category: { type: 'string', index: true }, value: { type: 'number', index: true } }); // Insert test data const testData = []; for (let i = 0; i < 1000; i++) { testData.push({ category: `cat_${i % 10}`, value: Math.floor(Math.random() * 1000), description: `Description for item ${i}` }); } // Bulk insert for (const item of testData) { await db.insert('query_test', item); } // Test indexed query performance const startTime = Date.now(); const results = await db.find('query_test', { category: 'cat_5' }); const endTime = Date.now(); const queryTime = endTime - startTime; console.log(` Indexed query: ${results.length} results in ${queryTime}ms`); // Should be reasonably fast assert.ok(queryTime < 100, `Query took ${queryTime}ms, should be under 100ms`); assert.ok(results.length > 0, 'Should find matching documents'); await cleanup(); }); test('Cache performance', async () => { await setup(); await db.createCollection('cache_test'); // Insert test document const testDoc = { name: 'Cache Test', data: 'Large data payload '.repeat(100) }; const inserted = await db.insert('cache_test', testDoc); // First read (cache miss) const start1 = Date.now(); const result1 = await db.findOne('cache_test', { _id: inserted._id }); const time1 = Date.now() - start1; // Second read (cache hit) const start2 = Date.now(); const result2 = await db.findOne('cache_test', { _id: inserted._id }); const time2 = Date.now() - start2; console.log(` Cache miss: ${time1}ms, Cache hit: ${time2}ms`); // Cache hit should be faster assert.ok(time2 <= time1, 'Cache hit should be faster than cache miss'); assert.deepStrictEqual(result1, result2, 'Results should be identical'); // Check cache stats const cacheStats = db.cache.getStats(); assert.ok(cacheStats.hits > 0, 'Should have cache hits'); assert.ok(cacheStats.hitRate > 0, 'Should have positive hit rate'); await cleanup(); }); describe('Blockchain Integration', () => { test('should initialize blockchain engine', async () => { await setup(); assert.ok(db.blockchainEngine, 'Blockchain engine should be initialized'); assert.strictEqual(typeof db.createBlockchainWallet, 'function'); assert.strictEqual(typeof db.sendBlockchainTransaction, 'function'); await cleanup(); }); test('should create blockchain wallet', async () => { await setup(); const wallet = await db.createBlockchainWallet('test-wallet'); assert.ok(wallet.address, 'Wallet should have address'); assert.ok(wallet.privateKey, 'Wallet should have private key'); assert.ok(wallet.publicKey, 'Wallet should have public key'); assert.ok(/^0x[a-fA-F0-9]{40}$/.test(wallet.address), 'Address should be valid format'); await cleanup(); }); test('should get blockchain statistics', async () => { await setup(); const stats = await db.getBlockchainStats(); assert.ok(stats.totalBlocks !== undefined, 'Should have total blocks'); assert.ok(stats.totalTransactions !== undefined, 'Should have total transactions'); assert.ok(stats.networkHashRate !== undefined, 'Should have network hash rate'); assert.ok(stats.difficulty !== undefined, 'Should have difficulty'); await cleanup(); }); test('should deploy smart contract', async () => { await setup(); const wallet = await db.createBlockchainWallet('contract-owner'); const contract = await db.deploySmartContract( wallet.address, 'SimpleStorage', 'contract SimpleStorage { uint256 value; }' ); assert.ok(contract.address, 'Contract should have address'); assert.ok(contract.deploymentHash, 'Contract should have deployment hash'); assert.ok(/^0x[a-fA-F0-9]{40}$/.test(contract.address), 'Contract address should be valid format'); await cleanup(); }); test('should mint NFT', async () => { await setup(); const wallet = await db.createBlockchainWallet('nft-owner'); const nft = await db.mintNFT( wallet.address, 'Test NFT', 'A test NFT', 'https://example.com/nft.json' ); assert.ok(nft.tokenId, 'NFT should have token ID'); assert.ok(nft.owner, 'NFT should have owner'); assert.ok(nft.metadata, 'NFT should have metadata'); assert.strictEqual(nft.owner, wallet.address, 'NFT owner should match wallet address'); await cleanup(); }); test('should create staking pool', async () => { await setup(); const pool = await db.createStakingPool('TEST', 365, 10.5, 1000000); assert.ok(pool.poolId, 'Pool should have ID'); assert.ok(pool.token, 'Pool should have token'); assert.ok(pool.duration, 'Pool should have duration'); assert.strictEqual(pool.token, 'TEST', 'Pool token should match'); assert.strictEqual(pool.apr, 10.5, 'Pool APR should match'); await cleanup(); }); test('should create liquidity pool', async () => { await setup(); const pool = await db.createLiquidityPool('ETH', 'USDC', 1000, 3000000); assert.ok(pool.poolAddress, 'Pool should have address'); assert.ok(pool.tokenA, 'Pool should have token A'); assert.ok(pool.tokenB, 'Pool should have token B'); assert.strictEqual(pool.tokenA, 'ETH', 'Token A should match'); assert.strictEqual(pool.tokenB, 'USDC', 'Token B should match'); await cleanup(); }); test('should create governance proposal', async () => { await setup(); const wallet = await db.createBlockchainWallet('proposer'); const proposal = await db.createGovernanceProposal( wallet.address, 'Test Proposal', 'A test governance proposal', 30 ); assert.ok(proposal.proposalId, 'Proposal should have ID'); assert.ok(proposal.title, 'Proposal should have title'); assert.ok(proposal.proposer, 'Proposal should have proposer'); assert.strictEqual(proposal.proposer, wallet.address, 'Proposer should match wallet address'); await cleanup(); }); test('should mine block', async () => { await setup(); const wallet = await db.createBlockchainWallet('miner'); const block = await db.mineBlock(wallet.address); assert.ok(block.index !== undefined, 'Block should have index'); assert.ok(block.hash, 'Block should have hash'); assert.ok(block.miner, 'Block should have miner'); assert.strictEqual(block.miner, wallet.address, 'Miner should match wallet address'); await cleanup(); }); }); }); // Run tests if this file is executed directly if (import.meta.url === `file://${process.argv[1]}`) { console.log('🧪 Running BigBaseAlpha Tests...\n'); }