Skip to content

Commit c6dce15

Browse files
committed
test: assert directory-outline honesty at the rendered plain-text surface
The e2e expectations still parsed the legacy directory-JSON envelope. Assert the plain-text contract instead, at the surface the agent sees: partial-result and skipped-file footers rather than raw JSON fields.
1 parent a8d6648 commit c6dce15

2 files changed

Lines changed: 35 additions & 44 deletions

File tree

packages/opencode-plugin/src/__tests__/e2e/honest-reporting.test.ts

Lines changed: 12 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -122,16 +122,14 @@ export function runHonestReportingSuite(
122122
const output = toolResultText(
123123
await tools.aft_outline.execute({ target: "outline-small" }, sdkCtx),
124124
);
125-
const response = JSON.parse(output) as Record<string, unknown>;
126-
127-
expect(response.complete).toBe(true);
128-
expect(response.walk_truncated).toBe(false);
129-
const skipped = response.skipped_files as Array<{ file: string; reason: string }>;
130-
expect(skipped).toHaveLength(1);
131-
expect(skipped[0].file).toMatch(/outline-small[/\\]bad\.ts$/);
132-
expect(skipped[0].reason).toBe("parse_error");
133-
expect(String(response.text)).toContain("good.ts");
134-
expect(String(response.text)).toContain("good");
125+
126+
// Directory outlines are plain text; honesty data arrives as footers.
127+
expect(() => JSON.parse(output)).toThrow();
128+
expect(output).toContain("good.ts");
129+
expect(output).toContain("good");
130+
expect(output).not.toContain("⚠ Partial result");
131+
expect(output).toContain("Skipped 1 file(s):");
132+
expect(output).toMatch(/bad\.ts parse_error/);
135133
});
136134

137135
test("aft_outline directory mode returns complete false when Rust walk truncates", async () => {
@@ -148,12 +146,11 @@ export function runHonestReportingSuite(
148146
const output = toolResultText(
149147
await tools.aft_outline.execute({ target: "outline-large" }, sdkCtx),
150148
);
151-
const response = JSON.parse(output) as Record<string, unknown>;
152149

153-
expect(response.complete).toBe(false);
154-
expect(response.walk_truncated).toBe(true);
155-
expect(Array.isArray(response.skipped_files)).toBe(true);
156-
expect(String(response.text)).toContain("file-000.ts");
150+
// Truncation is disclosed in the plain-text partial-result footer.
151+
expect(() => JSON.parse(output)).toThrow();
152+
expect(output).toContain("file-000.ts");
153+
expect(output).toContain("⚠ Partial result: walk truncated at 200 files.");
157154
});
158155

159156
test("aft_outline single file target keeps text output behavior", async () => {

packages/opencode-plugin/src/__tests__/e2e/read-only-spine-toolcall.test.ts

Lines changed: 23 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -174,25 +174,20 @@ export function runReadOnlySpineToolcallSuite(
174174
expect(output).toContain("ToolCallOutlineService");
175175
});
176176

177-
test("aft_outline returns structured directory JSON through tool_call", async () => {
177+
test("aft_outline returns plain-text directory outline through tool_call", async () => {
178178
const h = await harness();
179179
const tools = readingTools(createPluginContext(h));
180180

181181
const output = await tools.aft_outline.execute({ target: "src" }, createToolContext(h));
182-
const parsed = JSON.parse(output) as {
183-
success?: boolean;
184-
complete?: boolean;
185-
text?: string;
186-
skipped_files?: unknown[];
187-
};
188-
189-
expect(parsed.success).toBe(true);
190-
expect(parsed.complete).toBe(true);
191-
expect(parsed.text).toContain("src/");
192-
expect(parsed.text).toContain("hit.ts");
193-
expect(parsed.text).toContain("toolCallOutlineFunction");
194-
expect(parsed.text).not.toContain("hit.test.ts");
195-
expect(parsed.skipped_files).toEqual([]);
182+
183+
// Directory outlines render as plain text like every other outline
184+
// mode; a complete walk carries no partial-result footer.
185+
expect(() => JSON.parse(output)).toThrow();
186+
expect(output).toContain("src/");
187+
expect(output).toContain("hit.ts");
188+
expect(output).toContain("toolCallOutlineFunction");
189+
expect(output).not.toContain("hit.test.ts");
190+
expect(output).not.toContain("⚠ Partial result");
196191
});
197192

198193
test("aft_outline files:true returns the server-rendered files tree through tool_call", async () => {
@@ -230,20 +225,19 @@ export function runReadOnlySpineToolcallSuite(
230225
const h = await harness();
231226
const tools = readingTools(createPluginContext(h));
232227

233-
const withoutTests = JSON.parse(
234-
await tools.aft_outline.execute({ target: "src" }, createToolContext(h)),
235-
) as { text?: string };
236-
const withTests = JSON.parse(
237-
await tools.aft_outline.execute(
238-
{ target: "src", includeTests: true },
239-
createToolContext(h),
240-
),
241-
) as { text?: string };
242-
243-
expect(withoutTests.text).not.toContain("hit.test.ts");
244-
expect(withoutTests.text).not.toContain("toolCallOutlineTestOnly");
245-
expect(withTests.text).toContain("hit.test.ts");
246-
expect(withTests.text).toContain("toolCallOutlineTestOnly");
228+
const withoutTests = await tools.aft_outline.execute(
229+
{ target: "src" },
230+
createToolContext(h),
231+
);
232+
const withTests = await tools.aft_outline.execute(
233+
{ target: "src", includeTests: true },
234+
createToolContext(h),
235+
);
236+
237+
expect(withoutTests).not.toContain("hit.test.ts");
238+
expect(withoutTests).not.toContain("toolCallOutlineTestOnly");
239+
expect(withTests).toContain("hit.test.ts");
240+
expect(withTests).toContain("toolCallOutlineTestOnly");
247241
});
248242
});
249243
}

0 commit comments

Comments
 (0)