deadhead-space-freight-tycoon/packages/sim/test/reposition.test.ts

71 lines
2.4 KiB
TypeScript

import { content } from "@deadhead/content";
import { describe, expect, it } from "vitest";
import {
createRepositionRecord,
validateReposition,
type PilotState,
type RepositionProposal,
type ShipState,
} from "../src/index";
const now = Date.parse("2100-01-01T00:30:00Z");
const ship: ShipState = { id: "s1", modelId: "courier", locationId: "earth", inFlight: false };
const pilot: PilotState = {
id: "p1",
isAvatar: false,
assignedShipId: "s1",
inFlight: false,
skills: {},
};
const valid: RepositionProposal = {
ship,
pilot,
destinationId: "moon",
bayLocationIds: new Set(["earth", "moon"]),
credits: 10_000,
now,
};
const reason = (proposal: RepositionProposal) => {
const result = validateReposition(proposal, content);
return result.ok ? "valid" : result.reason;
};
describe("reposition", () => {
it("accepts an empty flight to a bay in range, with no skills needed", () => {
expect(reason(valid)).toBe("valid");
});
it("fails validation when the destination has no player bay", () => {
expect(reason({ ...valid, bayLocationIds: new Set(["earth"]) })).toBe("no-bay-at-destination");
});
it("still applies range and fuel checks", () => {
expect(
reason({ ...valid, destinationId: "mars", bayLocationIds: new Set(["earth", "mars"]) }),
).toBe("out-of-range");
expect(reason({ ...valid, credits: 0 })).toBe("insufficient-credits");
});
it("rejects flying to where the ship already is, or with a busy or unassigned crew", () => {
expect(reason({ ...valid, destinationId: "earth" })).toBe("already-there");
expect(reason({ ...valid, ship: { ...ship, inFlight: true } })).toBe("ship-not-idle");
expect(reason({ ...valid, pilot: { ...pilot, inFlight: true } })).toBe("pilot-not-idle");
expect(reason({ ...valid, pilot: { ...pilot, assignedShipId: null } })).toBe(
"pilot-not-assigned",
);
});
it("creates a record with no contract, zero payout and a fuel charge", () => {
const record = createRepositionRecord(
{ id: "r1", ship, pilot, destinationId: "moon", now, worldSeed: 7 },
content,
);
expect(record.contract).toBeNull();
expect(record.expectedPayout).toBe(0);
expect(record.fuelCost).toBeGreaterThan(0);
expect([record.originId, record.destinationId]).toEqual(["earth", "moon"]);
expect(record.arrivalAt).toBeGreaterThan(record.departureAt);
});
});