deadhead-space-freight-tycoon/packages/content/test/locations.test.ts

68 lines
2.6 KiB
TypeScript

import { describe, expect, it } from "vitest";
import { cargoTypes, goods, locationSchema, locations } from "../src/index";
const cargoTypeIds = cargoTypes.map((c) => c.id);
describe("locations", () => {
it("all pass the schema", () => {
for (const location of locations) {
expect(() => locationSchema.parse(location)).not.toThrow();
}
});
it("has exactly five locations with unique ids", () => {
expect(locations).toHaveLength(5);
expect(new Set(locations.map((l) => l.id)).size).toBe(5);
});
it("starts with exactly Earth and Moon discovered", () => {
const discovered = locations.filter((l) => l.startsDiscovered).map((l) => l.id);
expect(discovered.sort()).toEqual(["earth", "moon"]);
});
it("references only existing goods, and cargo classes in its class mix", () => {
const goodIds = goods.map((g) => g.id);
for (const location of locations) {
for (const goodId of [...location.produces, ...location.demands]) {
expect(goodIds).toContain(goodId);
}
const { produces, demands } = location.cargoClassMix;
for (const cargoId of [...produces, ...demands]) expect(cargoTypeIds).toContain(cargoId);
}
});
it("has at least one shipper per location (CR-007)", () => {
for (const location of locations) expect(location.shippers.length).toBeGreaterThan(0);
});
it("orders fuel prices Jupiter < Ceres < Moon < Mars < Earth (decision 0.5.96)", () => {
const price = (id: string) => locations.find((l) => l.id === id)!.fuelPrice;
const order = ["jupiter-cloud-platform", "ceres-station", "moon", "mars", "earth"];
for (let i = 1; i < order.length; i++) {
expect(price(order[i - 1]!), order[i]).toBeLessThan(price(order[i]!));
}
});
it("sells fuel at every base location (CR-015 §3)", () => {
for (const location of locations) expect(location.sellsFuel, location.id).toBe(true);
});
it("gives every location its own map sprite key (CR-003)", () => {
const sprites = locations.map((x) => x.sprite);
for (const sprite of sprites) expect(sprite).toMatch(/^[a-z][a-z-]*$/);
expect(new Set(sprites).size).toBe(sprites.length);
});
it("gives every location a positive launch range factor (CR-012)", () => {
for (const l of locations) expect(l.launchRangeFactor, l.id).toBeGreaterThan(0);
const factor = (id: string) => locations.find((l) => l.id === id)!.launchRangeFactor;
expect([
factor("earth"),
factor("moon"),
factor("mars"),
factor("ceres-station"),
factor("jupiter-cloud-platform"),
]).toEqual([1, 1.3, 1.15, 1.3, 1]);
});
});