import test from "node:test"; import assert from "node:assert/strict"; import { changedLightSections } from "../light-changes.js"; function field(min = [-2, -2, -2], size = [54, 36, 36]) { const count = size.reduce((product, value) => product * value, 1); return { min, size, data: new Uint8Array(count * 4), skyLevels: new Uint8Array(count).fill(15), }; } const index = (field, [x, y, z]) => x - field.min[0] + field.size[0] * (y - field.min[1] + field.size[1] * (z - field.min[2])); test("initial lighting marks current sections, while equal fields retain every mesh", () => { const sections = new Map([ ["0,0,0", { vao: "first" }], ["1,0,0", { vao: "retained" }], ]); assert.deepEqual(changedLightSections(null, field(), sections.keys()), [ ...sections.keys(), ]); const before = [...sections.values()]; assert.deepEqual(changedLightSections(field(), field(), sections.keys()), []); assert.deepEqual([...sections.values()], before); }); test("a corner light delta invalidates all eight sharing neighborhoods but no distant section", () => { const previous = field(), next = field(); next.skyLevels[index(next, [15, 15, 15])] = 14; const neighbors = []; for (let x = 0; x <= 1; x++) for (let y = 0; y <= 1; y++) for (let z = 0; z <= 1; z++) neighbors.push(`${x},${y},${z}`); assert.deepEqual( changedLightSections(previous, next, [...neighbors, "2,0,0"]), neighbors, ); }); test("a tint-only change crosses the section boundary and preserves distant retained sections", () => { const previous = field(), next = field(); next.data[index(next, [16, 4, 4]) * 4 + 2] = 180; const sections = ["0,0,0", "1,0,0", "2,0,0"]; assert.deepEqual(changedLightSections(previous, next, sections), [ "0,0,0", "1,0,0", ]); }); test("moving field bounds compares world coordinates and only invalidates lost coverage", () => { const previous = field(); const shifted = field([-1, -2, -2], [55, 36, 36]); assert.deepEqual( changedLightSections(previous, shifted, ["0,0,0", "1,0,0"]), [], ); const clipped = field([0, -2, -2], [54, 36, 36]); assert.deepEqual( changedLightSections(previous, clipped, ["0,0,0", "1,0,0"]), ["0,0,0"], ); });