import * as plugins from './tapbundle.plugins.js'; import { tapCreator } from './tapbundle.tapcreator.js'; import { TapTools } from './tapbundle.classes.taptools.js'; // imported interfaces import { Deferred } from '@push.rocks/smartpromise'; import { HrtMeasurement } from '@push.rocks/smarttime'; // interfaces export type TTestStatus = 'success' | 'error' | 'pending' | 'errorAfterSuccess' | 'timeout'; export interface ITestFunction { (tapTools?: TapTools): Promise; } export class TapTest { public description: string; public failureAllowed: boolean; public hrtMeasurement: HrtMeasurement; public parallel: boolean; public status: TTestStatus; public tapTools: TapTools; public testFunction: ITestFunction; public testKey: number; // the testKey the position in the test qeue. Set upon calling .run() private testDeferred: Deferred> = plugins.smartpromise.defer(); public testPromise: Promise> = this.testDeferred.promise; private testResultDeferred: Deferred = plugins.smartpromise.defer(); public testResultPromise: Promise = this.testResultDeferred.promise; /** * constructor */ constructor(optionsArg: { description: string; testFunction: ITestFunction; parallel: boolean; }) { this.description = optionsArg.description; this.hrtMeasurement = new HrtMeasurement(); this.parallel = optionsArg.parallel; this.status = 'pending'; this.tapTools = new TapTools(this); this.testFunction = optionsArg.testFunction; } /** * run the test */ public async run(testKeyArg: number) { this.hrtMeasurement.start(); this.testKey = testKeyArg; const testNumber = testKeyArg + 1; try { const testReturnValue = await this.testFunction(this.tapTools); if (this.status === 'timeout') { throw new Error('Test succeeded, but timed out...'); } this.hrtMeasurement.stop(); console.log( `ok ${testNumber} - ${this.description} # time=${this.hrtMeasurement.milliSeconds}ms` ); this.status = 'success'; this.testDeferred.resolve(this); this.testResultDeferred.resolve(testReturnValue); } catch (err: any) { this.hrtMeasurement.stop(); console.log( `not ok ${testNumber} - ${this.description} # time=${this.hrtMeasurement.milliSeconds}ms` ); this.testDeferred.resolve(this); this.testResultDeferred.resolve(err); // if the test has already succeeded before if (this.status === 'success') { this.status = 'errorAfterSuccess'; console.log('!!! ALERT !!!: weird behaviour, since test has been already successfull'); } else { this.status = 'error'; } // if the test is allowed to fail if (this.failureAllowed) { console.log(`please note: failure allowed!`); } console.log(err); } } }