deadhead-space-freight-tycoon/packages/content/test/fixed-map.test.ts

102 lines
4.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 { content, type FixedPosition } from "../src/index";
import { offsetPosition } from "../src/data/locations";
// Vite reads the lockfile as text at test time.
import lockfile from "../../../pnpm-lock.yaml?raw";
function point(p: FixedPosition) {
const a = (p.angleDegrees * Math.PI) / 180;
return { x: p.radiusMillionKm * Math.cos(a), y: p.radiusMillionKm * Math.sin(a) };
}
function distance(fromId: string, toId: string): number {
const a = point(content.location(fromId)!.position);
const b = point(content.location(toId)!.position);
return Math.hypot(b.x - a.x, b.y - a.y);
}
describe("fixed map (Step 15.1, decision 0.5.93)", () => {
it("gives every location a fixed position", () => {
for (const location of content.locations) {
expect(location.position.radiusMillionKm, location.id).toBeGreaterThan(0);
expect(Number.isFinite(location.position.angleDegrees), location.id).toBe(true);
}
});
it("defines the Moon as an offset from Earth", () => {
const moon = content.location("moon")!;
expect(moon.orbitParent).toEqual({ locationId: "earth", offsetMillionKm: 0.384 });
expect(moon.position).toEqual(offsetPosition(content.location("earth")!.position, 0.384));
expect(distance("earth", "moon")).toBeCloseTo(0.384, 6);
});
it("puts every child body at its parent plus its offset", () => {
for (const location of content.locations.filter((l) => l.orbitParent)) {
const { locationId, offsetMillionKm } = location.orbitParent!;
const parent = content.location(locationId)!;
expect(location.position, location.id).toEqual(
offsetPosition(parent.position, offsetMillionKm),
);
}
});
it.each([
["earth", "mars", 201],
["mars", "ceres-station", 202],
["earth", "ceres-station", 402],
["ceres-station", "jupiter-cloud-platform", 393],
["mars", "jupiter-cloud-platform", 592],
["earth", "jupiter-cloud-platform", 792],
])("puts %s–%s at about %i M km (CR-015 §2, within 2 %)", (from, to, expected) => {
const d = distance(from, to);
expect(Math.abs(d - expected) / expected).toBeLessThan(0.02);
expect(distance(to, from)).toBeCloseTo(d, 9);
});
it("no longer depends on astronomy-engine", () => {
expect(lockfile).not.toContain("astronomy-engine");
});
});
describe("new locations (Step 16.1, decision 0.5.100)", () => {
it.each([
["earth", "venus-cloud-city", 200],
["moon", "venus-cloud-city", 200],
["venus-cloud-city", "mars", 332],
["venus-cloud-city", "ceres-station", 520],
["venus-cloud-city", "jupiter-cloud-platform", 885],
["ceres-station", "io-sulfur-works", 393],
["ceres-station", "europa-ice-station", 393],
])("puts %s–%s at about %i M km (CR-016 §2, within 2 %)", (from, to, expected) => {
expect(Math.abs(distance(from, to) - expected) / expected).toBeLessThan(0.02);
});
it("keeps the Jupiter system within 1.1M km of the platform", () => {
const system = ["jupiter-cloud-platform", "io-sulfur-works", "europa-ice-station"];
for (const a of system) for (const b of system) expect(distance(a, b)).toBeLessThan(1.1);
});
it("rides Io and Europa with Jupiter, at their offsets", () => {
expect(content.location("io-sulfur-works")!.orbitParent).toEqual({
locationId: "jupiter-cloud-platform",
offsetMillionKm: 0.42,
});
expect(content.location("europa-ice-station")!.orbitParent).toEqual({
locationId: "jupiter-cloud-platform",
offsetMillionKm: 0.67,
});
});
it("starts all three undiscovered, selling fuel, landable without Hardened ships", () => {
for (const id of ["venus-cloud-city", "io-sulfur-works", "europa-ice-station"]) {
const location = content.location(id)!;
expect(location.startsDiscovered, id).toBe(false);
expect(location.sellsFuel, id).toBe(true);
expect(location.landingRequirement, id).not.toBe("hardened");
}
expect(content.locations.filter((l) => l.startsDiscovered).map((l) => l.id)).toEqual([
"earth",
"moon",
]);
});
});