Files
minecraft-builder-mcp/scripts/test_voxel_island.py
T

83 lines
4.1 KiB
Python

"""Offline geometry regressions; no Minecraft world, MCP server or map fixtures."""
from collections import deque
import importlib.util
import math
from pathlib import Path
import unittest
spec = importlib.util.spec_from_file_location('voxel_island', Path(__file__).with_name('voxel-island.py'))
islands = importlib.util.module_from_spec(spec)
spec.loader.exec_module(islands)
class FloatingIslandTests(unittest.TestCase):
def test_same_input_is_reproducible_and_seed_changes_geometry(self):
args = (120, -80, 18, 13, 144, 30)
first = islands.columns(*args, 27)
self.assertEqual(first, islands.columns(*args, 27))
self.assertNotEqual(first, islands.columns(*args, 28))
def test_negative_coordinate_envelope_and_inclusive_solid_columns(self):
cx, cz, rx, rz, top, depth = -71, -39, 12, 9, 140, 27
columns = islands.columns(cx, cz, rx, rz, top, depth, 11, .2)
self.assertIn((cx, cz), columns)
for (x, z), column in columns.items():
self.assertLessEqual(abs(x-cx), rx*1.3)
self.assertLessEqual(abs(z-cz), rz*1.3)
self.assertEqual(top, column['top'])
self.assertIs(type(column['bottom']), int)
thickness = column['top'] - column['bottom'] + 1
self.assertGreaterEqual(thickness, 3)
self.assertLessEqual(thickness, math.ceil(depth + 5.5))
self.assertGreaterEqual(column['radial'], 0)
self.assertLessEqual(column['radial'], 1)
# Adjacent columns all overlap at these top three levels.
self.assertTrue(all(column['bottom'] <= y <= column['top'] for y in range(top-2, top+1)))
def test_representative_lobed_ellipses_are_four_connected(self):
for rx, rz in ((1, 1), (2, 8), (8, 2), (3, 17), (17, 3), (7, 11), (24, 22)):
for contour in (0, .055, .2):
for seed in range(12):
with self.subTest(rx=rx, rz=rz, contour=contour, seed=seed):
columns = islands.columns(0, 0, rx, rz, 140, 20, seed, contour)
reached, queue = set(), deque([(0, 0)])
while queue:
point = queue.popleft()
if point in reached or point not in columns:
continue
reached.add(point)
x, z = point
queue.extend(((x-1, z), (x+1, z), (x, z-1), (x, z+1)))
self.assertEqual(set(columns), reached)
def test_translation_preserves_outline_but_not_world_anchored_underside(self):
first = islands.columns(0, 0, 12, 9, 140, 20, 19)
moved = islands.columns(43, -27, 12, 9, 140, 20, 19)
self.assertEqual({(x+43, z-27) for x, z in first}, set(moved))
self.assertTrue(any(first[x, z]['bottom'] != moved[x+43, z-27]['bottom'] for x, z in first))
def test_tiny_positive_radii_still_include_the_centre(self):
self.assertEqual({(-5, 8)}, set(islands.columns(-5, 8, .01, .01, 140, 1, 2)))
def test_value_noise_is_bounded_and_continuous_at_negative_grid_edges(self):
for seed in (0, 1, 100):
for x, z in ((-3, .2), (.5, -7), (-4, -9), (0, 0)):
value = islands.noise(x, z, seed)
self.assertGreaterEqual(value, 0)
self.assertLessEqual(value, 1)
self.assertLess(abs(islands.noise(x-1e-7, z, seed)-islands.noise(x+1e-7, z, seed)), 1e-6)
def test_invalid_geometry_is_rejected_before_sampling(self):
for rx, rz, depth, contour in ((0, 5, 10, .1), (5, -1, 10, .1), (5, 5, 0, .1),
(math.inf, 5, 10, .1), (5, math.nan, 10, .1),
(5, 5, math.inf, .1), (5, 5, 10, -.01), (5, 5, 10, .201)):
with self.subTest(rx=rx, rz=rz, depth=depth, contour=contour):
with self.assertRaises(ValueError):
islands.columns(0, 0, rx, rz, 140, depth, 1, contour)
with self.assertRaises(ValueError):
islands.columns(.5, 0, 5, 5, 140, 10, 1)
if __name__ == '__main__':
unittest.main()