Files
AetherForge/server/web/src/help/pathTracerTimeline.test.ts
AetherForge d605ef4adb
Some checks failed
CI Docker Mining Proof / Linux agent hashrate proof (push) Has been cancelled
Add Strain Hospice for graceful low-win strain retirement.
Archive failed epidemiology strains to museum hospice with SQLite persistence, operator/AI/court triggers, breeding and graft guards, topology museum nodes, and Seer plus oath ledger accountability.
2026-06-07 09:26:39 -07:00

67 lines
1.9 KiB
TypeScript

/**
* @vitest-environment node
*/
import { describe, expect, it } from 'vitest';
import {
branchStatusClass,
ghostBranchesByHop,
mergeMermaidStyles,
pickMergeCandidate,
} from './pathTracerTimeline';
import type { PathTraceTimelineBranch } from './pathTracerTimeline';
function branch(partial: Partial<PathTraceTimelineBranch>): PathTraceTimelineBranch {
return {
id: 'b1',
fork_hop_index: 0,
status: 'running',
is_ghost: true,
...partial,
};
}
describe('pathTracerTimeline', () => {
it('groups ghost branches by fork hop', () => {
const map = ghostBranchesByHop([
branch({ id: 'a', fork_hop_index: 1 }),
branch({ id: 'b', fork_hop_index: 1 }),
branch({ id: 'c', fork_hop_index: 0 }),
]);
expect(map.get(1)?.map((b) => b.id)).toEqual(['a', 'b']);
expect(map.get(0)?.map((b) => b.id)).toEqual(['c']);
});
it('prefers won branch for merge candidate', () => {
const pick = pickMergeCandidate([
branch({ id: 'run', status: 'running' }),
branch({ id: 'win', status: 'won', mining_linked: true, hashrate: 120 }),
]);
expect(pick?.id).toBe('win');
});
it('skips hospice strains for fork-merge parent selection', () => {
const hospice = new Set(['#ab88e4']);
const pick = pickMergeCandidate(
[
branch({ id: 'hospice-win', status: 'won', spread_lanes: ['winrm'] }),
branch({ id: 'ok-run', status: 'running', spread_lanes: ['docker'] }),
],
hospice,
);
expect(pick?.id).toBe('ok-run');
});
it('maps status to CSS class', () => {
expect(branchStatusClass('won')).toBe('won');
expect(branchStatusClass('running')).toBe('running');
expect(branchStatusClass('failed')).toBe('failed');
});
it('appends mermaid classDef styles once', () => {
const raw = 'graph TD\n a --> b';
const styled = mergeMermaidStyles(raw);
expect(styled).toContain('classDef won');
expect(mergeMermaidStyles(styled)).toBe(styled);
});
});