npm package diff
Package: @forge/sql
Versions: 2.0.1-next.1 - 2.1.0-next.2
File: package/out/__test__/migration.test.js
Index: package/out/__test__/migration.test.js
===================================================================
--- package/out/__test__/migration.test.js
+++ package/out/__test__/migration.test.js
@@ -0,0 +1,121 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+const migration_1 = require("../migration");
+const sql_1 = require("../sql");
+const errorCodes_1 = require("../errorCodes");
+const jest_when_1 = require("jest-when");
+const sql_statement_1 = require("../sql-statement");
+jest.mock('../sql');
+describe('Migration', () => {
+ let migrationRunner;
+ let mockSqlClient;
+ beforeEach(() => {
+ mockSqlClient = new sql_1.SqlClient();
+ migrationRunner = new migration_1.MigrationRunner(mockSqlClient);
+ });
+ afterEach(() => {
+ jest.clearAllMocks();
+ });
+ describe('enqueueMigration', () => {
+ const versionOne = 'v001_create_table_testtest';
+ it('should store just one migration with the same name already exists', () => {
+ const createTableTest = 'CREATE TABLE test (id INT)';
+ migrationRunner.enqueue(versionOne, createTableTest);
+ migrationRunner.enqueue(versionOne, createTableTest);
+ expect(migrationRunner.getEnqueued().length).toBe(1);
+ expect(migrationRunner.getEnqueued()[0].name).toBe(versionOne);
+ expect(migrationRunner.getEnqueued()[0].statement).toBe(createTableTest);
+ });
+ it('should not throw an error if a migration names are unique, even when sql statements with the same name already exists', () => {
+ const versionTwo = 'v002_alter_table_test_add_column_foo';
+ migrationRunner.enqueue(versionOne, 'CREATE TABLE IF NOT EXISTS test (id INT)');
+ migrationRunner.enqueue(versionTwo, 'ALTER TABLE test ADD COLUMN foo BOOLEAN DEFAULT FALSE;');
+ expect(migrationRunner.getEnqueued().length).toBe(2);
+ expect(migrationRunner.getEnqueued()[0].name).toBe(versionOne);
+ expect(migrationRunner.getEnqueued()[1].name).toBe(versionTwo);
+ });
+ });
+ describe('list', () => {
+ it('should list all previously migrations', async () => {
+ const migratedAtDate = new Date();
+ mockSqlClient.executeRaw.mockResolvedValueOnce({
+ rows: [{ id: 1, name: 'create-table-test', migratedAt: migratedAtDate }]
+ });
+ const migrations = await migrationRunner.list();
+ expect(migrations.length).toBe(1);
+ expect(migrations[0]).toEqual({ id: 1, name: 'create-table-test', migratedAt: migratedAtDate });
+ expect(mockSqlClient.executeRaw).toHaveBeenCalledWith('SELECT id, name, migratedAt FROM __migrations;');
+ });
+ it('should be empty when no previous migrations exist', async () => {
+ mockSqlClient.executeRaw.mockResolvedValueOnce({
+ rows: []
+ });
+ const migrations = await migrationRunner.list();
+ expect(migrations.length).toBe(0);
+ expect(mockSqlClient.executeRaw).toHaveBeenCalledWith('SELECT id, name, migratedAt FROM __migrations;');
+ });
+ it('should raise an error when schema version table does not exist', async () => {
+ const tableDoesNotExistError = new Error(errorCodes_1.errorCodes.SQL_EXECUTION_ERROR);
+ mockSqlClient.executeRaw.mockRejectedValue(tableDoesNotExistError);
+ await expect(migrationRunner.list()).rejects.toThrow(tableDoesNotExistError);
+ });
+ });
+ describe('run', () => {
+ const insertMigrationVersionQueryTemplate = 'INSERT INTO __migrations (name) VALUES (?);';
+ const CREATE_TABLE_FOO_QUERY = 'CREATE TABLE IF NOT EXISTS foo (id INT);';
+ const CREATE_TABLE_BAR_QUERY = 'CREATE TABLE IF NOT EXISTS bar (id INT);';
+ afterEach(() => {
+ (0, jest_when_1.verifyAllWhenMocksCalled)();
+ (0, jest_when_1.resetAllWhenMocks)();
+ });
+ describe('when few migrations have been successfully run in the past', () => {
+ it('should execute migrations that have not been previously run', async () => {
+ migrationRunner.enqueue('v_001_create_table_foo', CREATE_TABLE_FOO_QUERY);
+ migrationRunner.enqueue('v_002_create_table_bar', CREATE_TABLE_BAR_QUERY);
+ (0, jest_when_1.when)(mockSqlClient.executeRaw)
+ .calledWith((0, jest_when_1.when)((arg) => arg.startsWith('CREATE TABLE IF NOT EXISTS __migrations')))
+ .mockResolvedValue({ rows: [] });
+ (0, jest_when_1.when)(mockSqlClient.executeRaw)
+ .calledWith('SELECT id, name, migratedAt FROM __migrations;')
+ .mockResolvedValue({
+ rows: [{ name: 'v_001_create_table_foo', statement: CREATE_TABLE_FOO_QUERY, migratedAt: new Date() }]
+ });
+ const mockApiCall = jest.fn();
+ (0, jest_when_1.when)(mockApiCall)
+ .expectCalledWith(insertMigrationVersionQueryTemplate, (0, jest_when_1.when)((arg) => arg[0] === 'v_002_create_table_bar'))
+ .mockResolvedValue({});
+ (0, jest_when_1.when)(mockSqlClient.prepare)
+ .calledWith(insertMigrationVersionQueryTemplate)
+ .mockReturnValue(new sql_statement_1.SqlStatement(insertMigrationVersionQueryTemplate, mockApiCall));
+ const result = await migrationRunner.run();
+ expect(result).toEqual(['v_002_create_table_bar']);
+ expect(mockSqlClient.prepare).toHaveBeenCalledTimes(1);
+ expect(mockSqlClient.executeRaw).toHaveBeenCalledTimes(3);
+ });
+ });
+ describe('when no migrations have been run in the past', () => {
+ it('should execute migrations that have not been previously run', async () => {
+ const CREATE_TABLE_FOO_QUERY = 'CREATE TABLE IF NOT EXISTS foo (id INT)';
+ migrationRunner.enqueue('v_001_create_table_foo', CREATE_TABLE_FOO_QUERY);
+ migrationRunner.enqueue('v_002_create_table_bar', 'CREATE TABLE IF NOT EXISTS bar (id INT)');
+ (0, jest_when_1.when)(mockSqlClient.executeRaw).calledWith('SELECT id, name, migratedAt FROM __migrations;').mockResolvedValue({
+ rows: []
+ });
+ (0, jest_when_1.when)(mockSqlClient.executeRaw)
+ .calledWith((0, jest_when_1.when)((arg) => arg.startsWith('CREATE TABLE IF NOT EXISTS __migrations')))
+ .mockResolvedValue({ rows: [] });
+ const mockApiCall = jest.fn();
+ (0, jest_when_1.when)(mockApiCall)
+ .expectCalledWith(insertMigrationVersionQueryTemplate, (0, jest_when_1.when)((arg) => arg[0] === 'v_001_create_table_foo' || arg[0] === 'v_002_create_table_bar'))
+ .mockResolvedValue({});
+ (0, jest_when_1.when)(mockSqlClient.prepare)
+ .calledWith(insertMigrationVersionQueryTemplate)
+ .mockReturnValue(new sql_statement_1.SqlStatement(insertMigrationVersionQueryTemplate, mockApiCall));
+ const result = await migrationRunner.run();
+ expect(result).toEqual(['v_001_create_table_foo', 'v_002_create_table_bar']);
+ expect(mockSqlClient.prepare).toHaveBeenCalledTimes(2);
+ expect(mockSqlClient.executeRaw).toHaveBeenCalledTimes(4);
+ });
+ });
+ });
+});