claude-code-best/src/utils/__tests__/notebook.test.ts
claude-code-best 4f323efb61 test: Phase 5 — 添加 12 个测试文件 (+209 tests, 1177 total)
新增覆盖: effort, tokenBudget, displayTags, taggedId,
controlMessageCompat, MCP normalization/envExpansion,
gitConfigParser, formatBriefTimestamp, hyperlink, windowsPaths, notebook

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-02 10:11:43 +08:00

163 lines
4.6 KiB
TypeScript

import { describe, expect, test } from "bun:test";
import { parseCellId, mapNotebookCellsToToolResult } from "../notebook";
// ─── parseCellId ───────────────────────────────────────────────────────
describe("parseCellId", () => {
test("parses cell-0 to 0", () => {
expect(parseCellId("cell-0")).toBe(0);
});
test("parses cell-5 to 5", () => {
expect(parseCellId("cell-5")).toBe(5);
});
test("parses cell-100 to 100", () => {
expect(parseCellId("cell-100")).toBe(100);
});
test("returns undefined for cell- (no number)", () => {
expect(parseCellId("cell-")).toBeUndefined();
});
test("returns undefined for cell-abc (non-numeric)", () => {
expect(parseCellId("cell-abc")).toBeUndefined();
});
test("returns undefined for other-format", () => {
expect(parseCellId("other-format")).toBeUndefined();
});
test("returns undefined for empty string", () => {
expect(parseCellId("")).toBeUndefined();
});
test("returns undefined for prefix-only match like cell-0-extra", () => {
// regex is /^cell-(\d+)$/ so trailing text should fail
expect(parseCellId("cell-0-extra")).toBeUndefined();
});
});
// ─── mapNotebookCellsToToolResult ──────────────────────────────────────
describe("mapNotebookCellsToToolResult", () => {
test("returns tool result with correct tool_use_id", () => {
const data = [
{
cellType: "code",
source: 'print("hello")',
cell_id: "cell-0",
language: "python",
},
];
const result = mapNotebookCellsToToolResult(data, "tool-123");
expect(result.tool_use_id).toBe("tool-123");
expect(result.type).toBe("tool_result");
});
test("content array contains text blocks for cell content", () => {
const data = [
{
cellType: "code",
source: 'x = 1',
cell_id: "cell-0",
language: "python",
},
];
const result = mapNotebookCellsToToolResult(data, "tool-1");
expect(result.content).toBeInstanceOf(Array);
expect(result.content!.length).toBeGreaterThanOrEqual(1);
const firstBlock = result.content![0] as { type: string; text: string };
expect(firstBlock.type).toBe("text");
expect(firstBlock.text).toContain("cell-0");
expect(firstBlock.text).toContain("x = 1");
});
test("merges adjacent text blocks from multiple cells", () => {
const data = [
{
cellType: "code",
source: "a = 1",
cell_id: "cell-0",
language: "python",
},
{
cellType: "code",
source: "b = 2",
cell_id: "cell-1",
language: "python",
},
];
const result = mapNotebookCellsToToolResult(data, "tool-2");
// Two adjacent text blocks should be merged into one
const textBlocks = result.content!.filter(
(b: any) => b.type === "text"
);
expect(textBlocks).toHaveLength(1);
});
test("preserves image blocks without merging", () => {
const data = [
{
cellType: "code",
source: "plot()",
cell_id: "cell-0",
language: "python",
outputs: [
{
output_type: "display_data",
text: "",
image: {
image_data: "iVBORw0KGgo=",
media_type: "image/png" as const,
},
},
],
},
{
cellType: "code",
source: "print(1)",
cell_id: "cell-1",
language: "python",
},
];
const result = mapNotebookCellsToToolResult(data, "tool-3");
const types = result.content!.map((b: any) => b.type);
expect(types).toContain("image");
});
test("markdown cell includes cell_type metadata", () => {
const data = [
{
cellType: "markdown",
source: "# Title",
cell_id: "cell-0",
},
];
const result = mapNotebookCellsToToolResult(data, "tool-4");
const textBlock = result.content![0] as { type: string; text: string };
expect(textBlock.text).toContain("<cell_type>markdown</cell_type>");
});
test("non-python code cell includes language metadata", () => {
const data = [
{
cellType: "code",
source: "val x = 1",
cell_id: "cell-0",
language: "scala",
},
];
const result = mapNotebookCellsToToolResult(data, "tool-5");
const textBlock = result.content![0] as { type: string; text: string };
expect(textBlock.text).toContain("<language>scala</language>");
});
});