diff --git a/cmd/pkgserver/ui/static/test.ts b/cmd/pkgserver/ui/static/test.ts index 245756c..f9f8ebb 100644 --- a/cmd/pkgserver/ui/static/test.ts +++ b/cmd/pkgserver/ui/static/test.ts @@ -34,17 +34,26 @@ function checkDuplicates(parent: string, names: { name: string }[]) { class FailNowSentinel {} +export type Journal = ({ method: "fail" } | { method: "log", message: string })[]; +function formatJournal(journal: Journal): string { + return journal + .filter((e) => e.method === "log") + .map((e) => e.message) + .join("\n"); +} + export class TestController { - #logBuf: string[]; + journal: Journal; #failed: boolean; constructor() { - this.#logBuf = []; + this.journal = []; this.#failed = false; } fail() { this.#failed = true; + this.journal.push({ method: "fail" }); } failed(): boolean { @@ -57,7 +66,7 @@ export class TestController { } log(message: string) { - this.#logBuf.push(message); + this.journal.push({ method: "log", message }); } error(message: string) { @@ -69,10 +78,6 @@ export class TestController { this.log(message); this.failNow(); } - - getLog(): string { - return this.#logBuf.join("\n"); - } } // ============================================================================= @@ -80,7 +85,7 @@ export class TestController { export interface TestResult { success: boolean; - output: string; + journal: Journal; } export function run(reporter: Reporter) { @@ -103,13 +108,11 @@ function runTests(reporter: Reporter, parents: string[], node: TestTree) { node.test(controller); } catch (e) { if (!(e instanceof FailNowSentinel)) { - controller.fail(); excStr = extractExceptionString(e); } } - const log = controller.getLog(); - const output = (log && excStr) ? `${log}\n${excStr}` : `${log}${excStr ?? ''}`; - reporter.update(path, { success: !controller.failed(), output }); + if (excStr !== undefined) controller.error(excStr); + reporter.update(path, { success: !controller.failed(), journal: controller.journal }); } function extractExceptionString(e: any): string { @@ -196,10 +199,11 @@ export class StreamReporter implements Reporter { #writeOutput(test: { name: string } & TestResult, prefix: string, nested: boolean) { let output = ""; - if (test.output) { - const lines = test.output.split("\n"); + let logOutput = formatJournal(test.journal); + if (logOutput) { + const lines = logOutput.split("\n"); if (lines.length <= 1) { - output = `: ${test.output}`; + output = `: ${logOutput}`; } else { const padding = nested ? " " : " "; output = ":\n" + lines.map((line) => padding + line).join("\n"); @@ -243,9 +247,10 @@ export class DOMReporter implements Reporter { } const p = document.createElement("p"); p.classList.add("test-desc"); - if (result.output) { + const logOutput = formatJournal(result.journal); + if (logOutput) { const pre = document.createElement("pre"); - pre.appendChild(document.createTextNode(result.output)); + pre.appendChild(document.createTextNode(logOutput)); p.appendChild(pre); } else { p.classList.add("italic"); @@ -266,7 +271,7 @@ interface GoNode { export class GoTestReporter implements Reporter { // Convert a test tree into the one expected by the Go code. static serialize(node: TestTree): GoNode { - if (!("children" in node)) return { name: node.name }; + if (!("children" in node)) return { name: node.name, subtests: null }; return { name: node.name, subtests: node.children.map(GoTestReporter.serialize), @@ -278,7 +283,7 @@ export class GoTestReporter implements Reporter { } update(path: string[], result: TestResult) { - console.log(JSON.stringify({ "path": path, "result": result })); + console.log(JSON.stringify({ "path": path, ...result })); } finalize() {