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

80 lines
3.0 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 { describe, expect, it } from "vitest";
import {
cargoTypes,
goods,
goodSchema,
goodsDemandedAt,
goodsProducedAt,
locations,
shipModels,
} from "../src/index";
import { gameConfig } from "../src/data/config";
const classIds = cargoTypes.map((c) => c.id);
const locationIds = locations.map((l) => l.id);
const standardOn = (from: string, to: string) =>
goods.filter(
(g) =>
g.cargoClassId === "standard" && g.producedAt.includes(from) && g.demandedAt.includes(to),
);
describe("goods catalog (CR-007)", () => {
it("has unique ids and every good passes the schema", () => {
expect(new Set(goods.map((g) => g.id)).size).toBe(goods.length);
for (const good of goods) expect(() => goodSchema.parse(good)).not.toThrow();
});
it("references existing classes and locations, with min ≤ max", () => {
for (const good of goods) {
expect(classIds).toContain(good.cargoClassId);
for (const id of [...good.producedAt, ...good.demandedAt]) expect(locationIds).toContain(id);
expect(good.massTonnes.min).toBeLessThanOrEqual(good.massTonnes.max);
}
});
it("gives High-Value and Dangerous goods a tier 1–5, and Standard and Heavy goods none", () => {
for (const good of goods) {
if (good.cargoClassId === "high-value" || good.cargoClassId === "dangerous") {
expect(good.tier).toBeGreaterThanOrEqual(1);
expect(good.tier).toBeLessThanOrEqual(5);
} else {
expect(good.tier).toBeUndefined();
}
}
});
it("has every location produce at least one Standard good", () => {
for (const id of locationIds) {
expect(goods.some((g) => g.cargoClassId === "standard" && g.producedAt.includes(id))).toBe(
true,
);
}
});
it("has at least two Standard goods each way between Earth and the Moon (tutorial)", () => {
expect(standardOn("earth", "moon").length).toBeGreaterThanOrEqual(2);
expect(standardOn("moon", "earth").length).toBeGreaterThanOrEqual(2);
});
it("offers variety on the early route: ≥ 5 Standard goods Earth→Moon, ≥ 4 back (CR-008)", () => {
expect(standardOn("earth", "moon").length).toBeGreaterThanOrEqual(5);
expect(standardOn("moon", "earth").length).toBeGreaterThanOrEqual(4);
expect(gameConfig.contractPayVariance).toBeGreaterThan(0);
expect(gameConfig.contractPayVariance).toBeLessThan(1);
});
it("keeps each location's produces and demands in sync with the catalog", () => {
for (const location of locations) {
expect(location.produces).toEqual(goodsProducedAt(location.id));
expect(location.demands).toEqual(goodsDemandedAt(location.id));
}
});
it("sets Priority to a real ship model and sensible numbers", () => {
expect(shipModels.map((s) => s.id)).toContain(gameConfig.priorityReferenceShipModelId);
expect(gameConfig.priorityChance).toBe(0.15);
expect(gameConfig.priorityPayoutMultiplier).toBeGreaterThan(1);
expect(goods.some((g) => g.priorityEligible)).toBe(true);
});
});