console/src/test/widget-mock.ts

103 lines
2.3 KiB
TypeScript

//! Mock `@paperclover/console/Widget` to make testing easier.
import { expect, mock } from "bun:test";
import assert from "node:assert";
import type { Widget } from "../Widget.ts";
process.env.CI = "true";
process.env.FORCE_COLOR = "10";
let buffer = "";
let widgets: MockWidget[] = [];
globalThis.setTimeout = (() => {
throw new Error("Do not call setTimeout in tests");
}) as any;
globalThis.clearTimeout = (() => {
throw new Error("Do not call clearTimeout in tests");
}) as any;
abstract class MockWidget {
abstract format(now: number): string;
abstract fps: number;
isActive = true;
redrawCount = 0;
successCalls: string[] = [];
errorCalls: (string | Error)[] = [];
stopCalls: (string | undefined)[] = [];
constructor() {
}
stop(finalMessage?: string): void {
this.stopCalls.push(finalMessage);
this.isActive = false;
}
protected redraw(): void {
this.redrawCount++;
}
success(message: string): void {
this.successCalls.push(message);
this.isActive = false;
}
error(message: string | Error): void {
this.errorCalls.push(message);
this.isActive = false;
}
get active(): boolean {
return this.isActive;
}
}
const warn = console.warn;
mock.module(require.resolve("../Widget.ts"), () => ({
writeLine: (line: string) => buffer += line + "\n",
errorAllWidgets: () => {
warn("errorAllWidgets is not implemented");
},
Widget: MockWidget,
}));
mock.module("node:fs", () => ({
writeSync: (fd: number, data: string) => {
assert(fd === 2, "writeSync must be called with stderr");
buffer += data;
},
}));
export function reset() {
buffer = "";
widgets = [];
}
export function getBuffer() {
return buffer;
}
export function getWidgets() {
return widgets as any;
}
export function expectCalls(widget: Widget, checks: {
successCalls?: string[];
errorCalls?: (string | Error)[];
redraws?: number;
stopCalls?: (string | undefined)[];
}) {
const mockWidget = widget as unknown as MockWidget;
expect({
successCalls: mockWidget.successCalls,
errorCalls: mockWidget.errorCalls,
redraws: mockWidget.redrawCount,
stopCalls: mockWidget.stopCalls,
}).toEqual({
successCalls: checks.successCalls ?? [],
errorCalls: checks.errorCalls ?? [],
redraws: checks.redraws ?? 0,
stopCalls: checks.stopCalls ?? [],
});
}