Files
MineGeo/tests/surface-map.test.ts

124 lines
3.8 KiB
TypeScript

import { test } from "node:test";
import assert from "node:assert/strict";
import { surfacePixels } from "../renderer/surface-map.mjs";
import type { TerrainSnapshot } from "../shared/protocol";
function pixel(map: ReturnType<typeof surfacePixels>, x: number, z: number) {
return [
...map.data.subarray((z * map.width + x) * 4, (z * map.width + x + 1) * 4),
];
}
test("surface map keeps north up, negative coordinates, rectangular bounds and uncovered parchment", () => {
const map = surfacePixels({
bounds: { minX: -2, maxX: 2, minZ: -3, maxZ: -1 },
coverage: [],
blocks: [
[-2, 64, -3, "minecraft:snow_block"],
[1, 64, -2, "minecraft:grass_block"],
[2, 90, -2, "minecraft:snow_block"], // half-open boundary
[-2, 90, -1, "minecraft:snow_block"],
],
});
assert.equal(map.width, 4);
assert.equal(map.height, 2);
assert.equal(map.columns, 2);
const north = pixel(map, 0, 0);
assert.equal(north[0], north[1]);
assert.equal(north[1], north[2]);
const south = pixel(map, 3, 1);
assert.ok(south[1] > south[0] && south[0] > south[2]);
const blank = pixel(map, 3, 0);
assert.ok(blank[0] > blank[1] && blank[1] > blank[2]);
assert.equal(blank[3], 255);
});
test("the highest mapped block wins regardless of export order and glass does not obscure terrain", () => {
const terrain: TerrainSnapshot = {
bounds: { minX: 0, maxX: 1, minZ: 0, maxZ: 1 },
coverage: [],
blocks: [
[0, 63, 0, "minecraft:dirt"],
[0, 64, 0, "minecraft:grass_block[snowy=false]"],
[0, 70, 0, "minecraft:glass"],
[0, 71, 0, "minecraft:short_grass"],
],
};
const first = surfacePixels(terrain);
const reversed = surfacePixels({
...terrain,
blocks: [...terrain.blocks].reverse(),
});
assert.deepEqual(first.data, reversed.data);
const rgb = pixel(first, 0, 0);
assert.ok(rgb[1] > rgb[0] && rgb[0] > rgb[2]);
});
test("depth shading separates shallow, deep and unknown-bed water without texture speckle", () => {
const map = surfacePixels({
bounds: { minX: 0, maxX: 3, minZ: 0, maxZ: 1 },
coverage: [],
blocks: [
[0, 64, 0, "minecraft:water[level=0]"],
[0, 63, 0, "minecraft:sand"],
[1, 64, 0, "minecraft:water[level=0]"],
[1, 52, 0, "minecraft:stone"],
[2, 64, 0, "minecraft:water[level=0]"],
],
});
const shallow = pixel(map, 0, 0),
deep = pixel(map, 1, 0);
assert.ok(shallow[2] > shallow[1] && shallow[1] > shallow[0]);
assert.ok(shallow[2] > deep[2]);
assert.deepEqual(deep, pixel(map, 2, 0));
});
test("height relief shades slopes while flat ground stays uniform", () => {
const blocks: TerrainSnapshot["blocks"] = [64, 64, 66, 64].map((y, z) => [
0,
y,
z,
"minecraft:stone",
]);
const map = surfacePixels({
bounds: { minX: 0, maxX: 1, minZ: 0, maxZ: 4 },
coverage: [],
blocks,
});
assert.deepEqual(pixel(map, 0, 0), pixel(map, 0, 1));
assert.ok(pixel(map, 0, 2)[0] > pixel(map, 0, 1)[0]);
assert.ok(pixel(map, 0, 3)[0] < pixel(map, 0, 1)[0]);
});
test("map cells use the dominant surface material instead of a textured average", () => {
const blocks: TerrainSnapshot["blocks"] = [];
for (let x = 0; x < 4; x++)
for (let z = 0; z < 4; z++)
blocks.push([
x,
64,
z,
x === 0 ? "minecraft:stone" : "minecraft:grass_block",
]);
const map = surfacePixels(
{ bounds: { minX: 0, maxX: 4, minZ: 0, maxZ: 4 }, coverage: [], blocks },
{ resolution: 1 },
);
assert.equal(map.width, 1);
assert.equal(map.height, 1);
const rgb = pixel(map, 0, 0);
assert.ok(rgb[1] > rgb[0] && rgb[0] > rgb[2]);
});
test("empty exports fail instead of producing a playable blank map", () => {
assert.throws(
() =>
surfacePixels({
bounds: { minX: 0, maxX: 16, minZ: 0, maxZ: 16 },
coverage: [],
blocks: [],
}),
/no mapped terrain/,
);
});