100 lines
2.5 KiB
TypeScript
100 lines
2.5 KiB
TypeScript
import assert from "node:assert/strict";
|
|
import { describe, test } from "vitest";
|
|
|
|
/**
|
|
* Regression tests for dashboard metric fallback chain.
|
|
*
|
|
* The dashboard reads metrics from two sources:
|
|
* 1. projectTotals (polled from /api/visualizer — always available)
|
|
* 2. auto (live auto-mode data — null when auto is not active)
|
|
*
|
|
* Fallback chain: projectTotals?.X ?? auto?.X ?? 0
|
|
*
|
|
* See: https://github.com/singularity-forge/sf-run/issues/2709
|
|
*/
|
|
|
|
interface ProjectTotals {
|
|
duration: number;
|
|
cost: number;
|
|
tokens: { total: number };
|
|
}
|
|
|
|
interface AutoDashboard {
|
|
elapsed: number;
|
|
totalCost: number;
|
|
totalTokens: number;
|
|
}
|
|
|
|
/** Mirrors the fallback logic in dashboard.tsx */
|
|
function deriveMetrics(
|
|
projectTotals: ProjectTotals | null,
|
|
auto: AutoDashboard | null,
|
|
) {
|
|
return {
|
|
elapsed: projectTotals?.duration ?? auto?.elapsed ?? 0,
|
|
totalCost: projectTotals?.cost ?? auto?.totalCost ?? 0,
|
|
totalTokens: projectTotals?.tokens.total ?? auto?.totalTokens ?? 0,
|
|
};
|
|
}
|
|
|
|
describe("dashboard metric fallback (#2709 regression)", () => {
|
|
test("returns zero when both sources are null", () => {
|
|
const result = deriveMetrics(null, null);
|
|
assert.equal(result.elapsed, 0);
|
|
assert.equal(result.totalCost, 0);
|
|
assert.equal(result.totalTokens, 0);
|
|
});
|
|
|
|
test("uses auto data when projectTotals is null", () => {
|
|
const auto: AutoDashboard = {
|
|
elapsed: 5000,
|
|
totalCost: 1.5,
|
|
totalTokens: 10000,
|
|
};
|
|
const result = deriveMetrics(null, auto);
|
|
assert.equal(result.elapsed, 5000);
|
|
assert.equal(result.totalCost, 1.5);
|
|
assert.equal(result.totalTokens, 10000);
|
|
});
|
|
|
|
test("uses projectTotals when auto is null (manual mode)", () => {
|
|
const totals: ProjectTotals = {
|
|
duration: 60000,
|
|
cost: 3.2,
|
|
tokens: { total: 50000 },
|
|
};
|
|
const result = deriveMetrics(totals, null);
|
|
assert.equal(result.elapsed, 60000);
|
|
assert.equal(result.totalCost, 3.2);
|
|
assert.equal(result.totalTokens, 50000);
|
|
});
|
|
|
|
test("projectTotals takes precedence over auto when both present", () => {
|
|
const totals: ProjectTotals = {
|
|
duration: 120000,
|
|
cost: 5.0,
|
|
tokens: { total: 80000 },
|
|
};
|
|
const auto: AutoDashboard = {
|
|
elapsed: 10000,
|
|
totalCost: 0.5,
|
|
totalTokens: 5000,
|
|
};
|
|
const result = deriveMetrics(totals, auto);
|
|
assert.equal(
|
|
result.elapsed,
|
|
120000,
|
|
"projectTotals duration should take precedence",
|
|
);
|
|
assert.equal(
|
|
result.totalCost,
|
|
5.0,
|
|
"projectTotals cost should take precedence",
|
|
);
|
|
assert.equal(
|
|
result.totalTokens,
|
|
80000,
|
|
"projectTotals tokens should take precedence",
|
|
);
|
|
});
|
|
});
|