81 lines
2.5 KiB
TypeScript
81 lines
2.5 KiB
TypeScript
import type { Role, RoleResult, StartStep, WorkflowMessage } from "@uncaged/nerve-core";
|
|
import { lastMetaForRole } from "../../lib/meta-helpers.js";
|
|
import { runTestCommand } from "../../lib/run-test-command.js";
|
|
import type { ImplementerMeta } from "../implementer/index.js";
|
|
import type { PlannerMeta } from "../planner/index.js";
|
|
|
|
export type TestCommandResult = {
|
|
command: string;
|
|
ok: boolean;
|
|
stdoutPreview: string;
|
|
stderrPreview: string;
|
|
};
|
|
|
|
export type TesterMeta = {
|
|
passed: boolean;
|
|
attempt: number;
|
|
failureReason: string | null;
|
|
testCommandResults: TestCommandResult[] | null;
|
|
};
|
|
|
|
export type BuildTesterDeps = {
|
|
nerveRoot: string;
|
|
};
|
|
|
|
export function buildTesterRole({ nerveRoot }: BuildTesterDeps): Role<TesterMeta> {
|
|
return async (_start: StartStep, messages: WorkflowMessage[]): Promise<RoleResult<TesterMeta>> => {
|
|
const plannerMeta = lastMetaForRole<PlannerMeta>(messages, "planner");
|
|
const implementerMeta = lastMetaForRole<ImplementerMeta>(messages, "implementer");
|
|
const attempt = messages.filter((message) => message.role === "tester").length + 1;
|
|
|
|
if (implementerMeta === null || !implementerMeta.implementationOk || implementerMeta.branchName === null) {
|
|
return {
|
|
content: "tester cannot continue: no successful implementer output",
|
|
meta: {
|
|
passed: false,
|
|
attempt,
|
|
failureReason: "no successful implementer output",
|
|
testCommandResults: null,
|
|
},
|
|
};
|
|
}
|
|
|
|
const commands =
|
|
plannerMeta?.testCommands !== null && plannerMeta?.testCommands !== undefined && plannerMeta.testCommands.length > 0
|
|
? plannerMeta.testCommands
|
|
: ["pnpm test"];
|
|
|
|
const testCommandResults: TestCommandResult[] = [];
|
|
for (const command of commands) {
|
|
const run = await runTestCommand(nerveRoot, command);
|
|
testCommandResults.push({
|
|
command,
|
|
ok: run.ok,
|
|
stdoutPreview: run.stdoutPreview,
|
|
stderrPreview: run.stderrPreview,
|
|
});
|
|
if (!run.ok) {
|
|
return {
|
|
content: `test failed: ${command}\n${run.reason ?? "unknown error"}`,
|
|
meta: {
|
|
passed: false,
|
|
attempt,
|
|
failureReason: `command failed: ${command} (${run.reason ?? "unknown error"})`,
|
|
testCommandResults,
|
|
},
|
|
};
|
|
}
|
|
}
|
|
|
|
return {
|
|
content: `all tests passed on branch ${implementerMeta.branchName}`,
|
|
meta: {
|
|
passed: true,
|
|
attempt,
|
|
failureReason: null,
|
|
testCommandResults,
|
|
},
|
|
};
|
|
};
|
|
}
|