mirror of
https://github.com/garrytan/gstack.git
synced 2026-05-05 13:15:24 +02:00
87cb769c35
- 005_sync_heartbeats.sql migration for connectivity testing - eval:trend --team flag pulls team eval data (graceful fallback) - docs/TEAM_SYNC_SETUP.md step-by-step setup guide - Design doc status updated to Phase 2 complete - 10 new tests for sync show formatting functions Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
109 lines
3.5 KiB
TypeScript
109 lines
3.5 KiB
TypeScript
/**
|
|
* Tests for sync show formatting functions (pure, no network).
|
|
*/
|
|
|
|
import { describe, test, expect } from 'bun:test';
|
|
import { formatTeamSummary, formatEvalTable, formatShipTable, formatRelativeTime } from '../lib/cli-sync';
|
|
|
|
describe('formatRelativeTime', () => {
|
|
test('returns "just now" for recent timestamps', () => {
|
|
expect(formatRelativeTime(new Date().toISOString())).toBe('just now');
|
|
});
|
|
|
|
test('returns minutes for recent past', () => {
|
|
const fiveMinAgo = new Date(Date.now() - 5 * 60_000).toISOString();
|
|
expect(formatRelativeTime(fiveMinAgo)).toBe('5m ago');
|
|
});
|
|
|
|
test('returns hours for older past', () => {
|
|
const threeHoursAgo = new Date(Date.now() - 3 * 3_600_000).toISOString();
|
|
expect(formatRelativeTime(threeHoursAgo)).toBe('3h ago');
|
|
});
|
|
|
|
test('returns days for old past', () => {
|
|
const twoDaysAgo = new Date(Date.now() - 2 * 86_400_000).toISOString();
|
|
expect(formatRelativeTime(twoDaysAgo)).toBe('2d ago');
|
|
});
|
|
});
|
|
|
|
describe('formatTeamSummary', () => {
|
|
test('formats summary with data', () => {
|
|
const output = formatTeamSummary({
|
|
teamSlug: 'test-team',
|
|
evalRuns: [
|
|
{ timestamp: new Date().toISOString(), user_id: 'u1', tests: [{ detection_rate: 4 }] },
|
|
{ timestamp: new Date().toISOString(), user_id: 'u2', tests: [{ detection_rate: 5 }] },
|
|
],
|
|
shipLogs: [
|
|
{ created_at: new Date().toISOString() },
|
|
],
|
|
retroSnapshots: [
|
|
{ date: '2026-03-15', streak_days: 47 },
|
|
],
|
|
queueSize: 0,
|
|
cacheLastPull: new Date().toISOString(),
|
|
});
|
|
|
|
expect(output).toContain('test-team');
|
|
expect(output).toContain('2 runs');
|
|
expect(output).toContain('2 contributors');
|
|
expect(output).toContain('1 PRs');
|
|
expect(output).toContain('4.5'); // avg detection
|
|
expect(output).toContain('streak: 47d');
|
|
expect(output).toContain('0 items');
|
|
});
|
|
|
|
test('handles empty data gracefully', () => {
|
|
const output = formatTeamSummary({
|
|
teamSlug: 'empty-team',
|
|
evalRuns: [],
|
|
shipLogs: [],
|
|
retroSnapshots: [],
|
|
queueSize: 3,
|
|
cacheLastPull: null,
|
|
});
|
|
|
|
expect(output).toContain('empty-team');
|
|
expect(output).toContain('0 runs');
|
|
expect(output).toContain('0 PRs');
|
|
expect(output).toContain('3 items');
|
|
expect(output).toContain('never');
|
|
});
|
|
});
|
|
|
|
describe('formatEvalTable', () => {
|
|
test('formats eval runs as table', () => {
|
|
const output = formatEvalTable([
|
|
{ timestamp: '2026-03-15T12:00:00Z', branch: 'main', passed: 10, total_tests: 10, total_cost_usd: 2.50, tier: 'e2e' },
|
|
]);
|
|
|
|
expect(output).toContain('Recent Eval Runs');
|
|
expect(output).toContain('2026-03-15');
|
|
expect(output).toContain('main');
|
|
expect(output).toContain('10/10');
|
|
expect(output).toContain('$2.50');
|
|
expect(output).toContain('e2e');
|
|
});
|
|
|
|
test('returns message for empty data', () => {
|
|
expect(formatEvalTable([])).toContain('No eval runs yet');
|
|
});
|
|
});
|
|
|
|
describe('formatShipTable', () => {
|
|
test('formats ship logs as table', () => {
|
|
const output = formatShipTable([
|
|
{ created_at: '2026-03-15T12:00:00Z', version: '0.3.10', branch: 'feature/sync', pr_url: 'https://github.com/org/repo/pull/1' },
|
|
]);
|
|
|
|
expect(output).toContain('Recent Ship Logs');
|
|
expect(output).toContain('0.3.10');
|
|
expect(output).toContain('feature/sync');
|
|
expect(output).toContain('github.com');
|
|
});
|
|
|
|
test('returns message for empty data', () => {
|
|
expect(formatShipTable([])).toContain('No ship logs yet');
|
|
});
|
|
});
|