Files

81 lines
4.2 KiB
TypeScript

// Shared fixture suite for the game tests (save.test.ts, the 5a route tests, and the later
// ship/research route tests): one deterministic world — seed '42', save stamped at the
// current schema version so no backfill runs — plus the crew and task-row minters the
// queueing tests use. Ids line up across worlds built in fresh files (same insert order),
// so two fixture worlds are comparable row for row.
import type { GameDb } from '@/lib/db/client'
import * as schema from '@/lib/db/schema'
import { SCHEMA_VERSION } from './save'
// Fixed so a fixture's event rows carry a stable created_at (tests never assert on it, but
// a wall-clock Date would make two fixture worlds differ byte-for-byte).
export const T0 = '2026-10-01T00:00:00.000Z'
// Origin (s0, id 1, current) — Outpost (s1, one hop: the jump target) — Farpoint (s2, two
// hops: beyond one-hop range, so the unreachable pre-check has a target to 409 on; with
// NAVIGATION AI researched it would be reachable). p0 'Alder' in s0, p1 'Basalt' in s1.
// No crew, tasks, ship, or tech rows — the caller mints exactly what a test needs.
export async function buildWorldFixture(
db: GameDb,
outpostDiscovered = false,
): Promise<{ sys1: number; p0: number; p1: number; farSystem: number }> {
const [save] = await db.db
.insert(schema.saves)
.values({ seed: '42', turn: 0, createdAt: T0, schemaVersion: SCHEMA_VERSION })
.returning()
const [s0] = await db.db
.insert(schema.solarSystems)
.values({ saveId: save.id, name: 'Origin', x: 50, y: 50, discovered: true, isCurrent: true })
.returning({ id: schema.solarSystems.id })
const [s1] = await db.db
.insert(schema.solarSystems)
.values({ saveId: save.id, name: 'Outpost', x: 55, y: 50, discovered: outpostDiscovered })
.returning({ id: schema.solarSystems.id })
const [s2] = await db.db
.insert(schema.solarSystems)
.values({ saveId: save.id, name: 'Farpoint', x: 60, y: 50, discovered: false })
.returning({ id: schema.solarSystems.id })
await db.db.insert(schema.jumpRoutes).values({ fromSystem: s0.id, toSystem: s1.id })
await db.db.insert(schema.jumpRoutes).values({ fromSystem: s1.id, toSystem: s0.id })
await db.db.insert(schema.jumpRoutes).values({ fromSystem: s1.id, toSystem: s2.id })
await db.db.insert(schema.jumpRoutes).values({ fromSystem: s2.id, toSystem: s1.id })
const [p0] = await db.db
.insert(schema.planets)
.values({ systemId: s0.id, parentId: null, name: 'Alder', type: 'ROCKY', hazard: false })
.returning({ id: schema.planets.id })
const [p1] = await db.db
.insert(schema.planets)
.values({ systemId: s1.id, parentId: null, name: 'Basalt', type: 'GAS', hazard: false })
.returning({ id: schema.planets.id })
return { sys1: s1.id, p0: p0.id, p1: p1.id, farSystem: s2.id }
}
// `count` identical crew members, in insertion order — the queueing tests need real crew
// ids to lead and help with.
export async function addCrew(db: GameDb, count: number): Promise<number[]> {
const [save] = await db.db.select().from(schema.saves).limit(1)
const ids: number[] = []
for (let i = 0; i < count; i++) {
const [row] = await db.db
.insert(schema.crew)
.values({ saveId: save.id, name: `CREW ${i + 1}`, role: 'PILOT', traitGood: 'QUICK HANDS', traitBad: 'OVERCAUTIOUS', origin: 'STARTING CREW' })
.returning({ id: schema.crew.id })
ids.push(row.id)
}
return ids
}
// Mint one tasks-table row with a chosen state — the queueing/tick tests seed the queue
// directly instead of going through the routes (which would run the same validation).
export async function insertTaskRow(
db: GameDb,
over: { type: string; payload: object; leadCrewId: number; helpers: number[]; duration: number; remaining: number; status: string; queuedAtTurn: number },
): Promise<number> {
const [save] = await db.db.select().from(schema.saves).limit(1)
const [row] = await db.db
.insert(schema.tasks)
.values({ saveId: save.id, type: over.type, payload: JSON.stringify(over.payload), leadCrewId: over.leadCrewId, helpers: JSON.stringify(over.helpers), duration: over.duration, remaining: over.remaining, status: over.status, queuedAtTurn: over.queuedAtTurn })
.returning({ id: schema.tasks.id })
return row.id
}