79 lines
2.9 KiB
TypeScript
79 lines
2.9 KiB
TypeScript
|
|
import { tap, expect } from '@git.zone/tstest/tapbundle';
|
||
|
|
import { SmartMigration, SmartMigrationError } from '../ts/index.js';
|
||
|
|
|
||
|
|
// Tests for the MigrationStepBuilder fluent chain.
|
||
|
|
|
||
|
|
tap.test('step builder: registers a single step', async () => {
|
||
|
|
const m = new SmartMigration({ targetVersion: '1.0.0', db: {} as any });
|
||
|
|
m.step('a').from('1.0.0').to('1.1.0').up(async () => {});
|
||
|
|
const steps = m.getRegisteredSteps();
|
||
|
|
expect(steps).toHaveLength(1);
|
||
|
|
expect(steps[0].id).toEqual('a');
|
||
|
|
expect(steps[0].fromVersion).toEqual('1.0.0');
|
||
|
|
expect(steps[0].toVersion).toEqual('1.1.0');
|
||
|
|
expect(steps[0].isResumable).toBeFalse();
|
||
|
|
expect(steps[0].description).toBeUndefined();
|
||
|
|
});
|
||
|
|
|
||
|
|
tap.test('step builder: chains multiple steps via the parent', async () => {
|
||
|
|
const m = new SmartMigration({ targetVersion: '2.0.0', db: {} as any });
|
||
|
|
m
|
||
|
|
.step('a').from('1.0.0').to('1.1.0').up(async () => {})
|
||
|
|
.step('b').from('1.1.0').to('1.5.0').up(async () => {})
|
||
|
|
.step('c').from('1.5.0').to('2.0.0').up(async () => {});
|
||
|
|
expect(m.getRegisteredSteps()).toHaveLength(3);
|
||
|
|
expect(m.getRegisteredSteps().map((s) => s.id)).toEqual(['a', 'b', 'c']);
|
||
|
|
});
|
||
|
|
|
||
|
|
tap.test('step builder: stores description and resumable', async () => {
|
||
|
|
const m = new SmartMigration({ targetVersion: '1.1.0', db: {} as any });
|
||
|
|
m
|
||
|
|
.step('with-meta')
|
||
|
|
.from('1.0.0')
|
||
|
|
.to('1.1.0')
|
||
|
|
.description('does important things')
|
||
|
|
.resumable()
|
||
|
|
.up(async () => {});
|
||
|
|
const step = m.getRegisteredSteps()[0];
|
||
|
|
expect(step.description).toEqual('does important things');
|
||
|
|
expect(step.isResumable).toBeTrue();
|
||
|
|
});
|
||
|
|
|
||
|
|
tap.test('step builder: requires .from() before .up()', async () => {
|
||
|
|
const m = new SmartMigration({ targetVersion: '1.0.0', db: {} as any });
|
||
|
|
let caught: SmartMigrationError | undefined;
|
||
|
|
try {
|
||
|
|
(m.step('bad').to('1.1.0') as any).up(async () => {});
|
||
|
|
} catch (err) {
|
||
|
|
caught = err as SmartMigrationError;
|
||
|
|
}
|
||
|
|
expect(caught).toBeInstanceOf(SmartMigrationError);
|
||
|
|
expect(caught!.code).toEqual('STEP_MISSING_FROM');
|
||
|
|
});
|
||
|
|
|
||
|
|
tap.test('step builder: requires .to() before .up()', async () => {
|
||
|
|
const m = new SmartMigration({ targetVersion: '1.0.0', db: {} as any });
|
||
|
|
let caught: SmartMigrationError | undefined;
|
||
|
|
try {
|
||
|
|
(m.step('bad').from('1.0.0') as any).up(async () => {});
|
||
|
|
} catch (err) {
|
||
|
|
caught = err as SmartMigrationError;
|
||
|
|
}
|
||
|
|
expect(caught).toBeInstanceOf(SmartMigrationError);
|
||
|
|
expect(caught!.code).toEqual('STEP_MISSING_TO');
|
||
|
|
});
|
||
|
|
|
||
|
|
tap.test('step builder: rejects non-function handler', async () => {
|
||
|
|
const m = new SmartMigration({ targetVersion: '1.0.0', db: {} as any });
|
||
|
|
let caught: SmartMigrationError | undefined;
|
||
|
|
try {
|
||
|
|
(m.step('bad').from('1.0.0').to('1.1.0') as any).up('not-a-function');
|
||
|
|
} catch (err) {
|
||
|
|
caught = err as SmartMigrationError;
|
||
|
|
}
|
||
|
|
expect(caught).toBeInstanceOf(SmartMigrationError);
|
||
|
|
expect(caught!.code).toEqual('STEP_HANDLER_NOT_FUNCTION');
|
||
|
|
});
|
||
|
|
|
||
|
|
export default tap.start();
|