import test from "node:test"; import assert from "node:assert/strict"; import { readFile } from "node:fs/promises"; import { applyLightProperties, loadLightProperties } from "../light-properties.js"; const properties = JSON.parse(await readFile(new URL("../light-properties.json", import.meta.url))); const reference = JSON.parse(await readFile(new URL("./fixtures/lighting-java26.2.json", import.meta.url))); test("all original measured examples match by Minecraft ID and canonical state", () => { for (const example of reference.examples) { for (const material of [{ minecraft_id: example.minecraft_id }, { state: example.state }]) { const actual = applyLightProperties(material, properties); assert.equal(actual.light_dampening, example.dampening, example.state); assert.deepEqual(actual.light_occlusion, example.occlusion.map((box) => ({ min: box.slice(0, 3), max: box.slice(3, 6) })), example.state); assert.deepEqual(material, "state" in material ? { state: example.state } : { minecraft_id: example.minecraft_id }); } } }); test("partial state strings use default values and accept arbitrary property order", () => { const top = applyLightProperties({ state: "minecraft:oak_slab[type=top]" }, properties); assert.equal(top.light_dampening, 0); assert.deepEqual(top.light_occlusion, [{ min: [0, 0.5, 0], max: [1, 1, 1] }]); const wet = applyLightProperties({ state: "minecraft:oak_slab[waterlogged=true,type=top]" }, properties); assert.equal(wet.light_dampening, 1); assert.deepEqual(wet.light_occlusion, top.light_occlusion); const iron = applyLightProperties({ state: "minecraft:iron_trapdoor[open=false]" }, properties); assert.equal(iron.light_dampening, 0); assert.deepEqual(iron.light_occlusion, []); }); test("custom materials retain their own identity and optional light properties", () => { const custom = { id: 1, state: "shacraft:trampoline", light: 11, light_dampening: 2, light_occlusion: [] }; const actual = applyLightProperties(custom, properties); assert.notEqual(actual, custom); assert.deepEqual(actual, custom); for (const state of ["minecraft:oak_slab[type=invalid]", "minecraft:stone[missing=true]", "minecraft:oak_slab[type=top,type=bottom]"]) { assert.deepEqual(applyLightProperties({ state }, properties), { state }); } assert.deepEqual(applyLightProperties({ id: 1 }, properties), { id: 1 }); const glass = applyLightProperties({ id: 999, minecraft_id: reference.examples.find((e) => e.state === "minecraft:glass").minecraft_id, light: 4 }, properties); assert.equal(glass.id, 999); assert.equal(glass.light, 4); assert.equal(glass.light_dampening, 0); }); test("every registry state is present and every shape index is valid", () => { assert.equal(properties.codes.length, 32366); assert.equal(Object.keys(properties.blocks).length, 1196); assert.equal(properties.shapes.length, 60); for (const code of properties.codes) { assert.ok(Number.isInteger(code) && code >= 0); assert.ok(properties.shapes[Math.floor(code / 16)]); } }); test("the runtime metadata request is shared by concurrent and later callers", async () => { const originalFetch = globalThis.fetch; let calls = 0; globalThis.fetch = async (url) => { calls++; assert.equal(url.pathname.endsWith("/light-properties.json"), true); return { ok: true, json: async () => properties }; }; try { const [first, second] = await Promise.all([loadLightProperties(), loadLightProperties()]); assert.equal(first, properties); assert.equal(first, second); assert.equal(await loadLightProperties(), properties); assert.equal(calls, 1); } finally { globalThis.fetch = originalFetch; } });