import { tap, expect } from '@push.rocks/tapbundle'; import { Qenv } from '@push.rocks/qenv'; import * as smartmongo from '@push.rocks/smartmongo'; import { smartunique } from '../ts/plugins.js'; const testQenv = new Qenv(process.cwd(), process.cwd() + '/.nogit/'); console.log(process.memoryUsage()); // the tested module import * as smartdata from '../ts/index.js'; // ======================================= // Connecting to the database server // ======================================= let smartmongoInstance: smartmongo.SmartMongo; let testDb: smartdata.SmartdataDb; const totalCars = 2000; tap.test('should create a testinstance as database', async () => { smartmongoInstance = await smartmongo.SmartMongo.createAndStart(); testDb = new smartdata.SmartdataDb(await smartmongoInstance.getMongoDescriptor()); await testDb.init(); }); tap.skip.test('should connect to atlas', async (tools) => { const databaseName = `test-smartdata-${smartunique.shortId()}`; testDb = new smartdata.SmartdataDb({ mongoDbUrl: await testQenv.getEnvVarOnDemand('MONGO_URL'), mongoDbName: databaseName, }); await testDb.init(); }); @smartdata.Collection(() => testDb) class House extends smartdata.SmartDataDbDoc { @smartdata.unI() public id: string = smartunique.shortId(); @smartdata.svDb() public data = { id: smartunique.shortId(), hello: 'hello', }; } tap.test('should watch a collection', async (toolsArg) => { const done = toolsArg.defer(); const watcher = await House.watch({}); watcher.changeSubject.subscribe(async (houseArg) => { console.log('hey there, we observed a house'); await watcher.close(); done.resolve(); }); const newHouse = new House(); await newHouse.save(); console.log('saved a house'); await done.promise; }); // ======= New tests for EventEmitter and buffering support ======= tap.test('should emit change via EventEmitter', async (tools) => { const done = tools.defer(); const watcher = await House.watch({}); watcher.on('change', async (houseArg) => { // Expect a House instance expect(houseArg).toBeDefined(); // Clean up await watcher.stop(); done.resolve(); }); // Trigger an insert to generate a change event const h = new House(); await h.save(); await done.promise; }); tap.test('should buffer change events when bufferTimeMs is set', async (tools) => { const done = tools.defer(); // bufferTimeMs collects events into arrays every 50ms const watcher = await House.watch({}, { bufferTimeMs: 50 }); let received: House[]; watcher.changeSubject.subscribe(async (batch: House[]) => { if (batch && batch.length > 0) { received = batch; await watcher.stop(); done.resolve(); } }); // Rapidly insert multiple docs const docs = [new House(), new House(), new House()]; for (const doc of docs) await doc.save(); await done.promise; // All inserts should be in one buffered batch expect(received.length).toEqual(docs.length); }); // ======================================= // close the database connection // ======================================= tap.test('close', async () => { try { await testDb.mongoDb.dropDatabase(); } catch (err) { console.warn('dropDatabase error ignored in cleanup:', err.message || err); } await testDb.close(); if (smartmongoInstance) { await smartmongoInstance.stop(); } }); tap.start({ throwOnError: true });