deadhead-space-freight-tycoon/packages/sim/test/goals.test.ts

67 lines
2.6 KiB
TypeScript

import { content } from "@deadhead/content";
import { describe, expect, it } from "vitest";
import { completedGoals, type GoalProgress } from "../src/index";
const goals = content.onboardingGoals;
/** Just after the deal: a ship, an Earth bay and the full loan. */
const fresh: GoalProgress = {
ownShipDeliveries: 0,
skillPointsSpent: 0,
shipsOwned: 1,
pilotsHired: 0,
veteranContracts: 0,
locationsDiscovered: 0,
dealAccepted: true,
loanBalance: content.dealLoanAmount,
};
const isComplete = (id: string, progress: GoalProgress) =>
completedGoals(goals, progress).includes(id);
/** For each goal: a summary just short of its condition, and one that meets it. */
const cases: [string, Partial<GoalProgress>, Partial<GoalProgress>][] = [
["first-own-delivery", { ownShipDeliveries: 0 }, { ownShipDeliveries: 1 }],
["first-skill-point", { skillPointsSpent: 0 }, { skillPointsSpent: 1 }],
["second-ship", { shipsOwned: 1 }, { shipsOwned: 2 }],
["veteran-contract", { veteranContracts: 0 }, { veteranContracts: 1 }],
["first-discovery", { locationsDiscovered: 0 }, { locationsDiscovered: 1 }],
["loan-paid-off", { loanBalance: 1 }, { loanBalance: 0 }],
];
describe("onboarding goal evaluation", () => {
it("covers every goal in content, in order", () => {
expect(cases.map(([id]) => id)).toEqual(goals.map((g) => g.id));
});
it.each(cases)(
"%s: incomplete just short of the condition, complete once met",
(id, short, met) => {
expect(isComplete(id, { ...fresh, ...short })).toBe(false);
expect(isComplete(id, { ...fresh, ...met })).toBe(true);
},
);
it("needs a contract flown by the veteran, not just the avatar's deliveries (CR-010)", () => {
expect(
isComplete("veteran-contract", { ...fresh, ownShipDeliveries: 12, pilotsHired: 1 }),
).toBe(false);
expect(isComplete("veteran-contract", { ...fresh, veteranContracts: 1 })).toBe(true);
expect(goals.find((g) => g.id === "veteran-contract")?.title).toBe(
`Fly a contract with ${content.veteranPilot.name}`,
);
});
it("does not count a loan as paid off before the deal", () => {
expect(isComplete("loan-paid-off", { ...fresh, dealAccepted: false, loanBalance: 0 })).toBe(
false,
);
});
it("returns completed goals in content order, identically for identical inputs", () => {
const progress: GoalProgress = { ...fresh, veteranContracts: 3, ownShipDeliveries: 5 };
expect(completedGoals(goals, progress)).toEqual(["first-own-delivery", "veteran-contract"]);
expect(completedGoals(goals, progress)).toEqual(completedGoals(goals, { ...progress }));
});
});