test: 添加一大堆测试文件

This commit is contained in:
claude-code-best
2026-04-02 20:28:08 +08:00
parent 6f5623b26c
commit ce29527a67
33 changed files with 3502 additions and 329 deletions

View File

@@ -0,0 +1,121 @@
import { describe, expect, test } from "bun:test";
import { groupMessagesByApiRound } from "../grouping";
function makeMsg(type: "user" | "assistant" | "system", id: string): any {
return {
type,
message: { id, content: `${type}-${id}` },
};
}
describe("groupMessagesByApiRound", () => {
// Boundary fires when: assistant msg with NEW id AND current group has items
test("splits before first assistant if user messages precede it", () => {
const messages = [makeMsg("user", "u1"), makeMsg("assistant", "a1")];
const groups = groupMessagesByApiRound(messages);
// user msgs form group 1, assistant starts group 2
expect(groups).toHaveLength(2);
expect(groups[0]).toHaveLength(1);
expect(groups[1]).toHaveLength(1);
});
test("single assistant message forms one group", () => {
const messages = [makeMsg("assistant", "a1")];
const groups = groupMessagesByApiRound(messages);
expect(groups).toHaveLength(1);
});
test("splits at new assistant message ID", () => {
const messages = [
makeMsg("user", "u1"),
makeMsg("assistant", "a1"),
makeMsg("assistant", "a2"),
];
const groups = groupMessagesByApiRound(messages);
expect(groups).toHaveLength(3);
});
test("keeps same-ID assistant messages in same group (streaming chunks)", () => {
const messages = [
makeMsg("assistant", "a1"),
makeMsg("assistant", "a1"),
makeMsg("assistant", "a1"),
];
const groups = groupMessagesByApiRound(messages);
expect(groups).toHaveLength(1);
expect(groups[0]).toHaveLength(3);
});
test("returns empty array for empty input", () => {
expect(groupMessagesByApiRound([])).toEqual([]);
});
test("handles all user messages (no assistant)", () => {
const messages = [makeMsg("user", "u1"), makeMsg("user", "u2")];
const groups = groupMessagesByApiRound(messages);
expect(groups).toHaveLength(1);
});
test("three API rounds produce correct groups", () => {
const messages = [
makeMsg("user", "u1"),
makeMsg("assistant", "a1"),
makeMsg("user", "u2"),
makeMsg("assistant", "a2"),
makeMsg("user", "u3"),
makeMsg("assistant", "a3"),
];
const groups = groupMessagesByApiRound(messages);
// [u1], [a1, u2], [a2, u3], [a3] = 4 groups
expect(groups).toHaveLength(4);
});
test("consecutive user messages stay in same group", () => {
const messages = [makeMsg("user", "u1"), makeMsg("user", "u2")];
expect(groupMessagesByApiRound(messages)).toHaveLength(1);
});
test("does not produce empty groups", () => {
const messages = [
makeMsg("assistant", "a1"),
makeMsg("assistant", "a2"),
];
const groups = groupMessagesByApiRound(messages);
for (const group of groups) {
expect(group.length).toBeGreaterThan(0);
}
});
test("handles single message", () => {
expect(groupMessagesByApiRound([makeMsg("user", "u1")])).toHaveLength(1);
});
test("preserves message order within groups", () => {
const messages = [makeMsg("assistant", "a1"), makeMsg("user", "u2")];
const groups = groupMessagesByApiRound(messages);
expect(groups[0][0].message.id).toBe("a1");
expect(groups[0][1].message.id).toBe("u2");
});
test("handles system messages", () => {
const messages = [
makeMsg("system", "s1"),
makeMsg("assistant", "a1"),
];
// system msg is non-assistant, goes to current. Then assistant a1 is new ID
// and current has items, so split.
const groups = groupMessagesByApiRound(messages);
expect(groups).toHaveLength(2);
});
test("tool_result after assistant stays in same round", () => {
const messages = [
makeMsg("assistant", "a1"),
makeMsg("user", "tool_result_1"),
makeMsg("assistant", "a1"), // same ID = no new boundary
];
const groups = groupMessagesByApiRound(messages);
expect(groups).toHaveLength(1);
expect(groups[0]).toHaveLength(3);
});
});

View File

@@ -0,0 +1,77 @@
import { mock, describe, expect, test } from "bun:test";
mock.module("bun:bundle", () => ({ feature: () => false }));
const { formatCompactSummary } = await import("../prompt");
describe("formatCompactSummary", () => {
test("strips <analysis>...</analysis> block", () => {
const input = "<analysis>my thought process</analysis>\n<summary>the summary</summary>";
const result = formatCompactSummary(input);
expect(result).not.toContain("<analysis>");
expect(result).not.toContain("my thought process");
});
test("replaces <summary>...</summary> with 'Summary:\\n' prefix", () => {
const input = "<summary>key points here</summary>";
const result = formatCompactSummary(input);
expect(result).toContain("Summary:");
expect(result).toContain("key points here");
expect(result).not.toContain("<summary>");
});
test("handles analysis + summary together", () => {
const input = "<analysis>thinking</analysis><summary>result</summary>";
const result = formatCompactSummary(input);
expect(result).not.toContain("thinking");
expect(result).toContain("result");
});
test("handles summary without analysis", () => {
const input = "<summary>just the summary</summary>";
const result = formatCompactSummary(input);
expect(result).toContain("just the summary");
});
test("handles analysis without summary", () => {
const input = "<analysis>just analysis</analysis>and some text";
const result = formatCompactSummary(input);
expect(result).not.toContain("just analysis");
expect(result).toContain("and some text");
});
test("collapses multiple newlines to double", () => {
const input = "hello\n\n\n\nworld";
const result = formatCompactSummary(input);
expect(result).not.toMatch(/\n{3,}/);
});
test("trims leading/trailing whitespace", () => {
const input = " \n hello \n ";
const result = formatCompactSummary(input);
expect(result).toBe("hello");
});
test("handles empty string", () => {
expect(formatCompactSummary("")).toBe("");
});
test("handles plain text without tags", () => {
const input = "just plain text";
expect(formatCompactSummary(input)).toBe("just plain text");
});
test("handles multiline analysis content", () => {
const input = "<analysis>\nline1\nline2\nline3\n</analysis><summary>ok</summary>";
const result = formatCompactSummary(input);
expect(result).not.toContain("line1");
expect(result).toContain("ok");
});
test("preserves content between analysis and summary", () => {
const input = "<analysis>thoughts</analysis>middle text<summary>final</summary>";
const result = formatCompactSummary(input);
expect(result).toContain("middle text");
expect(result).toContain("final");
});
});