@tsdi/unit
Version:
unit testing framework, base on AOP, Ioc container
1,020 lines (1,005 loc) • 34.6 kB
JavaScript
import { createClassDecorator, isString, isNumber, createMethodDecorator, isArray, tokenId, Abstract, lang, PromiseUtil, Injectable, Refs, Destoryable, isFunction, Inject, INJECTOR, Singleton, isClass, IocExt, DesignRegisterer, RuntimeRegisterer, RegSingletionAction, DecoratorProvider, InjectReference, isToken } from '@tsdi/ioc';
import { __decorate, __awaiter, __metadata, __param } from 'tslib';
import { Runnable, Startup, ApplicationExit, BuilderService, AnnoationAction, BootContext, ConfigureRegister, createContext, DIModule, BootApplication } from '@tsdi/boot';
import { AfterThrowing, Joinpoint, Around, Aspect, JoinpointState, AopModule } from '@tsdi/aop';
import { LoggerAspect, LogModule } from '@tsdi/logs';
import { ContainerToken } from '@tsdi/core';
import * as assert from 'assert';
import * as expect from 'expect';
/**
* create filed decorator.
*
* @export
* @template T
* @param {string} [SuiteType]
* @param {ArgsIteratorAction<T>[]} [actions]
* @param {MetadataExtends<T>} [metaExtends]
* @returns {IFiledDecorator<T>}
*/
function createSuiteDecorator(actions, metaExtends) {
return createClassDecorator('Suite', [
...(actions || []),
(ctx, next) => {
let arg = ctx.currArg;
if (isString(arg)) {
ctx.metadata.describe = arg;
ctx.next(next);
}
},
(ctx, next) => {
let arg = ctx.currArg;
if (isNumber(arg)) {
ctx.metadata.timeout = arg;
ctx.next(next);
}
}
], (metadata) => {
if (metaExtends) {
metaExtends(metadata);
}
metadata.singleton = true;
return metadata;
});
}
const Suite = createSuiteDecorator();
/**
* create Test decorator.
*
* @export
* @template T
* @param {string} [TestType]
* @param {MetadataAdapter} [actions]
* @param {MetadataExtends<T>} [metaExtends]
* @returns {ITestDecorator<T>}
*/
function createTestDecorator(name, actions, finallyActions, metaExtends) {
return createMethodDecorator(name, [
...(actions ? (isArray(actions) ? actions : [actions]) : []),
(ctx, next) => {
let arg = ctx.currArg;
if (isNumber(arg)) {
ctx.metadata.timeout = arg;
ctx.next(next);
}
},
...(finallyActions ? (isArray(finallyActions) ? finallyActions : [finallyActions]) : [])
], metaExtends);
}
/**
* @Test decorator. define the method of class as unit test case. Describe a specification or test-case with the given `title` and callback `fn` acting
* as a thunk.
*
* @export
* @interface ITestDecorator
* @template T
*/
const Test = createTestDecorator('TestCase', (ctx, next) => {
let arg = ctx.currArg;
if (isString(arg)) {
ctx.metadata.title = arg;
ctx.next(next);
}
}, (ctx, next) => {
let arg = ctx.currArg;
if (isNumber(arg)) {
ctx.metadata.setp = arg;
ctx.next(next);
}
});
/**
* @BeforeAll decorator. define the method of class as unit test action run before all test case.
*
* @export
* @interface IBeforeTestDecorator
* @template T
*/
const BeforeAll = createTestDecorator('BeforeAll');
/**
* @BeforeAll decorator. define the method of class as unit test action run before all test case.
*
* @export
* @interface IBeforeTestDecorator
* @template T
*/
const Before = BeforeAll;
/**
* @BeforeEach decorator. define the method of class as unit test action run before each test case.
*
* @export
* @interface IBeforeEachTestDecorator
* @template T
*/
const BeforeEach = createTestDecorator('TestBeforeEach');
/**
* @AfterAll decorator. define the method of class as unit test action run after all test case.
*
* @export
* @interface IAfterTestDecorator
* @template T
*/
const AfterAll = createTestDecorator('AfterAll');
/**
* @AfterAll decorator. define the method of class as unit test action run after all test case.
*
* @export
* @interface IAfterTestDecorator
* @template T
*/
const After = AfterAll;
/**
* @AfterEach decorator. define the method of class as unit test action run after each test case.
*
* @export
* @interface IAfterEachTestDecorator
* @template T
*/
const AfterEach = createTestDecorator('TestAfterEach');
const RunSuiteToken = tokenId('runSuite');
const RunCaseToken = tokenId('runCase');
/**
* abstract Assert class.
*
* @export
* @abstract
* @class Assert
*/
let Assert = class Assert {
static ρAnn() {
return { "name": "Assert", "params": { "fail": ["actual", "expected", "message", "operator"], "ok": ["value", "message"], "equal": ["actual", "expected", "message"], "notEqual": ["actual", "expected", "message"], "deepEqual": ["actual", "expected", "message"], "notDeepEqual": ["acutal", "expected", "message"], "strictEqual": ["actual", "expected", "message"], "notStrictEqual": ["actual", "expected", "message"], "deepStrictEqual": ["actual", "expected", "message"], "notDeepStrictEqual": ["actual", "expected", "message"], "throws": ["block", "error", "message"], "doesNotThrow": ["block", "error", "message"], "ifError": ["value"], "rejects": ["block", "error", "message"], "doesNotReject": ["block", "error", "message"] } };
}
};
Assert = __decorate([
Abstract()
], Assert);
const ExpectToken = tokenId('unit-expect');
/**
* Suite runner.
*
* @export
* @class SuiteRunner
* @implements {IRunner<any>}
*/
let SuiteRunner = class SuiteRunner extends Runnable {
configureService(ctx) {
return __awaiter(this, void 0, void 0, function* () {
this.context = ctx;
});
}
/**
* get suite describe.
*
* @returns {ISuiteDescribe}
* @memberof SuiteRunner
*/
getSuiteDescribe() {
let meta = this.context.getTargetReflect().getAnnoation();
this.timeout = (meta && meta.timeout) ? meta.timeout : (3 * 60 * 60 * 1000);
this.describe = meta.describe || lang.getClassName(this.getBootType());
return {
timeout: this.timeout,
describe: this.describe,
cases: []
};
}
run(data) {
return __awaiter(this, void 0, void 0, function* () {
try {
let desc = this.getSuiteDescribe();
yield this.runSuite(desc);
}
catch (err) {
// console.error(err);
}
});
}
runSuite(desc) {
return __awaiter(this, void 0, void 0, function* () {
yield this.runBefore(desc);
yield this.runTest(desc);
yield this.runAfter(desc);
});
}
runTimeout(key, describe, timeout) {
let instance = this.getBoot();
let defer = PromiseUtil.defer();
let injector = this.getContext().injector;
let timer = setTimeout(() => {
if (timer) {
clearTimeout(timer);
let assert = injector.resolve(Assert);
let err = new assert.AssertionError({
message: `${describe}, timeout ${timeout}`,
stackStartFunction: instance[key],
stackStartFn: instance[key]
});
defer.reject(err);
}
}, timeout || this.timeout);
Promise.resolve(injector.invoke(instance, key, { provide: RunCaseToken, useValue: instance[key] }, { provide: RunSuiteToken, useValue: instance }))
.then(r => {
clearTimeout(timer);
timer = null;
defer.resolve(r);
})
.catch(err => {
clearTimeout(timer);
timer = null;
defer.reject(err);
});
return defer.promise;
}
runBefore(describe) {
return __awaiter(this, void 0, void 0, function* () {
let methodMaps = this.context.reflects.getMethodMetadata(Before, this.getBoot());
yield PromiseUtil.step(Object.keys(methodMaps)
.map(key => () => {
let meta = methodMaps[key].find(m => isNumber(m.timeout));
return this.runTimeout(key, 'sutie before ' + key, meta ? meta.timeout : describe.timeout);
}));
});
}
runBeforeEach() {
return __awaiter(this, void 0, void 0, function* () {
let methodMaps = this.context.reflects.getMethodMetadata(BeforeEach, this.getBoot());
yield PromiseUtil.step(Object.keys(methodMaps)
.map(key => () => {
let meta = methodMaps[key].find(m => isNumber(m.timeout));
return this.runTimeout(key, 'before each ' + key, meta ? meta.timeout : this.timeout);
}));
});
}
runAfterEach() {
return __awaiter(this, void 0, void 0, function* () {
let methodMaps = this.context.reflects.getMethodMetadata(AfterEach, this.getBoot());
yield PromiseUtil.step(Object.keys(methodMaps)
.map(key => () => {
let meta = methodMaps[key].find(m => isNumber(m.timeout));
return this.runTimeout(key, 'after each ' + key, meta ? meta.timeout : this.timeout);
}));
});
}
runAfter(describe) {
return __awaiter(this, void 0, void 0, function* () {
let methodMaps = this.context.reflects.getMethodMetadata(After, this.getBoot());
yield PromiseUtil.step(Object.keys(methodMaps)
.map(key => () => {
let meta = methodMaps[key].find(m => isNumber(m.timeout));
return this.runTimeout(key, 'sutie after ' + key, meta ? meta.timeout : describe.timeout);
}));
});
}
runTest(desc) {
return __awaiter(this, void 0, void 0, function* () {
let methodMaps = this.context.reflects.getMethodMetadata(Test, this.getBoot());
let keys = Object.keys(methodMaps);
yield PromiseUtil.step(keys.map(key => {
let meta = methodMaps[key].find(m => isNumber(m.setp));
let timeoutMeta = methodMaps[key].find(m => isNumber(m.timeout));
let title = methodMaps[key].map(m => m.title).filter(t => t).join('; ');
return {
key: key,
order: meta ? meta.setp : keys.length,
timeout: timeoutMeta ? timeoutMeta.timeout : this.timeout,
title: title || key
};
})
.sort((a, b) => {
return b.order - a.order;
})
.map(caseDesc => {
return () => this.runCase(caseDesc);
}));
});
}
runCase(caseDesc) {
return __awaiter(this, void 0, void 0, function* () {
try {
yield this.runBeforeEach();
yield this.runTimeout(caseDesc.key, caseDesc.title, caseDesc.timeout);
yield this.runAfterEach();
}
catch (err) {
caseDesc.error = err;
}
return caseDesc;
});
}
static ρAnn() {
return { "name": "SuiteRunner", "params": { "configureService": ["ctx"], "run": ["data"], "runSuite": ["desc"], "runTimeout": ["key", "describe", "timeout"], "runBefore": ["describe"], "runAfter": ["describe"], "runTest": ["desc"], "runCase": ["caseDesc"] } };
}
};
SuiteRunner = __decorate([
Injectable(),
Refs('@Suite', Startup)
], SuiteRunner);
const gls = {
describe: undefined,
suite: undefined,
it: undefined,
test: undefined,
before: undefined,
beforeAll: undefined,
beforeEach: undefined,
after: undefined,
afterAll: undefined,
afterEach: undefined
};
const testkeys = Object.keys(gls);
const globals = typeof window !== 'undefined' ? window : global;
/**
* Suite runner.
*
* @export
* @class SuiteRunner
* @implements {IRunner<any>}
*/
let OldTestRunner = class OldTestRunner extends Destoryable {
constructor(timeout) {
super();
this.suites = [];
this.timeout = timeout || (3 * 60 * 60 * 1000);
}
configureService(ctx) {
return __awaiter(this, void 0, void 0, function* () {
});
}
getContext() {
return null;
}
getBootType() {
return null;
}
getBoot() {
return this.suites;
}
registerGlobalScope() {
// isUndefined(window) ? global : window;
testkeys.forEach(k => {
gls[k] = globals[k];
});
let suites = this.suites;
// BDD style
let describe = globals.describe = (name, fn, superDesc) => {
if (!isFunction(fn))
return;
let suiteDesc = Object.assign(Object.assign({}, superDesc), { describe: name, cases: [] });
suites.push(suiteDesc);
globals.describe = (subname, fn) => {
describe(name + ' ' + subname, fn, suiteDesc);
};
globals.it = (title, test, timeout) => {
if (!isFunction(test))
return;
suiteDesc.cases.push({ title: title, key: '', fn: test, timeout: timeout });
};
globals.before = globals.beforeAll = (fn, timeout) => {
if (!isFunction(fn))
return;
suiteDesc.before = suiteDesc.before || [];
suiteDesc.before.push({
fn: fn,
timeout: timeout
});
};
globals.beforeEach = (fn, timeout) => {
if (!isFunction(fn))
return;
suiteDesc.beforeEach = suiteDesc.beforeEach || [];
suiteDesc.beforeEach.push({
fn: fn,
timeout: timeout
});
};
globals.after = globals.afterAll = (fn, timeout) => {
if (!isFunction(fn))
return;
suiteDesc.after = suiteDesc.after || [];
suiteDesc.after.push({
fn: fn,
timeout: timeout
});
};
globals.afterEach = (fn, timeout) => {
if (!isFunction(fn))
return;
suiteDesc.afterEach = suiteDesc.afterEach || [];
suiteDesc.afterEach.push({
fn: fn,
timeout: timeout
});
};
fn && fn();
globals.describe = describe;
};
// TDD style
let suite = globals.suite = function (name, fn, superDesc) {
let suiteDesc = Object.assign(Object.assign({}, superDesc), { describe: name, cases: [] });
suites.push(suiteDesc);
globals.suite = (subname, fn) => {
suite(name + ' ' + subname, fn, suiteDesc);
};
globals.test = (title, test, timeout) => {
suiteDesc.cases.push({ title: title, key: '', fn: test, timeout: timeout });
};
globals.before = globals.beforeAll = (test, timeout) => {
suiteDesc.before = suiteDesc.before || [];
suiteDesc.before.push({
fn: test,
timeout: timeout
});
};
globals.beforeEach = (test, timeout) => {
suiteDesc.beforeEach = suiteDesc.beforeEach || [];
suiteDesc.beforeEach.push({
fn: test,
timeout: timeout
});
};
globals.after = globals.afterAll = (test, timeout) => {
suiteDesc.after = suiteDesc.after || [];
suiteDesc.after.push({
fn: test,
timeout: timeout
});
};
globals.afterEach = (test, timeout) => {
suiteDesc.afterEach = suiteDesc.afterEach || [];
suiteDesc.afterEach.push({
fn: test,
timeout: timeout
});
};
fn && fn();
globals.suite = suite;
};
}
unregisterGlobalScope() {
// reset to default.
testkeys.forEach(k => {
globals[k] = gls[k];
});
}
startup() {
return __awaiter(this, void 0, void 0, function* () {
return this.run();
});
}
run() {
return __awaiter(this, void 0, void 0, function* () {
try {
yield PromiseUtil.step(this.suites.map(desc => desc.cases.length ? () => this.runSuite(desc) : () => Promise.resolve()));
}
catch (err) {
// console.error(err);
}
});
}
runSuite(desc) {
return __awaiter(this, void 0, void 0, function* () {
yield this.runBefore(desc);
yield this.runTest(desc);
yield this.runAfter(desc);
});
}
runTimeout(fn, describe, timeout) {
let defer = PromiseUtil.defer();
let timer = setTimeout(() => {
if (timer) {
clearTimeout(timer);
let assert = this.injector.resolve(Assert);
let err = new assert.AssertionError({
message: `${describe}, timeout ${timeout}`,
stackStartFunction: fn,
stackStartFn: fn
});
defer.reject(err);
}
}, timeout || this.timeout);
Promise.resolve(fn(() => defer.resolve()))
.then(r => {
clearTimeout(timer);
timer = null;
defer.resolve(r);
})
.catch(err => {
clearTimeout(timer);
timer = null;
defer.reject(err);
});
return defer.promise;
}
runHook(describe, action, desc) {
return __awaiter(this, void 0, void 0, function* () {
yield PromiseUtil.step((describe[action] || [])
.map(hk => () => this.runTimeout(hk.fn, desc, hk.timeout || describe.timeout)));
});
}
runBefore(describe) {
return __awaiter(this, void 0, void 0, function* () {
yield this.runHook(describe, 'before', 'suite before');
});
}
runBeforeEach(describe) {
return __awaiter(this, void 0, void 0, function* () {
yield this.runHook(describe, 'beforeEach', 'before each');
});
}
runAfterEach(describe) {
return __awaiter(this, void 0, void 0, function* () {
yield this.runHook(describe, 'afterEach', 'after case each');
});
}
runAfter(describe) {
return __awaiter(this, void 0, void 0, function* () {
yield this.runHook(describe, 'after', 'suite after');
});
}
runTest(desc) {
return __awaiter(this, void 0, void 0, function* () {
yield PromiseUtil.step(desc.cases.map(caseDesc => () => this.runCase(caseDesc, desc)));
});
}
runCase(caseDesc, suiteDesc) {
return __awaiter(this, void 0, void 0, function* () {
try {
yield this.runBeforeEach(suiteDesc);
yield this.runTimeout(caseDesc.fn, caseDesc.title, caseDesc.timeout);
yield this.runAfterEach(suiteDesc);
}
catch (err) {
caseDesc.error = err;
}
return caseDesc;
});
}
destroying() {
}
static ρAnn() {
return { "name": "OldTestRunner", "params": { "configureService": ["ctx"], "constructor": ["timeout"], "runSuite": ["desc"], "runTimeout": ["fn", "describe", "timeout"], "runHook": ["describe", "action", "desc"], "runBefore": ["describe"], "runBeforeEach": ["describe"], "runAfterEach": ["describe"], "runAfter": ["describe"], "runTest": ["desc"], "runCase": ["caseDesc", "suiteDesc"] } };
}
};
__decorate([
Inject(INJECTOR),
__metadata("design:type", Object)
], OldTestRunner.prototype, "injector", void 0);
OldTestRunner = __decorate([
Singleton,
__metadata("design:paramtypes", [Number])
], OldTestRunner);
/**
* reportor.
*
* @export
* @abstract
* @class Reporter
*/
let Reporter = class Reporter {
constructor() {
}
static ρAnn() {
return { "name": "Reporter", "params": { "render": ["suites"], "track": ["error"] } };
}
};
Reporter = __decorate([
Abstract(),
__metadata("design:paramtypes", [])
], Reporter);
/**
* realtime reporter.
*
* @export
* @abstract
* @class RealtimeReporter
*/
let RealtimeReporter = class RealtimeReporter extends Reporter {
constructor() {
super();
}
static ρAnn() {
return { "name": "RealtimeReporter", "params": { "renderSuite": ["desc"], "renderCase": ["desc"] } };
}
};
RealtimeReporter = __decorate([
Abstract(),
__metadata("design:paramtypes", [])
], RealtimeReporter);
/**
* is target reporter.
*
* @export
* @param {*} target
* @returns
*/
function isReporterClass(target) {
return isClass(target) && lang.isExtendsClass(target, Reporter);
}
/**
* report token.
*/
const ReportsToken = tokenId('unit-reports');
/**
* test report.
*
* @export
* @class TestReport
* @implements {ITestReport}
*/
let TestReport = class TestReport {
constructor() {
this.suites = new Map();
}
getReports() {
if (!this.resports || this.resports.length < 0) {
this.resports = this.injector.getServices(Reporter);
}
return this.resports || [];
}
track(error) {
this.resports.forEach(rep => {
rep.track(error);
});
}
addSuite(suit, describe) {
if (!this.suites.has(suit)) {
describe.start = new Date().getTime();
// init suite must has no completed cases.
if (describe.cases.length) {
describe = lang.omit(describe, 'cases');
}
describe.cases = [];
this.suites.set(suit, describe);
this.getReports().forEach((rep) => __awaiter(this, void 0, void 0, function* () {
if (rep instanceof RealtimeReporter) {
rep.renderSuite(describe);
}
}));
}
}
getSuite(suit) {
return this.suites.has(suit) ? this.suites.get(suit) : null;
}
setSuiteCompleted(suit) {
let suite = this.getSuite(suit);
if (suite) {
suite.end = new Date().getTime();
}
}
addCase(suit, testCase) {
if (this.suites.has(suit)) {
testCase.start = new Date().getTime();
this.suites.get(suit).cases.push(testCase);
}
}
getCase(suit, test) {
let suite = this.getSuite(suit);
if (suite) {
let tCase = suite.cases.find(c => c.key === test);
if (!tCase) {
tCase = suite.cases.find(c => c.title === test);
}
return tCase;
}
return null;
}
setCaseCompleted(testCase) {
testCase.end = new Date().getTime();
this.getReports().forEach((rep) => __awaiter(this, void 0, void 0, function* () {
if (rep instanceof RealtimeReporter) {
rep.renderCase(testCase);
}
}));
}
report() {
return __awaiter(this, void 0, void 0, function* () {
yield Promise.all(this.getReports().map(rep => {
if (rep) {
return rep.render(this.suites);
}
return null;
}));
});
}
static ρAnn() {
return { "name": "TestReport", "params": { "track": ["error"], "addSuite": ["suit", "describe"], "getSuite": ["suit"], "setSuiteCompleted": ["suit"], "addCase": ["suit", "testCase"], "getCase": ["suit", "test"], "setCaseCompleted": ["testCase"] } };
}
};
__decorate([
Inject(INJECTOR),
__metadata("design:type", Object)
], TestReport.prototype, "injector", void 0);
TestReport = __decorate([
Singleton(),
__metadata("design:paramtypes", [])
], TestReport);
/**
* Suite runner.
*
* @export
* @class SuiteRunner
* @implements {IRunner<any>}
*/
let UnitTestRunner = class UnitTestRunner extends Runnable {
configureService(ctx) {
return __awaiter(this, void 0, void 0, function* () {
this.context = ctx;
});
}
getContext() {
return this.context;
}
run(data) {
return __awaiter(this, void 0, void 0, function* () {
let context = this.getContext();
let config = yield context.getConfiguration();
let src = config.src;
let injector = context.injector;
const exit = injector.get(ApplicationExit);
if (exit) {
exit.enable = false;
}
let suites = [];
let oldRunner = injector.resolve(OldTestRunner);
yield oldRunner.configureService(context);
let loader = injector.getLoader();
oldRunner.registerGlobalScope();
if (isString(src)) {
let alltypes = yield loader.loadTypes({ files: [src], basePath: this.context.baseURL });
alltypes.forEach(tys => {
suites = suites.concat(tys);
});
}
else if (isClass(src)) {
suites = [src];
}
else if (isArray(src)) {
if (src.some(t => isClass(t))) {
suites = src;
}
else {
let alltypes = yield loader.loadTypes({ files: src, basePath: this.context.baseURL });
alltypes.forEach(tys => {
suites = suites.concat(tys);
});
}
}
oldRunner.unregisterGlobalScope();
yield oldRunner.run();
let builder = injector.resolve(BuilderService);
let reflects = this.context.reflects;
yield PromiseUtil.step(suites.filter(v => isClass(v) && reflects.hasMetadata(Suite, v)).map(s => () => builder.run({ type: s, injector: injector })));
yield injector.resolve(TestReport).report();
});
}
static ρAnn() {
return { "name": "UnitTestRunner", "params": { "configureService": ["ctx"], "run": ["data"] } };
}
};
UnitTestRunner = __decorate([
Injectable
], UnitTestRunner);
/**
* Bootstrap ext for ioc. auto run setup after registered.
* with @IocExt('setup') decorator.
* @export
* @class BootModule
*/
let UnitSetup = class UnitSetup {
constructor() {
}
/**
* register aop for container.
*
* @memberof AopModule
*/
setup(container) {
let actInjector = container.getActionInjector();
actInjector.getInstance(DesignRegisterer)
.register(Suite, 'Class', AnnoationAction);
actInjector.getInstance(RuntimeRegisterer)
.register(Suite, 'Class', RegSingletionAction);
actInjector.getInstance(DecoratorProvider)
.bindProviders(Suite, {
provide: BootContext,
deps: [ContainerToken],
useFactory: (container, ...providers) => {
let ref = new InjectReference(BootContext, Suite.toString());
if (container.has(ref)) {
return container.get(ref, ...providers);
}
return null;
}
});
}
static ρAnn() {
return { "name": "UnitSetup", "params": { "setup": ["container"] } };
}
};
__decorate([
__param(0, Inject(ContainerToken)),
__metadata("design:type", Function),
__metadata("design:paramtypes", [Object]),
__metadata("design:returntype", void 0)
], UnitSetup.prototype, "setup", null);
UnitSetup = __decorate([
IocExt(),
__metadata("design:paramtypes", [])
], UnitSetup);
/**
* unit test configure register.
*
* @export
* @class UnitTestConfigureRegister
* @extends {ConfigureRegister}
*/
let UnitTestConfigureRegister = class UnitTestConfigureRegister extends ConfigureRegister {
register(config, ctx) {
return __awaiter(this, void 0, void 0, function* () {
if (!ctx.injector.has(Assert)) {
ctx.injector.setValue(Assert, assert);
}
if (!ctx.injector.has(ExpectToken)) {
ctx.injector.setValue(ExpectToken, expect);
}
if (isArray(config.reporters) && config.reporters.length) {
ctx.injector.use(...config.reporters);
}
});
}
static ρAnn() {
return { "name": "UnitTestConfigureRegister", "params": { "register": ["config", "ctx"] } };
}
};
UnitTestConfigureRegister = __decorate([
Singleton
], UnitTestConfigureRegister);
var UnitTestContext_1;
let UnitTestContext = UnitTestContext_1 = class UnitTestContext extends BootContext {
getConfiguration() {
return super.getConfiguration();
}
getConfigureManager() {
return super.getConfigureManager();
}
static parse(injector, target) {
return createContext(injector, UnitTestContext_1, isToken(target) ? { module: target } : target);
}
static ρAnn() {
return { "name": "UnitTestContext", "params": { "parse": ["injector", "target"] } };
}
};
UnitTestContext = UnitTestContext_1 = __decorate([
Injectable(),
Refs('@Suite', BootContext)
], UnitTestContext);
let RunAspect = class RunAspect extends LoggerAspect {
getReport() {
if (!this.report) {
this.report = this.injector.resolve(TestReport);
}
return this.report;
}
beforeError(joinPoint) {
this.getReport().track(joinPoint.throwing);
}
beforeEachError(joinPoint) {
this.getReport().track(joinPoint.throwing);
}
afterEachError(joinPoint) {
this.getReport().track(joinPoint.throwing);
}
afterError(joinPoint) {
this.getReport().track(joinPoint.throwing);
}
logBefore(joinPoint) {
let runner = joinPoint.target;
let desc = joinPoint.args[0];
switch (joinPoint.state) {
case JoinpointState.Before:
this.getReport().addSuite(runner.getBootType() || desc.describe, desc);
break;
case JoinpointState.AfterReturning:
case JoinpointState.AfterThrowing:
this.getReport().setSuiteCompleted(runner.getBootType() || desc.describe);
break;
}
}
logTestCase(joinPoint) {
let desc = joinPoint.args[0];
let suiteDesc = joinPoint.args.length > 1 ? joinPoint.args[1] : {};
let runner = joinPoint.target;
switch (joinPoint.state) {
case JoinpointState.Before:
this.getReport().addCase(runner.getBootType() || suiteDesc.describe, desc);
break;
case JoinpointState.AfterReturning:
case JoinpointState.AfterThrowing:
this.getReport().setCaseCompleted(desc);
break;
}
}
static ρAnn() {
return { "name": "RunAspect", "params": { "beforeError": ["joinPoint"], "beforeEachError": ["joinPoint"], "afterEachError": ["joinPoint"], "afterError": ["joinPoint"], "logBefore": ["joinPoint"], "logTestCase": ["joinPoint"] } };
}
};
__decorate([
AfterThrowing('execution(*.runBefore)'),
__metadata("design:type", Function),
__metadata("design:paramtypes", [Joinpoint]),
__metadata("design:returntype", void 0)
], RunAspect.prototype, "beforeError", null);
__decorate([
AfterThrowing('execution(*.runBeforeEach)'),
__metadata("design:type", Function),
__metadata("design:paramtypes", [Joinpoint]),
__metadata("design:returntype", void 0)
], RunAspect.prototype, "beforeEachError", null);
__decorate([
AfterThrowing('execution(*.runAfterEach)'),
__metadata("design:type", Function),
__metadata("design:paramtypes", [Joinpoint]),
__metadata("design:returntype", void 0)
], RunAspect.prototype, "afterEachError", null);
__decorate([
AfterThrowing('execution(*.runAfter)'),
__metadata("design:type", Function),
__metadata("design:paramtypes", [Joinpoint]),
__metadata("design:returntype", void 0)
], RunAspect.prototype, "afterError", null);
__decorate([
Around('execution(*.runSuite)'),
__metadata("design:type", Function),
__metadata("design:paramtypes", [Joinpoint]),
__metadata("design:returntype", void 0)
], RunAspect.prototype, "logBefore", null);
__decorate([
Around('execution(*.runCase)'),
__metadata("design:type", Function),
__metadata("design:paramtypes", [Joinpoint]),
__metadata("design:returntype", void 0)
], RunAspect.prototype, "logTestCase", null);
RunAspect = __decorate([
Aspect({
within: [SuiteRunner, OldTestRunner],
singleton: true
})
], RunAspect);
let UnitTest = class UnitTest {
static ρAnn() {
return { "name": "UnitTest", "params": {} };
}
};
UnitTest = __decorate([
DIModule({
imports: [
AopModule,
LogModule,
UnitSetup
],
providers: [
UnitTestContext,
UnitTestConfigureRegister,
RunAspect,
OldTestRunner,
SuiteRunner,
UnitTestRunner,
TestReport
],
bootstrap: UnitTestRunner
})
], UnitTest);
/**
* unit test.
*
* @export
* @param {(string | Type | (string | Type)[])} src test source.
* @param {(string | AppConfigure)} [config] test configure.
* @param {...LoadType[]} deps custom set unit test dependencies.
* @returns {Promise<any>}
*/
function runTest(src, config, ...deps) {
return __awaiter(this, void 0, void 0, function* () {
yield BootApplication.run({ type: UnitTest, deps: deps, configures: [config, { src: src }] });
});
}
export { After, AfterAll, AfterEach, Assert, Before, BeforeAll, BeforeEach, ExpectToken, OldTestRunner, RealtimeReporter, Reporter, ReportsToken, RunCaseToken, RunSuiteToken, Suite, SuiteRunner, Test, TestReport, UnitTest, UnitTestConfigureRegister, UnitTestContext, UnitTestRunner, createSuiteDecorator, createTestDecorator, isReporterClass, runTest };
//# sourceMappingURL=unit.js.map