Import the committed KnowledgeFS snapshot dc4072ee302317145612087ce7440851dc329fd0 under knowledge-fs/ without its Git history, local IDE settings, or build artifacts.
320 lines
8.5 KiB
TypeScript
320 lines
8.5 KiB
TypeScript
import { describe, expect, it } from "vitest";
|
|
|
|
import { createEvaluationDashboardSummary } from "./evaluation-dashboard";
|
|
|
|
describe("createEvaluationDashboardSummary", () => {
|
|
it("summarizes bounded evaluation runs for dashboard trends", () => {
|
|
const summary = createEvaluationDashboardSummary({
|
|
maxRuns: 5,
|
|
maxTrendPoints: 3,
|
|
runs: [
|
|
{
|
|
citationAccuracy: 0.79,
|
|
costUsd: 1.4,
|
|
failedQuestions: 3,
|
|
faithfulnessScore: 0.81,
|
|
id: "run-1",
|
|
latencyMs: 980,
|
|
recallAtK: 0.84,
|
|
runAt: "2026-05-13T10:00:00.000Z",
|
|
totalQuestions: 12,
|
|
},
|
|
{
|
|
citationAccuracy: 0.83,
|
|
costUsd: 1.1,
|
|
failedQuestions: 2,
|
|
faithfulnessScore: 0.86,
|
|
id: "run-2",
|
|
latencyMs: 870,
|
|
recallAtK: 0.88,
|
|
runAt: "2026-05-13T11:00:00.000Z",
|
|
totalQuestions: 12,
|
|
},
|
|
{
|
|
citationAccuracy: 0.9,
|
|
costUsd: 0.9,
|
|
failedQuestions: 1,
|
|
faithfulnessScore: 0.92,
|
|
id: "run-3",
|
|
latencyMs: 740,
|
|
recallAtK: 0.91,
|
|
runAt: "2026-05-13T12:00:00.000Z",
|
|
totalQuestions: 12,
|
|
},
|
|
],
|
|
});
|
|
|
|
expect(summary.latest).toMatchObject({
|
|
citationAccuracyLabel: "90%",
|
|
faithfulnessLabel: "92%",
|
|
passRateLabel: "92%",
|
|
recallLabel: "91%",
|
|
});
|
|
expect(summary.recallTrend.map((point) => point.label)).toEqual(["10:00", "11:00", "12:00"]);
|
|
expect(summary.recallTrend.map((point) => point.valueLabel)).toEqual(["84%", "88%", "91%"]);
|
|
expect(summary.citationTrend.map((point) => point.valueLabel)).toEqual(["79%", "83%", "90%"]);
|
|
expect(summary.costLatency).toEqual({
|
|
averageCostLabel: "$1.13",
|
|
averageLatencyLabel: "863 ms",
|
|
latestCostLabel: "$0.90",
|
|
latestLatencyLabel: "740 ms",
|
|
});
|
|
});
|
|
|
|
it("rejects unbounded dashboard inputs and invalid metric ranges", () => {
|
|
expect(() =>
|
|
createEvaluationDashboardSummary({
|
|
maxRuns: 0,
|
|
runs: [],
|
|
}),
|
|
).toThrow("Evaluation dashboard maxRuns must be at least 1");
|
|
|
|
expect(() =>
|
|
createEvaluationDashboardSummary({
|
|
maxRuns: 1,
|
|
runs: [
|
|
{
|
|
citationAccuracy: 0.5,
|
|
costUsd: 0,
|
|
failedQuestions: 0,
|
|
faithfulnessScore: 0.9,
|
|
id: "run-1",
|
|
latencyMs: 10,
|
|
recallAtK: 1.2,
|
|
runAt: "2026-05-13T10:00:00.000Z",
|
|
totalQuestions: 1,
|
|
},
|
|
],
|
|
}),
|
|
).toThrow("Evaluation dashboard recallAtK must be between 0 and 1");
|
|
|
|
expect(() =>
|
|
createEvaluationDashboardSummary({
|
|
maxRuns: 1,
|
|
runs: [
|
|
{
|
|
citationAccuracy: 0.5,
|
|
costUsd: 0,
|
|
failedQuestions: 2,
|
|
faithfulnessScore: 0.9,
|
|
id: "run-1",
|
|
latencyMs: 10,
|
|
recallAtK: 0.8,
|
|
runAt: "2026-05-13T10:00:00.000Z",
|
|
totalQuestions: 1,
|
|
},
|
|
],
|
|
}),
|
|
).toThrow("Evaluation dashboard failedQuestions cannot exceed totalQuestions");
|
|
|
|
expect(() =>
|
|
createEvaluationDashboardSummary({
|
|
maxRuns: 1,
|
|
runs: [
|
|
{
|
|
citationAccuracy: 0.5,
|
|
costUsd: 0,
|
|
failedQuestions: 0,
|
|
faithfulnessScore: 0.9,
|
|
id: " ",
|
|
latencyMs: 10,
|
|
recallAtK: 0.8,
|
|
runAt: "2026-05-13T10:00:00.000Z",
|
|
totalQuestions: 1,
|
|
},
|
|
],
|
|
}),
|
|
).toThrow("Evaluation dashboard run id is required");
|
|
|
|
expect(() =>
|
|
createEvaluationDashboardSummary({
|
|
maxRuns: 1,
|
|
runs: [
|
|
{
|
|
citationAccuracy: 0.5,
|
|
costUsd: 0,
|
|
failedQuestions: 0,
|
|
faithfulnessScore: 0.9,
|
|
id: "run-1",
|
|
latencyMs: 10,
|
|
recallAtK: 0.8,
|
|
runAt: "not-a-date",
|
|
totalQuestions: 1,
|
|
},
|
|
],
|
|
}),
|
|
).toThrow("Evaluation dashboard runAt must be a valid timestamp");
|
|
|
|
expect(() =>
|
|
createEvaluationDashboardSummary({
|
|
maxRuns: 1,
|
|
runs: [
|
|
{
|
|
citationAccuracy: -0.1,
|
|
costUsd: 0,
|
|
failedQuestions: 0,
|
|
faithfulnessScore: 0.9,
|
|
id: "run-1",
|
|
latencyMs: 10,
|
|
recallAtK: 0.8,
|
|
runAt: "2026-05-13T10:00:00.000Z",
|
|
totalQuestions: 1,
|
|
},
|
|
],
|
|
}),
|
|
).toThrow("Evaluation dashboard citationAccuracy must be between 0 and 1");
|
|
|
|
expect(() =>
|
|
createEvaluationDashboardSummary({
|
|
maxRuns: 1,
|
|
runs: [
|
|
{
|
|
citationAccuracy: 0.5,
|
|
costUsd: 0,
|
|
failedQuestions: 0,
|
|
faithfulnessScore: Number.NaN,
|
|
id: "run-1",
|
|
latencyMs: 10,
|
|
recallAtK: 0.8,
|
|
runAt: "2026-05-13T10:00:00.000Z",
|
|
totalQuestions: 1,
|
|
},
|
|
],
|
|
}),
|
|
).toThrow("Evaluation dashboard faithfulnessScore must be between 0 and 1");
|
|
|
|
expect(() =>
|
|
createEvaluationDashboardSummary({
|
|
maxRuns: 1,
|
|
runs: [
|
|
{
|
|
citationAccuracy: 0.5,
|
|
costUsd: 0,
|
|
failedQuestions: 0,
|
|
faithfulnessScore: 0.9,
|
|
id: "run-1",
|
|
latencyMs: 10,
|
|
recallAtK: 0.8,
|
|
runAt: "2026-05-13T10:00:00.000Z",
|
|
totalQuestions: 0,
|
|
},
|
|
],
|
|
}),
|
|
).toThrow("Evaluation dashboard totalQuestions must be at least 1");
|
|
|
|
expect(() =>
|
|
createEvaluationDashboardSummary({
|
|
maxRuns: 1,
|
|
runs: [
|
|
{
|
|
citationAccuracy: 0.5,
|
|
costUsd: 0,
|
|
failedQuestions: -1,
|
|
faithfulnessScore: 0.9,
|
|
id: "run-1",
|
|
latencyMs: 10,
|
|
recallAtK: 0.8,
|
|
runAt: "2026-05-13T10:00:00.000Z",
|
|
totalQuestions: 1,
|
|
},
|
|
],
|
|
}),
|
|
).toThrow("Evaluation dashboard failedQuestions must be non-negative");
|
|
|
|
expect(() =>
|
|
createEvaluationDashboardSummary({
|
|
maxRuns: 1,
|
|
runs: [
|
|
{
|
|
citationAccuracy: 0.5,
|
|
costUsd: -0.01,
|
|
failedQuestions: 0,
|
|
faithfulnessScore: 0.9,
|
|
id: "run-1",
|
|
latencyMs: 10,
|
|
recallAtK: 0.8,
|
|
runAt: "2026-05-13T10:00:00.000Z",
|
|
totalQuestions: 1,
|
|
},
|
|
],
|
|
}),
|
|
).toThrow("Evaluation dashboard costUsd must be non-negative");
|
|
|
|
expect(() =>
|
|
createEvaluationDashboardSummary({
|
|
maxRuns: 1,
|
|
runs: [
|
|
{
|
|
citationAccuracy: 0.5,
|
|
costUsd: 0,
|
|
failedQuestions: 0,
|
|
faithfulnessScore: 0.9,
|
|
id: "run-1",
|
|
latencyMs: -1,
|
|
recallAtK: 0.8,
|
|
runAt: "2026-05-13T10:00:00.000Z",
|
|
totalQuestions: 1,
|
|
},
|
|
],
|
|
}),
|
|
).toThrow("Evaluation dashboard latencyMs must be non-negative");
|
|
});
|
|
|
|
it("bounds run count and handles empty dashboard data", () => {
|
|
expect(() =>
|
|
createEvaluationDashboardSummary({
|
|
maxRuns: 1,
|
|
runs: [
|
|
{
|
|
citationAccuracy: 0.5,
|
|
costUsd: 0,
|
|
failedQuestions: 0,
|
|
faithfulnessScore: 0.9,
|
|
id: "run-1",
|
|
latencyMs: 10,
|
|
recallAtK: 0.8,
|
|
runAt: "2026-05-13T10:00:00.000Z",
|
|
totalQuestions: 1,
|
|
},
|
|
{
|
|
citationAccuracy: 0.6,
|
|
costUsd: 0,
|
|
failedQuestions: 0,
|
|
faithfulnessScore: 0.9,
|
|
id: "run-2",
|
|
latencyMs: 10,
|
|
recallAtK: 0.9,
|
|
runAt: "2026-05-13T11:00:00.000Z",
|
|
totalQuestions: 1,
|
|
},
|
|
],
|
|
}),
|
|
).toThrow("Evaluation dashboard runs exceeds maxRuns=1");
|
|
|
|
expect(() =>
|
|
createEvaluationDashboardSummary({
|
|
maxTrendPoints: 0,
|
|
runs: [],
|
|
}),
|
|
).toThrow("Evaluation dashboard maxTrendPoints must be at least 1");
|
|
|
|
expect(createEvaluationDashboardSummary({ runs: [] })).toEqual({
|
|
citationTrend: [],
|
|
costLatency: {
|
|
averageCostLabel: "$0.00",
|
|
averageLatencyLabel: "0 ms",
|
|
latestCostLabel: "$0.00",
|
|
latestLatencyLabel: "0 ms",
|
|
},
|
|
latest: {
|
|
citationAccuracyLabel: "0%",
|
|
faithfulnessLabel: "0%",
|
|
passRateLabel: "100%",
|
|
recallLabel: "0%",
|
|
runId: "",
|
|
},
|
|
recallTrend: [],
|
|
});
|
|
});
|
|
});
|