UNPKG

@backstage/backend-test-utils

Version:

Test helpers library for Backstage backends

129 lines (125 loc) 4.16 kB
'use strict'; var isDockerDisabledForTests = require('../util/isDockerDisabledForTests.cjs.js'); var mysql = require('./mysql.cjs.js'); var postgres = require('./postgres.cjs.js'); var sqlite = require('./sqlite.cjs.js'); var types = require('./types.cjs.js'); class TestDatabases { engineFactoryByDriver = { pg: postgres.PostgresEngine.create, mysql: mysql.MysqlEngine.create, mysql2: mysql.MysqlEngine.create, "better-sqlite3": sqlite.SqliteEngine.create, sqlite3: sqlite.SqliteEngine.create }; engineByTestDatabaseId; supportedIds; static defaultIds; /** * Creates an empty `TestDatabases` instance, and sets up Jest to clean up * all of its acquired resources after all tests finish. * * You typically want to create just a single instance like this at the top * of your test file or `describe` block, and then call `init` many times on * that instance inside the individual tests. Spinning up a "physical" * database instance takes a considerable amount of time, slowing down tests. * But initializing a new logical database inside that instance using `init` * is very fast. */ static create(options) { const ids = options?.ids; const disableDocker = options?.disableDocker ?? isDockerDisabledForTests.isDockerDisabledForTests(); let testDatabaseIds; if (ids) { testDatabaseIds = ids; } else if (TestDatabases.defaultIds) { testDatabaseIds = TestDatabases.defaultIds; } else { testDatabaseIds = Object.keys(types.allDatabases); } const supportedIds = testDatabaseIds.filter((id) => { const properties = types.allDatabases[id]; if (!properties) { return false; } if (properties.connectionStringEnvironmentVariableName && process.env[properties.connectionStringEnvironmentVariableName]) { return true; } if (!properties.dockerImageName) { return true; } if (disableDocker) { return false; } return true; }); const databases = new TestDatabases(supportedIds); if (supportedIds.length > 0) { afterAll(async () => { await databases.shutdown(); }); } return databases; } static setDefaults(options) { TestDatabases.defaultIds = options.ids; } constructor(supportedIds) { this.engineByTestDatabaseId = /* @__PURE__ */ new Map(); this.supportedIds = supportedIds; } supports(id) { return this.supportedIds.includes(id); } eachSupportedId() { return this.supportedIds.map((id) => [id]); } /** * Returns a fresh, unique, empty logical database on an instance of the * given database ID platform. * * @param id - The ID of the database platform to use, e.g. 'POSTGRES_13' * @returns A `Knex` connection object */ async init(id) { const properties = types.allDatabases[id]; if (!properties) { const candidates = Object.keys(types.allDatabases).join(", "); throw new Error( `Unknown test database ${id}, possible values are ${candidates}` ); } if (!this.supportedIds.includes(id)) { const candidates = this.supportedIds.join(", "); throw new Error( `Unsupported test database ${id} for this environment, possible values are ${candidates}` ); } let engine = this.engineByTestDatabaseId.get(id); if (!engine) { const factory = this.engineFactoryByDriver[properties.driver]; if (!factory) { throw new Error(`Unknown database driver ${properties.driver}`); } engine = await factory(properties); this.engineByTestDatabaseId.set(id, engine); } return await engine.createDatabaseInstance(); } async shutdown() { const engines = [...this.engineByTestDatabaseId.values()]; this.engineByTestDatabaseId.clear(); for (const engine of engines) { try { await engine.shutdown(); } catch (error) { console.warn(`TestDatabases: Failed to shutdown engine`, { engine, error }); } } } } exports.TestDatabases = TestDatabases; //# sourceMappingURL=TestDatabases.cjs.js.map