deadhead-space-freight-tycoon/packages/sim/test/fuel-share.test.ts

55 lines
2.1 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { content } from "@deadhead/content";
import { beforeAll, describe, expect, it } from "vitest";
import { formatFuelShares, fuelShares, type FuelShare } from "../balance/fuel-share";
import { checkRoute, fuelPriceAt, legFuel, routeDistance } from "../src/index";
const loc = (id: string) => content.location(id)!;
let rows: FuelShare[];
beforeAll(() => {
rows = fuelShares(content);
});
describe("fuel-to-payout check (CR-018 Step 18.1, decision 0.5.110)", () => {
it("reports every purchasable ship on every route it can fly", () => {
const models = content.shipModels.filter((m) => m.purchasable);
expect(new Set(rows.map((r) => r.modelId))).toEqual(new Set(models.map((m) => m.id)));
for (const row of rows) {
const model = content.shipModel(row.modelId)!;
expect(checkRoute(model, loc(row.originId), loc(row.destinationId), content.config).ok).toBe(
true,
);
expect(row.contracts).toBeGreaterThan(0);
}
// Every Earth–Moon leg is flown by every purchasable ship, and boards always offer it.
for (const model of models) {
expect(
rows.some(
(r) => r.modelId === model.id && r.originId === "earth" && r.destinationId === "moon",
),
).toBe(true);
}
});
it("prices a leg's fuel at the origin and divides by the median fitting payout", () => {
const row = rows.find(
(r) => r.modelId === "courier" && r.originId === "earth" && r.destinationId === "moon",
)!;
const courier = content.shipModel("courier")!;
const fuel =
legFuel(courier, loc("earth"), routeDistance(loc("earth"), loc("moon")), content.config) *
fuelPriceAt(loc("earth"), content.config);
expect(row.fuelCost).toBeCloseTo(fuel, 9);
expect(row.share).toBeCloseTo(row.fuelCost / row.medianPayout, 12);
expect(row.medianPayout).toBeGreaterThan(0);
});
it("reports the share for each ship and route as a table", () => {
const table = formatFuelShares(rows).split("\n");
expect(table).toHaveLength(rows.length + 1);
expect(
table.find((line) => line.startsWith("courier") && line.includes("earth → moon")),
).toMatch(/\d+\.\d%$/);
});
});