Files
Rune-Spec/tests/agent/e2e-flow.test.ts

119 lines
4.0 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { describe, it, expect, beforeEach, afterEach } from "bun:test";
import { createRunner } from "./agent-mock.ts";
import {
setupTempDir,
cleanupTempDir,
getTempDir,
createFreshProject,
changeFileExists,
} from "./fixtures.ts";
import { assertAllTasksDone } from "./validators.ts";
import { scanChanges, scanArchives } from "../../src/core/scanner.ts";
import { assembleDiscussPrompt } from "../../src/core/assembler.ts";
import { validateChangeName } from "../../src/cli.ts";
describe("e2e: 全流程", () => {
let runner: ReturnType<typeof createRunner>;
beforeEach(async () => {
await setupTempDir();
runner = createRunner();
});
afterEach(async () => {
await cleanupTempDir();
});
it("完整四阶段流程discuss → plan → build → archive", async () => {
const config = await createFreshProject();
const discussPrompt = assembleDiscussPrompt(config);
expect(typeof discussPrompt).toBe("string");
expect(discussPrompt.length).toBeGreaterThan(0);
await runner.runPlan(getTempDir(), "full-flow", "design", config);
await runner.runPlan(getTempDir(), "full-flow", "task", config);
let changes = await scanChanges(getTempDir(), config);
expect(changes).toHaveLength(1);
expect(changes[0]!.name).toBe("full-flow");
expect(changes[0]!.planCompleted).toBe(true);
expect(changes[0]!.buildUnlocked).toBe(true);
const buildResult = await runner.runBuild(getTempDir(), "full-flow", config);
expect(buildResult.files.length).toBeGreaterThan(0);
changes = await scanChanges(getTempDir(), config);
expect(changes).toHaveLength(1);
assertAllTasksDone(changes[0]!);
await runner.runArchive(getTempDir(), "full-flow", config);
expect(changeFileExists("full-flow", "task.md")).toBe(false);
const archives = await scanArchives(getTempDir());
expect(archives.length).toBeGreaterThanOrEqual(1);
changes = await scanChanges(getTempDir(), config);
expect(changes.find((c) => c.name === "full-flow")).toBeUndefined();
});
it("多变更并行互不干扰", async () => {
const config = await createFreshProject();
await runner.runPlan(getTempDir(), "变更A", "design", config);
await runner.runPlan(getTempDir(), "变更A", "task", config);
await runner.runPlan(getTempDir(), "变更B", "design", config);
await runner.runPlan(getTempDir(), "变更B", "task", config);
let changes = await scanChanges(getTempDir(), config);
expect(changes).toHaveLength(2);
const changeA = changes.find((c) => c.name === "变更A");
const changeB = changes.find((c) => c.name === "变更B");
expect(changeA).toBeDefined();
expect(changeB).toBeDefined();
expect(changeA!.planCompleted).toBe(true);
expect(changeB!.planCompleted).toBe(true);
await runner.runBuild(getTempDir(), "变更A", config);
await runner.runBuild(getTempDir(), "变更B", config);
changes = await scanChanges(getTempDir(), config);
expect(changes).toHaveLength(2);
assertAllTasksDone(changes.find((c) => c.name === "变更A")!);
assertAllTasksDone(changes.find((c) => c.name === "变更B")!);
expect(changes[0]!.taskProgress?.completed).toBe(changes[0]!.taskProgress?.total);
expect(changes[1]!.taskProgress?.completed).toBe(changes[1]!.taskProgress?.total);
});
describe("变更名非法字符拒绝", () => {
it("空字符串抛出错误", () => {
expect(() => validateChangeName("")).toThrow();
});
it("包含 / 抛出错误", () => {
expect(() => validateChangeName("变更/A")).toThrow();
});
it("包含 . 抛出错误", () => {
expect(() => validateChangeName("变更.A")).toThrow();
});
it("合法中文名称不抛出错误", () => {
expect(() => validateChangeName("变更名")).not.toThrow();
});
it("合法英文名称不抛出错误", () => {
expect(() => validateChangeName("my-change")).not.toThrow();
});
it("合法短横线名称不抛出错误", () => {
expect(() => validateChangeName("abc-def-xyz")).not.toThrow();
});
});
});