@travetto/test
Version:
Declarative test framework
89 lines (73 loc) • 2.56 kB
text/typescript
import { EventEmitter } from 'node:events';
import fs from 'node:fs/promises';
import path from 'node:path';
import { Env } from '@travetto/runtime';
import { CliCommandShape, CliCommand, CliValidationError } from '@travetto/cli';
import { WorkPool } from '@travetto/worker';
import { Max, Min } from '@travetto/schema';
/**
* Launch test framework and execute tests
*/
()
export class TestCommand implements CliCommandShape {
/** Output format for test results */
format: string = 'tap';
/** Number of tests to run concurrently */
(1) (WorkPool.MAX_SIZE)
concurrency: number = WorkPool.DEFAULT_SIZE;
/** Test run mode */
mode: 'single' | 'standard' = 'standard';
/**
* Tags to target or exclude
* @alias env.TRV_TEST_TAGS
*/
tags?: string[];
/**
* Format options
* @alias o
*/
formatOptions?: string[];
preMain(): void {
EventEmitter.defaultMaxListeners = 1000;
Env.TRV_ROLE.set('test');
Env.TRV_ENV.set('test');
Env.DEBUG.set(false);
Env.TRV_LOG_PLAIN.set(true);
Env.TRV_LOG_TIME.clear();
}
isFirstFile(first: string): Promise<boolean> {
return fs.stat(path.resolve(first ?? '')).then(x => x.isFile(), () => false);
}
async resolvedMode(first: string, rest: string[]): Promise<string> {
return (await this.isFirstFile(first)) && rest.length === 0 ? 'single' : this.mode;
}
async preValidate(): Promise<void> {
const { selectConsumer } = await import('./bin/run.ts');
await selectConsumer(this);
}
async validate(first: string = '**/*', rest: string[]): Promise<CliValidationError | undefined> {
const mode = await this.resolvedMode(first, rest);
if (mode === 'single' && !await this.isFirstFile(first)) {
return { message: 'You must specify a proper test file to run in single mode', source: 'arg' };
}
}
async main(first: string = '**/*', globs: string[] = []): Promise<void> {
const { runTests } = await import('./bin/run.ts');
const isFirst = await this.isFirstFile(first);
const isSingle = this.mode === 'single' || (isFirst && globs.length === 0);
const options = Object.fromEntries((this.formatOptions ?? [])?.map(f => [...f.split(':'), true]));
return runTests({
concurrency: this.concurrency,
consumer: this.format,
consumerOptions: options,
tags: this.tags,
target: isSingle ?
{
import: first,
classId: globs[0],
methodNames: globs.slice(1),
} :
{ globs: [first, ...globs], }
});
}
}