Add Prettier and ESLint tooling (Refs #77)

This commit is contained in:
2026-10-09 15:56:13 -04:00
parent 8ed059b8d3
commit 16469e2d43
711 changed files with 99737 additions and 28286 deletions
+99 -36
View File
@@ -9,26 +9,61 @@ let fixture: Fixture;
beforeEach(async () => {
vi.resetModules();
vi.useFakeTimers({ toFake: ['Date'] }); vi.setSystemTime(now);
vi.useFakeTimers({ toFake: ['Date'] });
vi.setSystemTime(now);
fixture = await newFixture([]);
});
afterEach(async () => { await fixture.cleanup(); vi.useRealTimers(); vi.restoreAllMocks(); });
afterEach(async () => {
await fixture.cleanup();
vi.useRealTimers();
vi.restoreAllMocks();
});
async function setup(count = 1) {
const { db } = await import('../../src/lib/server/db/index.js');
const database = db();
const names = Array.from({ length: count }, (_, i) => `server-${i}`);
for (const name of names) database.prepare(`INSERT INTO servers(name,created_at,game_port,container_state,
container_checked_at,last_checked_at,last_seen_at,last_players) VALUES(?, ?, 28960, 'running', ?, ?, ?, 3)`)
.run(name, iso(-60_000), iso(), iso(), iso());
const { monitoringStatusWriter } = await import('../../src/lib/server/fleet/health-observations.js');
function publish(name: string, capacity: number | null | undefined = 4, observedAt = iso(), ok = true) {
monitoringStatusWriter(name)({ observedAt: new Date().toISOString(), result: { ok: true, state: 'running' } },
{ observedAt, result: ok ? { ok: true, endpoint: { host: 'localhost', port: 28960 },
status: { players: 3, capacity, map: 'zombie_theater', gametype: 'zom', roster: [] } }
: { ok: false, endpoint: null, reason: 'timeout', detail: 'No reply' } });
for (const name of names)
database
.prepare(
`INSERT INTO servers(name,created_at,game_port,container_state,
container_checked_at,last_checked_at,last_seen_at,last_players) VALUES(?, ?, 28960, 'running', ?, ?, ?, 3)`
)
.run(name, iso(-60_000), iso(), iso(), iso());
const { monitoringStatusWriter } =
await import('../../src/lib/server/fleet/health-observations.js');
function publish(
name: string,
capacity: number | null | undefined = 4,
observedAt = iso(),
ok = true
) {
monitoringStatusWriter(name)(
{ observedAt: new Date().toISOString(), result: { ok: true, state: 'running' } },
{
observedAt,
result: ok
? {
ok: true,
endpoint: { host: 'localhost', port: 28960 },
status: {
players: 3,
capacity,
map: 'zombie_theater',
gametype: 'zom',
roster: []
}
}
: { ok: false, endpoint: null, reason: 'timeout', detail: 'No reply' }
}
);
}
return { database, names, publish, ...await import('../../src/lib/server/fleet/player-capacity.js') };
return {
database,
names,
publish,
...(await import('../../src/lib/server/fleet/player-capacity.js'))
};
}
describe('current player capacity', () => {
@@ -39,17 +74,26 @@ describe('current player capacity', () => {
expect(currentCapacity(known, now + 90_001)).toBeNull();
expect(currentCapacity(known, now - 2000)).toBeNull();
expect(currentCapacity({ ...known, telemetry_after: iso(-1) }, now)).toBe(4);
for (const telemetry_after of [iso(), iso(1), 'invalid']) expect(currentCapacity({ ...known, telemetry_after }, now)).toBeNull();
for (const capacity of [null, undefined, 0, -1, 4.5, NaN, Infinity]) expect(currentCapacity({ ...known, capacity }, now)).toBeNull();
for (const capacity_observed_at of [null, undefined, 'invalid']) expect(currentCapacity({ ...known, capacity_observed_at }, now)).toBeNull();
for (const telemetry_after of [iso(), iso(1), 'invalid'])
expect(currentCapacity({ ...known, telemetry_after }, now)).toBeNull();
for (const capacity of [null, undefined, 0, -1, 4.5, NaN, Infinity])
expect(currentCapacity({ ...known, capacity }, now)).toBeNull();
for (const capacity_observed_at of [null, undefined, 'invalid'])
expect(currentCapacity({ ...known, capacity_observed_at }, now)).toBeNull();
});
it('projects the accepted structured sample into REST and initial SSE without probing', async () => {
const api = await setup();
api.publish('server-0');
const rcon = vi.spyOn(await import('../../src/lib/server/integrations/rcon.js'), 'rconStatusResult');
const rcon = vi.spyOn(
await import('../../src/lib/server/integrations/rcon.js'),
'rconStatusResult'
);
const { fleetSnapshot } = await import('../../src/lib/server/fleet/snapshot.js');
expect(fleetSnapshot().servers[0]).toMatchObject({ capacity: 4, capacity_observed_at: iso() });
expect(fleetSnapshot().servers[0]).toMatchObject({
capacity: 4,
capacity_observed_at: iso()
});
const { GET } = await import('../../src/routes/api/events/servers/+server.js');
const reader = (await GET()).body!.getReader();
try {
@@ -57,7 +101,9 @@ describe('current player capacity', () => {
const frame = new TextDecoder().decode((await reader.read()).value);
const body = JSON.parse(frame.split('data: ')[1]);
expect(body.entries[0]).toMatchObject({ capacity: 4, capacityObservedAt: iso() });
} finally { await reader.cancel(); }
} finally {
await reader.cancel();
}
expect(rcon).not.toHaveBeenCalled();
});
@@ -74,7 +120,9 @@ describe('current player capacity', () => {
api.publish('server-0', 4, iso(), false);
expect(read()).toEqual(unavailable);
api.publish('server-0');
api.database.prepare("UPDATE servers SET last_checked_at=?,last_error='timeout:newer failure'").run(iso(1));
api.database
.prepare("UPDATE servers SET last_checked_at=?,last_error='timeout:newer failure'")
.run(iso(1));
expect(read()).toEqual(unavailable);
});
@@ -86,30 +134,45 @@ describe('current player capacity', () => {
expect(api.playerCapacityReader()('server-0')).toEqual(unavailable);
});
it.each(['generation', 'lifecycle', 'registration', 'offline'] as const)('rejects capacity after %s changes', async change => {
const api = await setup();
const hosts = await import('../../src/lib/server/hosts/index.js');
const host = hosts.createHost({ name: 'Capacity host' });
hosts.enrollHost(hosts.createEnrollment(host.id).token, { protocolVersion: 1 });
api.database.prepare(`INSERT INTO native_instances(id,server,host_id,library_id,image,port,created_at)
VALUES('instance','server-0',?,'library','image',28960,?)`).run(host.id, iso());
api.publish('server-0');
expect(api.playerCapacityReader()('server-0').capacity).toBe(4);
if (change === 'generation') api.database.prepare('UPDATE native_instances SET generation=2').run();
if (change === 'lifecycle') api.database.prepare("INSERT INTO restart_rollout(server,requested_at) VALUES('server-0',?)").run(iso(1));
if (change === 'registration') api.database.prepare('UPDATE servers SET created_at=?').run(iso(1));
if (change === 'offline') api.database.prepare('UPDATE ec_hosts SET last_heartbeat=?').run(iso(-91_000));
expect(api.playerCapacityReader()('server-0')).toEqual(unavailable);
});
it.each(['generation', 'lifecycle', 'registration', 'offline'] as const)(
'rejects capacity after %s changes',
async (change) => {
const api = await setup();
const hosts = await import('../../src/lib/server/hosts/index.js');
const host = hosts.createHost({ name: 'Capacity host' });
hosts.enrollHost(hosts.createEnrollment(host.id).token, { protocolVersion: 1 });
api.database
.prepare(
`INSERT INTO native_instances(id,server,host_id,library_id,image,port,created_at)
VALUES('instance','server-0',?,'library','image',28960,?)`
)
.run(host.id, iso());
api.publish('server-0');
expect(api.playerCapacityReader()('server-0').capacity).toBe(4);
if (change === 'generation')
api.database.prepare('UPDATE native_instances SET generation=2').run();
if (change === 'lifecycle')
api.database
.prepare(
"INSERT INTO restart_rollout(server,requested_at) VALUES('server-0',?)"
)
.run(iso(1));
if (change === 'registration')
api.database.prepare('UPDATE servers SET created_at=?').run(iso(1));
if (change === 'offline')
api.database.prepare('UPDATE ec_hosts SET last_heartbeat=?').run(iso(-91_000));
expect(api.playerCapacityReader()('server-0')).toEqual(unavailable);
}
);
it('reads a fleet in one joined query and keeps server-detail reads scoped', async () => {
const api = await setup(20);
api.names.forEach(name => api.publish(name));
api.names.forEach((name) => api.publish(name));
// Initialize schema before measuring the snapshot's actual reads.
api.playerCapacityReader();
const prepare = vi.spyOn(api.database, 'prepare');
const fleet = api.playerCapacityReader();
expect(api.names.map(name => fleet(name).capacity)).toEqual(Array(20).fill(4));
expect(api.names.map((name) => fleet(name).capacity)).toEqual(Array(20).fill(4));
expect(prepare).toHaveBeenCalledTimes(1);
expect(prepare.mock.calls[0][0]).toContain('WHERE s.destroyed_at IS NULL ORDER BY s.name');
prepare.mockClear();