nandi/oripublic Fork 0
b6cd929ab1425a4ef6073ea9c189917cca02cf3c
Commits
Clone
git clone https://git.rickub.com/nandi/ori.git
git clone ssh://git@rickub.com/nandi/ori.git

Host key fingerprint (ed25519): SHA256:iycHnxEyq0Q7uyVpB7JlznP0G7JrTPXLYRcAU5CSLhc — verify it before your first connect.

forked from bots-garden/ori

ToolCallCard.test.tsx · 110 lines · 3.0 KBTypeScript Blame HistoryRaw
✨ Workspace panel, selectors, previews, desktop app, sandbox template, resizable file tree, light/dark theme 76d62ac k33g yesterday1import { render, screen } from "@testing-library/react";
2import { describe, expect, it } from "vitest";
3import type { ToolCall } from "../reducer";
✨ Switch the ACP adapter to @agentclientprotocol/claude-agent-acp (template 0.0.2) 5d476ff k33g 22h ago4import { ToolCallCard, contentText, toolContentText } from "./ToolCallCard";
✨ Workspace panel, selectors, previews, desktop app, sandbox template, resizable file tree, light/dark theme 76d62ac k33g yesterday5
6function call(overrides: Partial<ToolCall>): ToolCall {
7 return {
8 toolCallId: "c1",
9 title: "A tool call",
10 toolKind: "other",
11 status: "completed",
12 contents: [],
13 locations: [],
14 ...overrides,
15 };
16}
17
18describe("ToolCallCard", () => {
19 it("renders execute output verbatim in a monospace block", () => {
20 const { container } = render(
21 <ToolCallCard
22 call={call({
23 toolKind: "execute",
24 contents: [
25 {
26 type: "content",
27 content: { type: "text", text: "* main\n remote/origin" },
28 },
29 ],
30 })}
31 />,
32 );
33
34 const output = container.querySelector("pre.tool-output");
35 expect(output).not.toBeNull();
36 // Verbatim: the "* " prefix must not have become a markdown list.
37 expect(output?.textContent).toBe("* main\n remote/origin");
38 expect(container.querySelector("ul li")).toBeNull();
39 });
40
41 it("renders backticked commands in the title as monospace code", () => {
42 const { container } = render(
43 <ToolCallCard
44 call={call({ toolKind: "execute", title: "Run `ls .memory/`" })}
45 />,
46 );
47
48 const code = container.querySelector(".tool-title code.inline-code");
49 expect(code?.textContent).toBe("ls .memory/");
50 });
51
52 it("renders non-execute text content as markdown", () => {
53 const { container } = render(
54 <ToolCallCard
55 call={call({
56 toolKind: "read",
57 contents: [
58 {
59 type: "content",
60 content: { type: "text", text: "**bold** result" },
61 },
62 ],
63 })}
64 />,
65 );
66
67 expect(container.querySelector("pre.tool-output")).toBeNull();
68 expect(screen.getByText("bold")).toBeDefined();
69 });
70});
✨ Switch the ACP adapter to @agentclientprotocol/claude-agent-acp (template 0.0.2) 5d476ff k33g 22h ago71
72describe("toolContentText", () => {
73 it("returns the text of content blocks", () => {
74 expect(
75 contentText({ type: "content", content: { type: "text", text: "hi" } }),
76 ).toBe("hi");
77 });
78
79 it("flattens a diff into labelled path, old and new sections", () => {
80 expect(
81 contentText({ type: "diff", path: "a.go", oldText: "x", newText: "y" }),
82 ).toBe("Path: a.go\n\nOld:\nx\n\nNew:\ny");
83 });
84
85 it("omits diff sections that are absent", () => {
86 expect(contentText({ type: "diff", path: "a.go", newText: "y" })).toBe(
87 "Path: a.go\n\nNew:\ny",
88 );
89 });
90
91 it("ignores terminal blocks and joins the rest with blank lines", () => {
92 expect(
93 toolContentText([
94 { type: "terminal", terminalId: "t1" },
95 { type: "content", content: { type: "text", text: "one" } },
96 { type: "content", content: { type: "text", text: "" } },
97 { type: "content", content: { type: "text", text: "two" } },
98 ]),
99 ).toBe("one\n\ntwo");
100 });
101
102 it("hides the copy button when the call has no textual content", () => {
103 render(
104 <ToolCallCard
105 call={call({ contents: [{ type: "terminal", terminalId: "t1" }] })}
106 />,
107 );
108 expect(screen.queryByLabelText("Copy tool output")).toBeNull();
109 });
110});