import { tap, expect } from '@git.zone/tstest/tapbundle'; import { SmartMigration, SmartMigrationError } from '../ts/index.js'; // Pure-logic tests for the SmartMigration constructor — no database required. tap.test('constructor: rejects empty options', async () => { expect(() => new (SmartMigration as any)()).toThrow(); expect(() => new (SmartMigration as any)(null)).toThrow(); }); tap.test('constructor: requires targetVersion', async () => { expect(() => new SmartMigration({} as any)).toThrow(); }); tap.test('constructor: rejects invalid targetVersion', async () => { let caught: SmartMigrationError | undefined; try { // not a real semver new SmartMigration({ targetVersion: 'not-a-version', db: {} as any }); } catch (err) { caught = err as SmartMigrationError; } expect(caught).toBeInstanceOf(SmartMigrationError); expect(caught!.code).toEqual('INVALID_VERSION'); }); tap.test('constructor: rejects when neither db nor bucket given', async () => { let caught: SmartMigrationError | undefined; try { new SmartMigration({ targetVersion: '1.0.0' }); } catch (err) { caught = err as SmartMigrationError; } expect(caught).toBeInstanceOf(SmartMigrationError); expect(caught!.code).toEqual('NO_RESOURCES'); }); tap.test('constructor: defaults ledgerBackend to "mongo" when db is given', async () => { const m = new SmartMigration({ targetVersion: '1.0.0', db: {} as any, }); expect(m.settings.ledgerBackend).toEqual('mongo'); expect(m.settings.ledgerName).toEqual('smartmigration'); expect(m.settings.lockWaitMs).toEqual(60_000); expect(m.settings.lockTtlMs).toEqual(600_000); expect(m.settings.dryRun).toBeFalse(); }); tap.test('constructor: defaults ledgerBackend to "s3" when only bucket is given', async () => { const m = new SmartMigration({ targetVersion: '1.0.0', bucket: {} as any, }); expect(m.settings.ledgerBackend).toEqual('s3'); }); tap.test('constructor: rejects mongo backend without db', async () => { let caught: SmartMigrationError | undefined; try { new SmartMigration({ targetVersion: '1.0.0', bucket: {} as any, ledgerBackend: 'mongo', }); } catch (err) { caught = err as SmartMigrationError; } expect(caught).toBeInstanceOf(SmartMigrationError); expect(caught!.code).toEqual('LEDGER_BACKEND_MISMATCH'); }); tap.test('constructor: rejects s3 backend without bucket', async () => { let caught: SmartMigrationError | undefined; try { new SmartMigration({ targetVersion: '1.0.0', db: {} as any, ledgerBackend: 's3', }); } catch (err) { caught = err as SmartMigrationError; } expect(caught).toBeInstanceOf(SmartMigrationError); expect(caught!.code).toEqual('LEDGER_BACKEND_MISMATCH'); }); tap.test('step(): rejects empty id', async () => { const m = new SmartMigration({ targetVersion: '1.0.0', db: {} as any }); expect(() => m.step('')).toThrow(); }); export default tap.start();