UNPKG

@joystick.js/db-canary

Version:

JoystickDB - A minimalist database server for the Joystick framework

269 lines (205 loc) 9.29 kB
import test from 'ava'; import { initialize_database, cleanup_database } from '../../../src/server/lib/query_engine.js'; import { initialize_index_database, get_indexes, cleanup_index_database } from '../../../src/server/lib/index_manager.js'; import { initialize_auto_index_database, cleanup_auto_index_database } from '../../../src/server/lib/auto_index_manager.js'; import find from '../../../src/server/lib/operations/find.js'; import find_one from '../../../src/server/lib/operations/find_one.js'; import insert_one from '../../../src/server/lib/operations/insert_one.js'; import admin from '../../../src/server/lib/operations/admin.js'; test.beforeEach(async (t) => { initialize_database('./test_data'); initialize_index_database(); initialize_auto_index_database(); const test_documents = [ { name: 'Alice', age: 25, department: 'Engineering', salary: 75000 }, { name: 'Bob', age: 30, department: 'Marketing', salary: 65000 }, { name: 'Charlie', age: 35, department: 'Engineering', salary: 85000 }, { name: 'Diana', age: 28, department: 'Sales', salary: 70000 }, { name: 'Eve', age: 32, department: 'Engineering', salary: 80000 } ]; for (const doc of test_documents) { await insert_one('default', 'employees', doc); } }); test.afterEach(async (t) => { cleanup_auto_index_database(); cleanup_index_database(); await cleanup_database(); }); test('should record query statistics during find operations', async (t) => { await find('default', 'employees', { name: 'Alice' }); await find('default', 'employees', { age: 25 }); await find('default', 'employees', { department: 'Engineering' }); const stats = await admin('get_query_stats', { collection: 'employees' }); t.truthy(stats.name); t.truthy(stats.age); t.truthy(stats.department); t.is(stats.name.query_count, 1); t.is(stats.age.query_count, 1); t.is(stats.department.query_count, 1); }); test('should record query statistics during find_one operations', async (t) => { await find_one('default', 'employees', { name: 'Bob' }); await find_one('default', 'employees', { age: 30 }); const stats = await admin('get_query_stats', { collection: 'employees' }); t.truthy(stats.name); t.truthy(stats.age); t.is(stats.name.query_count, 1); t.is(stats.age.query_count, 1); }); test('should track execution times for queries', async (t) => { await find('default', 'employees', { name: 'Alice' }); await find('default', 'employees', { name: 'Bob' }); await find('default', 'employees', { name: 'Charlie' }); const stats = await admin('get_query_stats', { collection: 'employees' }); t.is(stats.name.query_count, 3); t.true(stats.name.total_time_ms >= 0); t.true(stats.name.avg_time_ms >= 0); t.is(stats.name.avg_time_ms, stats.name.total_time_ms / 3); }); test('should get auto index statistics', async (t) => { const stats = await admin('get_auto_index_stats'); t.is(typeof stats, 'object'); t.is(stats.total_auto_indexes, 0); t.is(typeof stats.collections, 'object'); }); test('should force index evaluation', async (t) => { for (let i = 0; i < 50; i++) { await find('default', 'employees', { name: `User${i}` }); } const result = await admin('evaluate_auto_indexes', { collection: 'employees' }); t.is(result.acknowledged, true); }); test('should force index evaluation for all collections', async (t) => { await find('default', 'employees', { name: 'Alice' }); await find('default', 'products', { category: 'Electronics' }); const result = await admin('evaluate_auto_indexes'); t.is(result.acknowledged, true); }); test('should remove automatic indexes', async (t) => { const result = await admin('remove_auto_indexes', { collection: 'employees', field_names: ['name'] }); t.is(result.acknowledged, true); t.is(typeof result.removed_count, 'number'); }); test('should remove all automatic indexes from collection', async (t) => { const result = await admin('remove_auto_indexes', { collection: 'employees' }); t.is(result.acknowledged, true); t.is(typeof result.removed_count, 'number'); }); test('should handle complex query filters', async (t) => { await find('default', 'employees', { age: { $gte: 25, $lte: 35 }, department: { $in: ['Engineering', 'Marketing'] }, salary: { $gt: 70000 } }); const stats = await admin('get_query_stats', { collection: 'employees' }); t.truthy(stats.age); t.truthy(stats.department); t.truthy(stats.salary); t.is(stats.age.query_count, 1); t.is(stats.department.query_count, 1); t.is(stats.salary.query_count, 1); }); test('should track index usage when indexes exist', async (t) => { await admin('create_index', { collection: 'employees', field: 'name' }); await find('default', 'employees', { name: 'Alice' }); await find('default', 'employees', { name: 'Bob' }); const stats = await admin('get_query_stats', { collection: 'employees' }); t.is(stats.name.query_count, 2); t.is(stats.name.used_index_count, 2); }); test('should differentiate between indexed and non-indexed queries', async (t) => { await admin('create_index', { collection: 'employees', field: 'name' }); await find('default', 'employees', { name: 'Alice' }); await find('default', 'employees', { age: 25 }); const stats = await admin('get_query_stats', { collection: 'employees' }); t.is(stats.name.used_index_count, 1); t.is(stats.age.used_index_count, 0); }); test('should handle queries with projection and sorting', async (t) => { await find('default', 'employees', { department: 'Engineering' }, { projection: { name: 1, salary: 1 }, sort: { salary: -1 }, limit: 2 }); const stats = await admin('get_query_stats', { collection: 'employees' }); t.truthy(stats.department); t.is(stats.department.query_count, 1); }); test('should handle find_one with projection', async (t) => { await find_one('default', 'employees', { name: 'Alice' }, { projection: { age: 1, department: 1 } }); const stats = await admin('get_query_stats', { collection: 'employees' }); t.truthy(stats.name); t.is(stats.name.query_count, 1); }); test('should accumulate statistics across multiple operations', async (t) => { await find('default', 'employees', { name: 'Alice' }); await find_one('default', 'employees', { name: 'Bob' }); await find('default', 'employees', { name: 'Charlie' }); const stats = await admin('get_query_stats', { collection: 'employees' }); t.is(stats.name.query_count, 3); t.true(stats.name.total_time_ms >= 0); }); test('should handle empty result sets', async (t) => { await find('default', 'employees', { name: 'NonExistent' }); await find_one('default', 'employees', { age: 999 }); const stats = await admin('get_query_stats', { collection: 'employees' }); t.truthy(stats.name); t.truthy(stats.age); t.is(stats.name.query_count, 1); t.is(stats.age.query_count, 1); }); test('should handle queries on non-existent collections', async (t) => { await find('default', 'non_existent_collection', { field: 'value' }); const stats = await admin('get_query_stats', { collection: 'non_existent_collection' }); t.truthy(stats.field); t.is(stats.field.query_count, 1); }); test('should track slow queries correctly', async (t) => { for (let i = 0; i < 10; i++) { await find('default', 'employees', { department: 'Engineering' }); } const stats = await admin('get_query_stats', { collection: 'employees' }); t.is(stats.department.query_count, 10); t.true(stats.department.slow_query_count >= 0); }); test('should get statistics for specific collection only', async (t) => { await find('default', 'employees', { name: 'Alice' }); await find('default', 'products', { category: 'Electronics' }); const employee_stats = await admin('get_query_stats', { collection: 'employees' }); const product_stats = await admin('get_query_stats', { collection: 'products' }); t.truthy(employee_stats.name); t.falsy(employee_stats.category); t.truthy(product_stats.category); t.falsy(product_stats.name); }); test('should get statistics for all collections', async (t) => { await find('default', 'employees', { name: 'Alice' }); await find('default', 'products', { category: 'Electronics' }); const all_stats = await admin('get_query_stats'); t.truthy(all_stats.employees); t.truthy(all_stats.products); t.truthy(all_stats.employees.name); t.truthy(all_stats.products.category); }); test('should handle admin operations without errors', async (t) => { await t.notThrowsAsync(async () => { await admin('get_auto_index_stats'); await admin('get_query_stats'); await admin('evaluate_auto_indexes'); await admin('remove_auto_indexes', { collection: 'test' }); }); }); test('should maintain statistics persistence across operations', async (t) => { await find('default', 'employees', { name: 'Alice' }); let stats = await admin('get_query_stats', { collection: 'employees' }); t.is(stats.name.query_count, 1); await find('default', 'employees', { name: 'Bob' }); stats = await admin('get_query_stats', { collection: 'employees' }); t.is(stats.name.query_count, 2); });