Merge pull request #9255 from backstage/rugvip/role-jest

cli: bump to jest 27
This commit is contained in:
Patrik Oldsberg
2022-03-25 13:03:44 +01:00
committed by GitHub
30 changed files with 824 additions and 626 deletions
-1
View File
@@ -108,7 +108,6 @@
"aws-sdk-mock": "^5.2.1",
"better-sqlite3": "^7.5.0",
"http-errors": "^2.0.0",
"jest": "^26.0.1",
"mock-fs": "^5.1.0",
"msw": "^0.35.0",
"mysql2": "^2.2.5",
@@ -14,7 +14,6 @@
* limitations under the License.
*/
import { PassThrough } from 'stream';
import * as winston from 'winston';
/**
@@ -24,6 +23,6 @@ import * as winston from 'winston';
*/
export function getVoidLogger(): winston.Logger {
return winston.createLogger({
transports: [new winston.transports.Stream({ stream: new PassThrough() })],
transports: [new winston.transports.Console({ silent: true })],
});
}
@@ -130,7 +130,7 @@ describe('AzureUrlReader', () => {
{
url: 'com/a/b/blob/master/path/to/c.yaml',
config: createConfig(),
error: 'Invalid URL: com/a/b/blob/master/path/to/c.yaml',
error: 'Invalid URL',
},
{
url: '',
-1
View File
@@ -51,7 +51,6 @@
"@backstage/backend-test-utils": "^0.1.23-next.0",
"@backstage/cli": "^0.16.1-next.0",
"@types/cron": "^1.7.3",
"jest": "^26.0.1",
"wait-for-expect": "^3.0.2"
},
"files": [
@@ -17,10 +17,10 @@
import { getVoidLogger } from '@backstage/backend-common';
import { TestDatabaseId, TestDatabases } from '@backstage/backend-test-utils';
import { Duration } from 'luxon';
import waitForExpect from 'wait-for-expect';
import { migrateBackendTasks } from '../database/migrateBackendTasks';
import { PluginTaskSchedulerImpl } from './PluginTaskSchedulerImpl';
import { ConflictError, NotFoundError } from '@backstage/errors';
import { AbortSignal } from 'node-abort-controller';
jest.useFakeTimers();
@@ -56,6 +56,7 @@ describe('PluginTaskManagerImpl', () => {
const { manager } = await init(databaseId);
const fn = jest.fn();
const promise = new Promise(resolve => fn.mockImplementation(resolve));
await manager.scheduleTask({
id: 'task1',
timeout: Duration.fromMillis(5000),
@@ -63,9 +64,8 @@ describe('PluginTaskManagerImpl', () => {
fn,
});
await waitForExpect(() => {
expect(fn).toBeCalled();
});
await promise;
expect(fn).toHaveBeenCalledWith(expect.any(AbortSignal));
},
60_000,
);
@@ -76,6 +76,7 @@ describe('PluginTaskManagerImpl', () => {
const { manager } = await init(databaseId);
const fn = jest.fn();
const promise = new Promise(resolve => fn.mockImplementation(resolve));
await manager.scheduleTask({
id: 'task2',
timeout: Duration.fromMillis(5000),
@@ -83,9 +84,8 @@ describe('PluginTaskManagerImpl', () => {
fn,
});
await waitForExpect(() => {
expect(fn).toBeCalled();
});
await promise;
expect(fn).toHaveBeenCalledWith(expect.any(AbortSignal));
},
60_000,
);
@@ -98,6 +98,7 @@ describe('PluginTaskManagerImpl', () => {
const { manager } = await init(databaseId);
const fn = jest.fn();
const promise = new Promise(resolve => fn.mockImplementation(resolve));
await manager.scheduleTask({
id: 'task1',
timeout: Duration.fromMillis(5000),
@@ -109,9 +110,8 @@ describe('PluginTaskManagerImpl', () => {
await manager.triggerTask('task1');
jest.advanceTimersByTime(5000);
await waitForExpect(() => {
expect(fn).toBeCalled();
});
await promise;
expect(fn).toHaveBeenCalledWith(expect.any(AbortSignal));
},
60_000,
);
@@ -171,6 +171,7 @@ describe('PluginTaskManagerImpl', () => {
const { manager } = await init(databaseId);
const fn = jest.fn();
const promise = new Promise(resolve => fn.mockImplementation(resolve));
await manager
.createScheduledTaskRunner({
timeout: Duration.fromMillis(5000),
@@ -181,9 +182,8 @@ describe('PluginTaskManagerImpl', () => {
fn,
});
await waitForExpect(() => {
expect(fn).toBeCalled();
});
await promise;
expect(fn).toHaveBeenCalledWith(expect.any(AbortSignal));
},
60_000,
);
@@ -131,11 +131,11 @@ describe('TaskWorker', () => {
cadence: '* * * * * *',
timeoutAfterDuration: Duration.fromMillis(60000).toISO(),
};
const worker = new TaskWorker('task1', fn, knex, logger);
const checkFrequency = Duration.fromObject({ milliseconds: 100 });
const worker = new TaskWorker('task1', fn, knex, logger, checkFrequency);
worker.start(settings);
waitForExpect(() => {
await waitForExpect(() => {
expect(fn).toBeCalledTimes(3);
});
},
+9 -13
View File
@@ -24,7 +24,7 @@ import { TaskFunction, TaskSettingsV2, taskSettingsV2Schema } from './types';
import { delegateAbortController, nowPlus, sleep } from './util';
import { CronTime } from 'cron';
const WORK_CHECK_FREQUENCY = Duration.fromObject({ seconds: 5 });
const DEFAULT_WORK_CHECK_FREQUENCY = Duration.fromObject({ seconds: 5 });
/**
* Performs the actual work of a task.
@@ -32,17 +32,13 @@ const WORK_CHECK_FREQUENCY = Duration.fromObject({ seconds: 5 });
* @private
*/
export class TaskWorker {
private readonly taskId: string;
private readonly fn: TaskFunction;
private readonly knex: Knex;
private readonly logger: Logger;
constructor(taskId: string, fn: TaskFunction, knex: Knex, logger: Logger) {
this.taskId = taskId;
this.fn = fn;
this.knex = knex;
this.logger = logger;
}
constructor(
private readonly taskId: string,
private readonly fn: TaskFunction,
private readonly knex: Knex,
private readonly logger: Logger,
private readonly workCheckFrequency: Duration = DEFAULT_WORK_CHECK_FREQUENCY,
) {}
async start(settings: TaskSettingsV2, options?: { signal?: AbortSignal }) {
try {
@@ -63,7 +59,7 @@ export class TaskWorker {
break;
}
await sleep(WORK_CHECK_FREQUENCY, options?.signal);
await sleep(this.workCheckFrequency, options?.signal);
}
this.logger.info(`Task worker finished: ${this.taskId}`);
} catch (e) {
+1 -2
View File
@@ -46,8 +46,7 @@
"uuid": "^8.0.0"
},
"devDependencies": {
"@backstage/cli": "^0.16.1-next.0",
"jest": "^26.0.1"
"@backstage/cli": "^0.16.1-next.0"
},
"files": [
"dist"
+25
View File
@@ -36,6 +36,25 @@ const transformIgnorePattern = [
'typescript',
].join('|');
// Provides additional config that's based on the role of the target package
function getRoleConfig(role) {
switch (role) {
case 'frontend':
case 'web-library':
case 'common-library':
case 'frontend-plugin':
case 'frontend-plugin-module':
return { testEnvironment: 'jsdom' };
case 'cli':
case 'backend':
case 'node-library':
case 'backend-plugin':
case 'backend-plugin-module':
default:
return { testEnvironment: 'node' };
}
}
async function getProjectConfig(targetPath, displayName) {
const configJsPath = path.resolve(targetPath, 'jest.config.js');
const configTsPath = path.resolve(targetPath, 'jest.config.ts');
@@ -50,6 +69,7 @@ async function getProjectConfig(targetPath, displayName) {
// All configs are merged together to create the final config, with longer paths taking precedence.
// The merging of the configs is shallow, meaning e.g. all transforms are replaced if new ones are defined.
const pkgJsonConfigs = [];
let closestPkgJson = undefined;
let currentPath = targetPath;
// Some sanity check to avoid infinite loop
@@ -59,6 +79,9 @@ async function getProjectConfig(targetPath, displayName) {
if (exists) {
try {
const data = fs.readJsonSync(packagePath);
if (!closestPkgJson) {
closestPkgJson = data;
}
if (data.jest) {
pkgJsonConfigs.unshift(data.jest);
}
@@ -115,6 +138,8 @@ async function getProjectConfig(targetPath, displayName) {
testMatch: ['**/*.test.{js,jsx,ts,tsx,mjs,cjs}'],
transformIgnorePatterns: [`/node_modules/(?:${transformIgnorePattern})/`],
...getRoleConfig(closestPkgJson?.backstage?.role),
};
// Use src/setupTests.ts as the default location for configuring test env
+1 -1
View File
@@ -85,7 +85,7 @@
"handlebars": "^4.7.3",
"html-webpack-plugin": "^5.3.1",
"inquirer": "^8.2.0",
"jest": "^26.0.1",
"jest": "^27.5.1",
"jest-css-modules": "^2.1.0",
"jest-transform-yaml": "^1.0.0",
"json-schema": "^0.4.0",