118 lines
3.1 KiB
TypeScript
118 lines
3.1 KiB
TypeScript
import test from "node:test";
|
|
import assert from "node:assert/strict";
|
|
import { formatFetchOutput, formatSearchOutput, truncateText } from "./format.ts";
|
|
|
|
test("formatSearchOutput renders a compact metadata-only list", () => {
|
|
const output = formatSearchOutput({
|
|
providerName: "exa-main",
|
|
results: [
|
|
{
|
|
title: "Exa Docs",
|
|
url: "https://exa.ai/docs",
|
|
publishedDate: "2026-04-09",
|
|
author: "Exa",
|
|
score: 0.98,
|
|
},
|
|
],
|
|
});
|
|
|
|
assert.match(output, /Found 1 web result via exa-main:/);
|
|
assert.match(output, /Exa Docs/);
|
|
assert.match(output, /https:\/\/exa.ai\/docs/);
|
|
});
|
|
|
|
test("formatSearchOutput shows answer and fallback provider metadata", () => {
|
|
const output = formatSearchOutput({
|
|
providerName: "exa-fallback",
|
|
answer: "pi is a coding agent",
|
|
execution: {
|
|
actualProviderName: "exa-fallback",
|
|
attempts: [
|
|
{
|
|
providerName: "firecrawl-main",
|
|
status: "failed",
|
|
reason: "503 upstream unavailable",
|
|
},
|
|
{
|
|
providerName: "exa-fallback",
|
|
status: "succeeded",
|
|
},
|
|
],
|
|
},
|
|
results: [
|
|
{
|
|
title: "pi docs",
|
|
url: "https://pi.dev",
|
|
rawContent: "Very long raw content body",
|
|
},
|
|
],
|
|
} as any);
|
|
|
|
assert.match(output, /Answer: pi is a coding agent/);
|
|
assert.match(output, /Fallback: firecrawl-main -> exa-fallback/);
|
|
});
|
|
|
|
test("truncateText shortens long fetch bodies with an ellipsis", () => {
|
|
assert.equal(truncateText("abcdef", 4), "abc…");
|
|
assert.equal(truncateText("abc", 10), "abc");
|
|
});
|
|
|
|
test("formatFetchOutput includes both successful and failed URLs", () => {
|
|
const output = formatFetchOutput(
|
|
{
|
|
providerName: "exa-main",
|
|
results: [
|
|
{
|
|
url: "https://good.example",
|
|
title: "Good",
|
|
text: "This is a very long body that should be truncated in the final output.",
|
|
},
|
|
{
|
|
url: "https://bad.example",
|
|
title: null,
|
|
error: "429 rate limited",
|
|
},
|
|
],
|
|
},
|
|
{ maxCharactersPerResult: 20 },
|
|
);
|
|
|
|
assert.match(output, /Status: ok/);
|
|
assert.match(output, /Status: failed/);
|
|
assert.match(output, /429 rate limited/);
|
|
assert.match(output, /This is a very long…/);
|
|
});
|
|
|
|
test("formatFetchOutput shows fallback metadata and favicon/images when present", () => {
|
|
const output = formatFetchOutput({
|
|
providerName: "exa-fallback",
|
|
execution: {
|
|
actualProviderName: "exa-fallback",
|
|
attempts: [
|
|
{
|
|
providerName: "tavily-main",
|
|
status: "failed",
|
|
reason: "503 upstream unavailable",
|
|
},
|
|
{
|
|
providerName: "exa-fallback",
|
|
status: "succeeded",
|
|
},
|
|
],
|
|
},
|
|
results: [
|
|
{
|
|
url: "https://pi.dev",
|
|
title: "pi",
|
|
text: "Fetched body",
|
|
favicon: "https://pi.dev/favicon.ico",
|
|
images: ["https://pi.dev/logo.png"],
|
|
},
|
|
],
|
|
} as any);
|
|
|
|
assert.match(output, /Fallback: tavily-main -> exa-fallback/);
|
|
assert.match(output, /Favicon: https:\/\/pi.dev\/favicon.ico/);
|
|
assert.match(output, /Images:/);
|
|
});
|