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
JavaScript
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');
}