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); }); });