|
|
import { stringify } from "yaml";
|
|
|
|
|
|
export interface TapWriter {
|
|
|
version(): void;
|
|
|
plan(n: number): void;
|
|
|
fail(e: any): void;
|
|
|
ok(msg: string): void;
|
|
|
skip(msg: string): void;
|
|
|
bailOut(msg: string): void;
|
|
|
comment(msg: string): void;
|
|
|
yaml(data: any): void;
|
|
|
end(): void;
|
|
|
}
|
|
|
|
|
|
enum TapState {
|
|
|
Init,
|
|
|
VersionWritten,
|
|
|
Ready,
|
|
|
ReadyWithoutPlan,
|
|
|
End
|
|
|
}
|
|
|
|
|
|
export abstract class AbstractTapWriter implements TapWriter {
|
|
|
private _state = TapState.Init;
|
|
|
private _version = 13;
|
|
|
private _testIndex = 1;
|
|
|
|
|
|
private _moveVersion() {
|
|
|
switch (this._state) {
|
|
|
case TapState.Init:
|
|
|
this._state = TapState.VersionWritten;
|
|
|
break;
|
|
|
default:
|
|
|
throw new Error("Invalid operation");
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
private _movePlan() {
|
|
|
switch (this._state) {
|
|
|
case TapState.Init:
|
|
|
case TapState.VersionWritten:
|
|
|
this._state = TapState.Ready;
|
|
|
break;
|
|
|
case TapState.ReadyWithoutPlan:
|
|
|
this._state = TapState.End;
|
|
|
break;
|
|
|
default:
|
|
|
throw new Error("Invalid operation");
|
|
|
}
|
|
|
}
|
|
|
|
|
|
private _moveTestResult() {
|
|
|
switch (this._state) {
|
|
|
case TapState.Init:
|
|
|
case TapState.VersionWritten:
|
|
|
this._state = TapState.ReadyWithoutPlan;
|
|
|
break;
|
|
|
case TapState.Ready:
|
|
|
case TapState.ReadyWithoutPlan:
|
|
|
break;
|
|
|
default:
|
|
|
throw new Error("Invalid operation");
|
|
|
}
|
|
|
}
|
|
|
|
|
|
private _moveEnd() {
|
|
|
switch (this._state) {
|
|
|
case TapState.End:
|
|
|
throw new Error("Invalid operation");
|
|
|
default:
|
|
|
this._state = TapState.End;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
private _moveDiag() {
|
|
|
switch (this._state) {
|
|
|
case TapState.Init:
|
|
|
case TapState.VersionWritten:
|
|
|
this._state = TapState.ReadyWithoutPlan;
|
|
|
break;
|
|
|
case TapState.Ready:
|
|
|
case TapState.ReadyWithoutPlan:
|
|
|
break;
|
|
|
default:
|
|
|
throw new Error("Invalid operation");
|
|
|
}
|
|
|
}
|
|
|
|
|
|
version() {
|
|
|
this._moveVersion();
|
|
|
|
|
|
this._writeLine(`TAP version ${this._version}`);
|
|
|
}
|
|
|
|
|
|
plan(n: number) {
|
|
|
this._movePlan();
|
|
|
|
|
|
this._writeLine(`1..${n}`);
|
|
|
}
|
|
|
|
|
|
fail(e: any) {
|
|
|
this._moveTestResult();
|
|
|
|
|
|
this._writeText(`not ok ${this._testIndex} ${e}`);
|
|
|
this._testIndex++;
|
|
|
}
|
|
|
|
|
|
ok(msg: string) {
|
|
|
this._moveTestResult();
|
|
|
|
|
|
this._writeText(`ok ${this._testIndex} ${msg}`);
|
|
|
this._testIndex++;
|
|
|
}
|
|
|
skip(msg: string) {
|
|
|
this._moveTestResult();
|
|
|
|
|
|
this._writeText(`ok ${this._testIndex} # SKIPPED: ${msg}`);
|
|
|
this._testIndex++;
|
|
|
}
|
|
|
bailOut(msg: string) {
|
|
|
this._moveEnd();
|
|
|
|
|
|
this._writeText(`Bail out! ${msg}`);
|
|
|
}
|
|
|
comment(msg: string) {
|
|
|
this._moveDiag();
|
|
|
|
|
|
this._writeText(`# ${msg}`);
|
|
|
}
|
|
|
yaml(data: any) {
|
|
|
this._moveDiag();
|
|
|
|
|
|
this._writeLine(" ---");
|
|
|
stringify(data).split("\r\n?").forEach(line => this._writeLine(" " + line));
|
|
|
this._writeLine(" ...");
|
|
|
}
|
|
|
end() {
|
|
|
this._moveEnd();
|
|
|
}
|
|
|
|
|
|
private _writeText(text: string) {
|
|
|
text.split("\r\n?").forEach((line, i) => this._writeLine(i ? "# " + line : line));
|
|
|
}
|
|
|
|
|
|
abstract _writeLine(text: string): void;
|
|
|
|
|
|
}
|
|
|
|