Add projects

This commit is contained in:
Alois 2026-08-24 00:10:41 +02:00
commit 8b607dd700
Signed by: alois
SSH key fingerprint: SHA256:GBzT2DXvAuGV9XIV5W3WrzVpjU54FThmxHXdbz95J24
1802 changed files with 503346 additions and 2 deletions

View file

@ -0,0 +1,133 @@
import { describe, expect, test } from 'vitest';
import { formatCompactNumber, formatPercent } from '../src/utils/format';
import { getProviderKeyCounts } from '../src/features/dashboard/hooks/useDashboardOverview';
import {
axisMax,
niceCeil,
providerLabel,
splitWindowMinutes,
toneForSuccessRate,
} from '../src/features/dashboard/utils';
describe('formatCompactNumber', () => {
test('leaves values below one thousand alone', () => {
expect(formatCompactNumber(0)).toBe('0');
expect(formatCompactNumber(999)).toBe('999');
});
test('compacts with a single decimal and no redundant .0', () => {
expect(formatCompactNumber(1000)).toBe('1K');
expect(formatCompactNumber(1284)).toBe('1.3K');
expect(formatCompactNumber(12_900)).toBe('12.9K');
expect(formatCompactNumber(1_500_000)).toBe('1.5M');
});
test('carries into the next tier instead of rendering 1000K', () => {
expect(formatCompactNumber(999_999)).toBe('1M');
expect(formatCompactNumber(999_999_999)).toBe('1B');
});
test('keeps the sign and survives non-finite input', () => {
expect(formatCompactNumber(-1500)).toBe('-1.5K');
expect(formatCompactNumber(Number.NaN)).toBe('0');
});
});
describe('formatPercent', () => {
test('trims trailing zeros but keeps meaningful decimals', () => {
expect(formatPercent(100)).toBe('100%');
expect(formatPercent(99.5)).toBe('99.5%');
expect(formatPercent(0)).toBe('0%');
});
test('renders an em dash for non-finite rates', () => {
expect(formatPercent(Number.NaN)).toBe('—');
});
});
describe('niceCeil', () => {
test('rounds up onto the step ladder', () => {
expect(niceCeil(1)).toBe(1);
expect(niceCeil(7)).toBe(8);
expect(niceCeil(12)).toBe(15);
expect(niceCeil(48)).toBe(50);
expect(niceCeil(320)).toBe(400);
});
test('never returns zero, so bar heights cannot divide by zero', () => {
expect(niceCeil(0)).toBe(1);
expect(niceCeil(-5)).toBe(1);
});
});
describe('axisMax', () => {
test('lands every gridline on a whole number', () => {
// 峰值 112 → 上限 120刻度 0/30/60/90/120而不是浪费半张图的 200
expect(axisMax(112, 4)).toBe(120);
expect(axisMax(7, 4)).toBe(8);
expect(axisMax(1533, 4)).toBe(1600);
});
test('keeps the axis just above the peak', () => {
for (const peak of [1, 3, 9, 17, 64, 112, 250, 999, 4321]) {
const max = axisMax(peak, 4);
expect(max).toBeGreaterThanOrEqual(peak);
// 上限不应超过峰值的两倍,否则柱子被压得太矮。
// 峰值极小时受「每格至少 1」约束下限就是间隔数本身。
expect(max).toBeLessThanOrEqual(Math.max(4, peak * 2));
// 每格都必须是整数
expect(Number.isInteger(max / 4)).toBe(true);
}
});
test('degrades safely with no traffic', () => {
expect(axisMax(0, 4)).toBe(4);
expect(axisMax(-3, 4)).toBe(4);
});
});
describe('toneForSuccessRate', () => {
test('maps a rate onto a severity band', () => {
expect(toneForSuccessRate(null)).toBe('idle');
expect(toneForSuccessRate(100)).toBe('good');
expect(toneForSuccessRate(95)).toBe('good');
expect(toneForSuccessRate(94.9)).toBe('warning');
expect(toneForSuccessRate(80)).toBe('warning');
expect(toneForSuccessRate(79.9)).toBe('critical');
});
});
describe('splitWindowMinutes', () => {
test('splits the rolling window into hours and minutes', () => {
expect(splitWindowMinutes(200)).toEqual({ hours: 3, minutes: 20 });
expect(splitWindowMinutes(60)).toEqual({ hours: 1, minutes: 0 });
expect(splitWindowMinutes(40)).toEqual({ hours: 0, minutes: 40 });
});
});
describe('provider key counts', () => {
test('includes native Interactions API keys in the dashboard total inputs', () => {
const counts = getProviderKeyCounts({
geminiApiKeys: [{ apiKey: 'gemini-key' }],
interactionsApiKeys: [{ apiKey: 'interactions-1' }, { apiKey: 'interactions-2' }],
codexApiKeys: [{ apiKey: 'codex-key' }],
});
expect(counts.interactions).toBe(2);
expect(Object.values(counts).reduce((sum, count) => sum + count, 0)).toBe(4);
});
});
describe('providerLabel', () => {
test('uses the brand spelling for known providers', () => {
expect(providerLabel('xai', 'Unattributed')).toBe('xAI');
expect(providerLabel('aistudio', 'Unattributed')).toBe('AI Studio');
expect(providerLabel('gemini-interactions', 'Unattributed')).toBe('Interactions API');
});
test('falls back to a capitalised id, and localises unknown', () => {
expect(providerLabel('somenewbrand', 'Unattributed')).toBe('Somenewbrand');
expect(providerLabel('unknown', 'Unattributed')).toBe('Unattributed');
expect(providerLabel('', 'Unattributed')).toBe('Unattributed');
});
});