mirror of
https://github.com/AutoMaker-Org/automaker.git
synced 2026-01-31 20:03:37 +00:00
Added extensive test coverage for previously untested files: Platform package (94.69% coverage, +47 tests): - paths.test.ts: 22 tests for path construction and directory creation - security.test.ts: 25 tests for path validation and security Utils package (94.3% coverage, +109 tests): - logger.test.ts: 23 tests for logging with levels - fs-utils.test.ts: 20 tests for safe file operations - conversation-utils.test.ts: 24 tests for message formatting - image-handler.test.ts: 25 tests for image processing - prompt-builder.test.ts: 17 tests for prompt construction Coverage improvements: - Platform: 63.71% → 94.69% stmts, 40% → 97.14% funcs - Utils: 19.51% → 94.3% stmts, 18.51% → 100% funcs Updated thresholds to enforce high quality: - Platform: 90% lines/stmts, 95% funcs, 75% branches - Utils: 90% lines/stmts, 95% funcs, 85% branches Total new tests: 156 (platform: 47, utils: 109) All tests passing with new coverage thresholds. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
262 lines
8.2 KiB
TypeScript
262 lines
8.2 KiB
TypeScript
import { describe, it, expect } from "vitest";
|
|
import type { ConversationMessage } from "@automaker/types";
|
|
import {
|
|
extractTextFromContent,
|
|
normalizeContentBlocks,
|
|
formatHistoryAsText,
|
|
convertHistoryToMessages,
|
|
} from "../src/conversation-utils";
|
|
|
|
describe("conversation-utils.ts", () => {
|
|
describe("extractTextFromContent", () => {
|
|
it("should extract text from string content", () => {
|
|
const content = "Hello, world!";
|
|
const result = extractTextFromContent(content);
|
|
expect(result).toBe("Hello, world!");
|
|
});
|
|
|
|
it("should extract text from array content with text blocks", () => {
|
|
const content = [
|
|
{ type: "text", text: "First block" },
|
|
{ type: "text", text: "Second block" },
|
|
];
|
|
const result = extractTextFromContent(content);
|
|
expect(result).toBe("First block\nSecond block");
|
|
});
|
|
|
|
it("should filter out non-text blocks", () => {
|
|
const content = [
|
|
{ type: "text", text: "Text block" },
|
|
{ type: "image", source: { data: "..." } },
|
|
{ type: "text", text: "Another text" },
|
|
];
|
|
const result = extractTextFromContent(content);
|
|
expect(result).toBe("Text block\nAnother text");
|
|
});
|
|
|
|
it("should handle empty text blocks", () => {
|
|
const content = [
|
|
{ type: "text", text: "First" },
|
|
{ type: "text" },
|
|
{ type: "text", text: "Third" },
|
|
];
|
|
const result = extractTextFromContent(content);
|
|
expect(result).toBe("First\n\nThird");
|
|
});
|
|
|
|
it("should return empty string for array with only non-text blocks", () => {
|
|
const content = [
|
|
{ type: "image", source: {} },
|
|
{ type: "tool_use", source: {} },
|
|
];
|
|
const result = extractTextFromContent(content);
|
|
expect(result).toBe("");
|
|
});
|
|
|
|
it("should return empty string for empty array", () => {
|
|
const content: Array<{ type: string; text?: string }> = [];
|
|
const result = extractTextFromContent(content);
|
|
expect(result).toBe("");
|
|
});
|
|
});
|
|
|
|
describe("normalizeContentBlocks", () => {
|
|
it("should convert string to array of text blocks", () => {
|
|
const content = "Simple text";
|
|
const result = normalizeContentBlocks(content);
|
|
expect(result).toEqual([{ type: "text", text: "Simple text" }]);
|
|
});
|
|
|
|
it("should return array as-is", () => {
|
|
const content = [
|
|
{ type: "text", text: "First" },
|
|
{ type: "image", source: {} },
|
|
];
|
|
const result = normalizeContentBlocks(content);
|
|
expect(result).toBe(content);
|
|
expect(result).toEqual(content);
|
|
});
|
|
|
|
it("should handle empty string", () => {
|
|
const content = "";
|
|
const result = normalizeContentBlocks(content);
|
|
expect(result).toEqual([{ type: "text", text: "" }]);
|
|
});
|
|
|
|
it("should handle multiline string", () => {
|
|
const content = "Line 1\nLine 2\nLine 3";
|
|
const result = normalizeContentBlocks(content);
|
|
expect(result).toEqual([{ type: "text", text: "Line 1\nLine 2\nLine 3" }]);
|
|
});
|
|
});
|
|
|
|
describe("formatHistoryAsText", () => {
|
|
it("should format empty history as empty string", () => {
|
|
const history: ConversationMessage[] = [];
|
|
const result = formatHistoryAsText(history);
|
|
expect(result).toBe("");
|
|
});
|
|
|
|
it("should format single user message", () => {
|
|
const history: ConversationMessage[] = [
|
|
{ role: "user", content: "Hello!" },
|
|
];
|
|
const result = formatHistoryAsText(history);
|
|
expect(result).toBe("Previous conversation:\n\nUser: Hello!\n\n---\n\n");
|
|
});
|
|
|
|
it("should format single assistant message", () => {
|
|
const history: ConversationMessage[] = [
|
|
{ role: "assistant", content: "Hi there!" },
|
|
];
|
|
const result = formatHistoryAsText(history);
|
|
expect(result).toBe(
|
|
"Previous conversation:\n\nAssistant: Hi there!\n\n---\n\n"
|
|
);
|
|
});
|
|
|
|
it("should format conversation with multiple messages", () => {
|
|
const history: ConversationMessage[] = [
|
|
{ role: "user", content: "What's 2+2?" },
|
|
{ role: "assistant", content: "The answer is 4." },
|
|
{ role: "user", content: "Thanks!" },
|
|
];
|
|
const result = formatHistoryAsText(history);
|
|
expect(result).toBe(
|
|
"Previous conversation:\n\n" +
|
|
"User: What's 2+2?\n\n" +
|
|
"Assistant: The answer is 4.\n\n" +
|
|
"User: Thanks!\n\n" +
|
|
"---\n\n"
|
|
);
|
|
});
|
|
|
|
it("should handle array content by extracting text", () => {
|
|
const history: ConversationMessage[] = [
|
|
{
|
|
role: "user",
|
|
content: [
|
|
{ type: "text", text: "First part" },
|
|
{ type: "text", text: "Second part" },
|
|
],
|
|
},
|
|
];
|
|
const result = formatHistoryAsText(history);
|
|
expect(result).toBe(
|
|
"Previous conversation:\n\nUser: First part\nSecond part\n\n---\n\n"
|
|
);
|
|
});
|
|
|
|
it("should handle mixed string and array content", () => {
|
|
const history: ConversationMessage[] = [
|
|
{ role: "user", content: "String message" },
|
|
{
|
|
role: "assistant",
|
|
content: [{ type: "text", text: "Array message" }],
|
|
},
|
|
];
|
|
const result = formatHistoryAsText(history);
|
|
expect(result).toContain("User: String message");
|
|
expect(result).toContain("Assistant: Array message");
|
|
});
|
|
});
|
|
|
|
describe("convertHistoryToMessages", () => {
|
|
it("should convert empty history", () => {
|
|
const history: ConversationMessage[] = [];
|
|
const result = convertHistoryToMessages(history);
|
|
expect(result).toEqual([]);
|
|
});
|
|
|
|
it("should convert single user message", () => {
|
|
const history: ConversationMessage[] = [
|
|
{ role: "user", content: "Hello!" },
|
|
];
|
|
const result = convertHistoryToMessages(history);
|
|
|
|
expect(result).toHaveLength(1);
|
|
expect(result[0]).toMatchObject({
|
|
type: "user",
|
|
session_id: "",
|
|
message: {
|
|
role: "user",
|
|
content: [{ type: "text", text: "Hello!" }],
|
|
},
|
|
parent_tool_use_id: null,
|
|
});
|
|
});
|
|
|
|
it("should convert single assistant message", () => {
|
|
const history: ConversationMessage[] = [
|
|
{ role: "assistant", content: "Hi there!" },
|
|
];
|
|
const result = convertHistoryToMessages(history);
|
|
|
|
expect(result).toHaveLength(1);
|
|
expect(result[0]).toMatchObject({
|
|
type: "assistant",
|
|
session_id: "",
|
|
message: {
|
|
role: "assistant",
|
|
content: [{ type: "text", text: "Hi there!" }],
|
|
},
|
|
parent_tool_use_id: null,
|
|
});
|
|
});
|
|
|
|
it("should preserve array content as-is", () => {
|
|
const content = [
|
|
{ type: "text", text: "Text" },
|
|
{ type: "image", source: { data: "..." } },
|
|
];
|
|
const history: ConversationMessage[] = [{ role: "user", content }];
|
|
const result = convertHistoryToMessages(history);
|
|
|
|
expect(result[0].message.content).toEqual(content);
|
|
});
|
|
|
|
it("should convert multiple messages", () => {
|
|
const history: ConversationMessage[] = [
|
|
{ role: "user", content: "First" },
|
|
{ role: "assistant", content: "Second" },
|
|
{ role: "user", content: "Third" },
|
|
];
|
|
const result = convertHistoryToMessages(history);
|
|
|
|
expect(result).toHaveLength(3);
|
|
expect(result[0].type).toBe("user");
|
|
expect(result[1].type).toBe("assistant");
|
|
expect(result[2].type).toBe("user");
|
|
});
|
|
|
|
it("should set session_id to empty string", () => {
|
|
const history: ConversationMessage[] = [
|
|
{ role: "user", content: "Test" },
|
|
];
|
|
const result = convertHistoryToMessages(history);
|
|
|
|
expect(result[0].session_id).toBe("");
|
|
});
|
|
|
|
it("should set parent_tool_use_id to null", () => {
|
|
const history: ConversationMessage[] = [
|
|
{ role: "user", content: "Test" },
|
|
];
|
|
const result = convertHistoryToMessages(history);
|
|
|
|
expect(result[0].parent_tool_use_id).toBeNull();
|
|
});
|
|
|
|
it("should normalize string content to blocks", () => {
|
|
const history: ConversationMessage[] = [
|
|
{ role: "user", content: "String content" },
|
|
];
|
|
const result = convertHistoryToMessages(history);
|
|
|
|
expect(result[0].message.content).toEqual([
|
|
{ type: "text", text: "String content" },
|
|
]);
|
|
});
|
|
});
|
|
});
|