import { describe, expect, it } from "vitest"; import { content, gameConfig, shipModels, upgradeMaxLevel, upgradePercentPerLevel, upgradeSchema, upgrades, type ShipStat, } from "../src/index"; const model = (id: string) => shipModels.find((m) => m.id === id)!; const upgradeFor = (stat: ShipStat) => upgrades.find((u) => u.stat === stat)!; /** A stat at the upgrade's max level for this model (decision 0.5.63: linear % of base). */ const maxed = (modelId: string, stat: Exclude) => { const upgrade = upgradeFor(stat); const level = upgradeMaxLevel(upgrade, modelId); return model(modelId)[stat] * (1 + (upgradePercentPerLevel(upgrade, modelId) * level) / 100); }; describe("ship upgrades content (CR-009)", () => { it("has the five upgrades, all valid, three levels each", () => { for (const upgrade of upgrades) expect(upgradeSchema.safeParse(upgrade).success).toBe(true); expect(upgrades.map((u) => u.id)).toEqual([ "engines", "cargo-bay", "fuel-tanks", "landing-thrusters", "handling-gear", ]); for (const upgrade of upgrades) expect(upgrade.maxLevel).toBe(3); expect(content.upgrade("engines")?.name).toBe("Engine Tuning"); }); it("only changes stats ships have", () => { for (const upgrade of upgrades) { if (upgrade.stat === "handlingGameHoursPerTonne") { // A game-wide base until upgraded. expect(gameConfig.handlingGameHoursPerTonne).toBeGreaterThan(0); } else { for (const m of shipModels) expect(m, `${m.id}.${upgrade.stat}`).toHaveProperty(upgrade.stat); } for (const id of Object.keys(upgrade.modelOverrides ?? {})) { expect(content.shipModel(id), id).toBeDefined(); } } }); it("prices levels at 10/20/35 % of the ship and 10/20/30 minutes in the shop", () => { expect(gameConfig.upgradeLevels).toEqual([ { costPercentOfPrice: 10, shopRealMinutes: 10 }, { costPercentOfPrice: 20, shopRealMinutes: 20 }, { costPercentOfPrice: 35, shopRealMinutes: 30 }, ]); for (const upgrade of upgrades) { for (const m of shipModels) { expect(upgradeMaxLevel(upgrade, m.id)).toBeLessThanOrEqual(gameConfig.upgradeLevels.length); } } }); it("keeps models distinct (decision 0.5.67)", () => { expect(maxed("courier", "cargoCapacityTonnes")).toBeLessThan( model("freighter").cargoCapacityTonnes, ); expect(maxed("bulk-hauler", "cruiseSpeedKmPerGameHour")).toBeLessThan( model("freighter").cruiseSpeedKmPerGameHour, ); expect(maxed("freighter", "fuelRangeMillionKm")).toBeLessThan( model("bulk-hauler").fuelRangeMillionKm, ); }); });