TestTraits.ts
74 lines
| 2.3 KiB
| video/mp2t
|
TypeScriptLexer
|
|
r50 | import { IObservable, ICancellation, IDestroyable } from "@implab/core/interfaces"; | ||
| import { Cancellation } from "@implab/core/Cancellation"; | ||||
| import { TraceEvent, LogLevel, WarnLevel, DebugLevel, TraceSource } from "@implab/core/log/TraceSource"; | ||||
| import * as tape from "tape"; | ||||
|
|
r59 | import { argumentNotNull, destroy } from "@implab/core/safe"; | ||
|
|
r50 | |||
| export class TapeWriter implements IDestroyable { | ||||
|
|
r82 | private readonly _tape: tape.Test; | ||
|
|
r50 | |||
|
|
r82 | private readonly _subscriptions = new Array<IDestroyable>(); | ||
| private _destroyed; | ||||
|
|
r50 | |||
| constructor(t: tape.Test) { | ||||
| argumentNotNull(t, "tape"); | ||||
| this._tape = t; | ||||
| } | ||||
| writeEvents(source: IObservable<TraceEvent>, ct: ICancellation = Cancellation.none) { | ||||
|
|
r82 | if (!this._destroyed) { | ||
| const subscription = source.on(this.writeEvent.bind(this)); | ||||
| if (ct.isSupported()) { | ||||
| ct.register(subscription.destroy.bind(subscription)); | ||||
| } | ||||
| this._subscriptions.push(subscription); | ||||
|
|
r50 | } | ||
| } | ||||
| writeEvent(next: TraceEvent) { | ||||
| if (next.level >= DebugLevel) { | ||||
|
|
r82 | this._tape.comment(`DEBUG ${next.source.id} ${next}`); | ||
|
|
r50 | } else if (next.level >= LogLevel) { | ||
|
|
r82 | this._tape.comment(`LOG ${next.source.id} ${next}`); | ||
|
|
r50 | } else if (next.level >= WarnLevel) { | ||
|
|
r82 | this._tape.comment(`WARN ${next.source.id} ${next}`); | ||
|
|
r50 | } else { | ||
|
|
r82 | this._tape.comment(`ERROR ${next.source.id} ${next}`); | ||
|
|
r50 | } | ||
| } | ||||
| destroy() { | ||||
|
|
r59 | this._subscriptions.forEach(destroy); | ||
|
|
r50 | } | ||
| } | ||||
|
|
r82 | export function test(name: string, cb: (t: tape.Test, trace: TraceSource) => any) { | ||
|
|
r50 | tape(name, async t => { | ||
| const writer = new TapeWriter(t); | ||||
|
|
r82 | // this trace is not announced through the TraceSource global registry | ||
| const trace = new TraceSource(name); | ||||
| trace.level = DebugLevel; | ||||
| writer.writeEvents(trace.events); | ||||
| const h = TraceSource.on(ts => { | ||||
|
|
r50 | ts.level = DebugLevel; | ||
| writer.writeEvents(ts.events); | ||||
| }); | ||||
| try { | ||||
|
|
r82 | await cb(t, trace); | ||
|
|
r50 | } catch (e) { | ||
| // verbose error information | ||||
| // tslint:disable-next-line | ||||
| console.error(e); | ||||
| t.fail(e); | ||||
| } finally { | ||||
| t.end(); | ||||
|
|
r59 | destroy(writer); | ||
|
|
r82 | destroy(h); | ||
|
|
r50 | } | ||
| }); | ||||
| } | ||||
