import { tap, expect } from '@git.zone/tstest/tapbundle'; import * as smartmongo from '@push.rocks/smartmongo'; import * as smartdata from '../ts/index.js'; /** * Regression tests for: * * 1. CollectionFactory per-db cache (previously keyed by class name * alone, which made two SmartdataDb instances share a single * collection bound to whichever db happened to request it first). * 2. EasyStore.replace() — new atomic-replace method that clears keys * not present in the new object. EasyStore.writeAll() still merges * for backward compatibility. */ let smartmongoInstance: smartmongo.SmartMongo; let dbA: smartdata.SmartdataDb; let dbB: smartdata.SmartdataDb; tap.test('setup: two dbs against the same replica set', async () => { smartmongoInstance = await smartmongo.SmartMongo.createAndStart(); const desc = await smartmongoInstance.getMongoDescriptor(); dbA = new smartdata.SmartdataDb({ ...desc, mongoDbName: 'cf_test_a' }); dbB = new smartdata.SmartdataDb({ ...desc, mongoDbName: 'cf_test_b' }); await dbA.init(); await dbB.init(); }); tap.test('CollectionFactory: same class name in two dbs yields two collections', async () => { const easyA = await dbA.createEasyStore<{ marker: string }>('shared'); const easyB = await dbB.createEasyStore<{ marker: string }>('shared'); await easyA.writeKey('marker', 'A'); await easyB.writeKey('marker', 'B'); const fromA = await easyA.readKey('marker'); const fromB = await easyB.readKey('marker'); expect(fromA).toEqual('A'); // Under the old singleton bug, this would be 'A' because the second // createEasyStore() call would receive the collection bound to dbA. expect(fromB).toEqual('B'); }); tap.test('EasyStore.replace: drops keys not present in the new object', async () => { const store = await dbA.createEasyStore<{ a?: string; b?: string }>('replace_test'); await store.writeKey('a', '1'); await store.writeKey('b', '2'); expect(await store.readKey('a')).toEqual('1'); expect(await store.readKey('b')).toEqual('2'); await store.replace({ a: 'only-a' }); expect(await store.readKey('a')).toEqual('only-a'); // `b` must be gone — this is the whole point of replace() over writeAll(). expect(await store.readKey('b')).toBeUndefined(); }); tap.test('EasyStore.writeAll: still merges (back-compat)', async () => { const store = await dbA.createEasyStore<{ a?: string; b?: string }>('merge_test'); await store.writeAll({ a: '1' }); await store.writeAll({ b: '2' }); expect(await store.readKey('a')).toEqual('1'); expect(await store.readKey('b')).toEqual('2'); }); tap.test('teardown', async () => { await dbA.mongoDb.dropDatabase(); await dbB.mongoDb.dropDatabase(); await dbA.close(); await dbB.close(); await smartmongoInstance.stop(); }); export default tap.start();