Files
electric-cherry/tests/unit/metrics-insights.test.ts
T

92 lines
3.2 KiB
TypeScript

import { describe, expect, it } from 'vitest';
import { metricRecommendations } from '../../src/lib/metrics-insights.js';
import type { MapMetrics } from '../../src/lib/metrics.js';
const map = (values: Partial<MapMetrics> = {}): MapMetrics => ({
game: 't5',
map: 'Moon',
observed: 10,
active: 5,
idle: 5,
unknown: 0,
playerHours: 10,
full: 0,
capacityObserved: 5,
...values
});
describe('advisory hosting experiments', () => {
it('uses map capacity time rather than summed server time for expansion', () => {
const [result] = metricRecommendations([
map({ observed: 100, active: 50, idle: 50, full: 1, capacityObserved: 4 })
]);
expect(result.kind).toBe('expand');
expect(result.evidence).toContain('25.0%');
expect(result.tentative).toBe(false);
});
it('offers a tentative trial even with a tiny recorded sample', () => {
const [result] = metricRecommendations([
map({
observed: 1 / 120,
active: 1 / 120,
idle: 0,
full: 1 / 120,
capacityObserved: 1 / 120
})
]);
expect(result.kind).toBe('expand');
expect(result.tentative).toBe(true);
expect(result.evidence).toContain('30 s');
});
it('uses explicitly tentative occupancy advice when capacity is missing', () => {
const [result] = metricRecommendations([map({ active: 8, idle: 2, capacityObserved: 0 })]);
expect(result.kind).toBe('expand');
expect(result.tentative).toBe(true);
expect(result.reason).toContain('not evidence of saturation');
});
it('does not confuse unknown occupancy with an idle fleet', () => {
const [result] = metricRecommendations([
map({
observed: 0,
active: 0,
idle: 0,
unknown: 10,
playerHours: 0,
capacityObserved: 0
})
]);
expect(result.kind).toBe('capacity');
expect(result.title).toBe('Check occupancy reporting');
expect(result.tentative).toBe(true);
});
it('keeps advice scoped to input maps and considers idle trials with incomplete capacity', () => {
const [result] = metricRecommendations([
map({ game: 't6', map: 'Town', active: 1, idle: 9, capacityObserved: 0 })
]);
expect(result).toMatchObject({
game: 't6',
map: 'Town',
kind: 'consolidate',
tentative: true
});
expect(result.reason).toContain('preserve access');
expect(metricRecommendations([])).toEqual([]);
});
it('distinguishes a zero-duration sample from failed occupancy reporting', () => {
const [result] = metricRecommendations([
map({ observed: 0, active: 0, idle: 0, playerHours: 0, capacityObserved: 0 })
]);
expect(result.title).toBe('Let observations accumulate');
expect(result.reason).toContain('no elapsed observations');
});
it('leaves the lineup alone when measured evidence does not trigger a rule', () => {
expect(metricRecommendations([map({ active: 9, idle: 1, full: 0 })])[0].kind).toBe('watch');
});
});