80 lines
3.0 KiB
TypeScript
80 lines
3.0 KiB
TypeScript
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);
|
||
});
|
||
});
|