7ade838df8
Tests · UI / test (push) Successful in 2m49s
Lifted the Phase 29 fog draw sequence out of `setVisibilityFog` into a pure `fogPaintOps` helper that returns an ordered list of fill operations (one fog rect, then one background-coloured circle per visibility entry). The renderer now dispatches each op straight onto a Pixi `Graphics`; the indirection lets the layered- overpaint contract be tested without booting Pixi. `tests/fog-paint-ops.test.ts` covers: empty input → no ops; single circle → fog rect + bg circle in that order; multiple circles → N bg circles after the fog rect; overlapping circles emitted independently (the rendering order unions them); zero / negative world dimensions → no ops. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
131 lines
3.3 KiB
TypeScript
131 lines
3.3 KiB
TypeScript
// Phase 29 unit coverage for the Phase 29 fog overlay's layered
|
|
// overpaint logic. `fogPaintOps` lives in `src/map/render.ts` next
|
|
// to its sole consumer (`RendererHandle.setVisibilityFog`) — the
|
|
// renderer dispatches each op straight onto a Pixi `Graphics`, so
|
|
// the unit test exercises the public ordering contract: a single
|
|
// fog-coloured rectangle followed by one background-coloured
|
|
// circle per visibility entry. The natural rendering order unions
|
|
// overlapping circles for free, replacing the earlier `cut()`
|
|
// implementation that produced disconnected arc segments.
|
|
|
|
import { describe, expect, test } from "vitest";
|
|
|
|
import { FOG_COLOR, fogPaintOps } from "../src/map/render";
|
|
|
|
const BG_COLOR = 0x0a0e1a;
|
|
const WORLD = { width: 1000, height: 800 };
|
|
|
|
describe("fogPaintOps", () => {
|
|
test("empty input returns no ops", () => {
|
|
expect(fogPaintOps(WORLD, [], FOG_COLOR, BG_COLOR)).toEqual([]);
|
|
});
|
|
|
|
test("single circle emits fog rect + one bg circle in that order", () => {
|
|
const ops = fogPaintOps(
|
|
WORLD,
|
|
[{ x: 100, y: 200, radius: 50 }],
|
|
FOG_COLOR,
|
|
BG_COLOR,
|
|
);
|
|
expect(ops).toEqual([
|
|
{
|
|
kind: "fillRect",
|
|
x: 0,
|
|
y: 0,
|
|
width: 1000,
|
|
height: 800,
|
|
color: FOG_COLOR,
|
|
alpha: 1,
|
|
},
|
|
{
|
|
kind: "fillCircle",
|
|
x: 100,
|
|
y: 200,
|
|
radius: 50,
|
|
color: BG_COLOR,
|
|
alpha: 1,
|
|
},
|
|
]);
|
|
});
|
|
|
|
test("multiple circles produce one fog rect followed by N bg circles", () => {
|
|
const ops = fogPaintOps(
|
|
WORLD,
|
|
[
|
|
{ x: 100, y: 100, radius: 50 },
|
|
{ x: 300, y: 200, radius: 80 },
|
|
{ x: 500, y: 600, radius: 30 },
|
|
],
|
|
FOG_COLOR,
|
|
BG_COLOR,
|
|
);
|
|
expect(ops.length).toBe(4);
|
|
expect(ops[0].kind).toBe("fillRect");
|
|
for (let i = 1; i < ops.length; i++) {
|
|
expect(ops[i].kind).toBe("fillCircle");
|
|
// Background-coloured circles paint on top of the fog rect.
|
|
const op = ops[i];
|
|
if (op.kind === "fillCircle") {
|
|
expect(op.color).toBe(BG_COLOR);
|
|
expect(op.alpha).toBe(1);
|
|
}
|
|
}
|
|
});
|
|
|
|
test("overlapping circles are emitted independently — the rendering order unions them", () => {
|
|
// Two overlapping circles around adjacent LOCAL planets — the
|
|
// op list keeps both circles. The renderer relies on the
|
|
// overpaint to merge them visually; `cut()` (the previous
|
|
// implementation) miscomputed the union.
|
|
const ops = fogPaintOps(
|
|
WORLD,
|
|
[
|
|
{ x: 200, y: 200, radius: 100 },
|
|
{ x: 250, y: 200, radius: 100 },
|
|
],
|
|
FOG_COLOR,
|
|
BG_COLOR,
|
|
);
|
|
expect(ops.length).toBe(3);
|
|
expect(ops[1]).toMatchObject({ x: 200, y: 200, radius: 100 });
|
|
expect(ops[2]).toMatchObject({ x: 250, y: 200, radius: 100 });
|
|
});
|
|
|
|
test("the fog rect always covers the full world rectangle", () => {
|
|
const ops = fogPaintOps(
|
|
{ width: 3200, height: 1600 },
|
|
[{ x: 0, y: 0, radius: 10 }],
|
|
FOG_COLOR,
|
|
BG_COLOR,
|
|
);
|
|
expect(ops[0]).toEqual({
|
|
kind: "fillRect",
|
|
x: 0,
|
|
y: 0,
|
|
width: 3200,
|
|
height: 1600,
|
|
color: FOG_COLOR,
|
|
alpha: 1,
|
|
});
|
|
});
|
|
|
|
test("zero or negative world dimensions return no ops", () => {
|
|
expect(
|
|
fogPaintOps(
|
|
{ width: 0, height: 800 },
|
|
[{ x: 0, y: 0, radius: 10 }],
|
|
FOG_COLOR,
|
|
BG_COLOR,
|
|
),
|
|
).toEqual([]);
|
|
expect(
|
|
fogPaintOps(
|
|
{ width: 1000, height: -1 },
|
|
[{ x: 0, y: 0, radius: 10 }],
|
|
FOG_COLOR,
|
|
BG_COLOR,
|
|
),
|
|
).toEqual([]);
|
|
});
|
|
});
|