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