3D / voxel unit tests

This commit is contained in:
John McCardle 2026-02-06 16:15:07 -05:00
commit 71cd2b9b41
22 changed files with 4705 additions and 0 deletions

View file

@ -0,0 +1,241 @@
#!/usr/bin/env python3
"""Unit tests for the Interactive Procedural Generation Demo System.
Tests:
- Demo creation and initialization
- Step execution (forward/backward)
- Parameter changes and regeneration
- Layer visibility toggling
- State snapshot capture/restore
"""
import sys
import os
# Add tests directory to path
tests_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
if tests_dir not in sys.path:
sys.path.insert(0, tests_dir)
import mcrfpy
from procgen_interactive.demos.cave_demo import CaveDemo
from procgen_interactive.demos.dungeon_demo import DungeonDemo
from procgen_interactive.demos.terrain_demo import TerrainDemo
from procgen_interactive.demos.town_demo import TownDemo
def test_cave_demo():
"""Test Cave demo creation and stepping."""
print("Testing CaveDemo...")
demo = CaveDemo()
demo.activate()
# Run all steps
for i in range(len(demo.steps)):
demo.advance_step()
assert demo.current_step == i + 1, f"Step count mismatch: {demo.current_step} != {i + 1}"
# Test backward navigation
demo.reverse_step()
assert demo.current_step == len(demo.steps) - 1, "Reverse step failed"
print(" CaveDemo OK")
return True
def test_dungeon_demo():
"""Test Dungeon demo creation and stepping."""
print("Testing DungeonDemo...")
demo = DungeonDemo()
demo.activate()
# Run all steps
for i in range(len(demo.steps)):
demo.advance_step()
assert demo.current_step == len(demo.steps), "Step count mismatch"
print(" DungeonDemo OK")
return True
def test_terrain_demo():
"""Test Terrain demo creation and stepping."""
print("Testing TerrainDemo...")
demo = TerrainDemo()
demo.activate()
# Run all steps
for i in range(len(demo.steps)):
demo.advance_step()
assert demo.current_step == len(demo.steps), "Step count mismatch"
print(" TerrainDemo OK")
return True
def test_town_demo():
"""Test Town demo creation and stepping."""
print("Testing TownDemo...")
demo = TownDemo()
demo.activate()
# Run all steps
for i in range(len(demo.steps)):
demo.advance_step()
assert demo.current_step == len(demo.steps), "Step count mismatch"
print(" TownDemo OK")
return True
def test_parameter_change(demo=None):
"""Test that parameter changes trigger regeneration."""
print("Testing parameter changes...")
# Reuse existing demo if provided (to avoid scene name conflict)
if demo is None:
demo = CaveDemo()
demo.activate()
# Change a parameter
seed_param = demo.parameters["seed"]
original_seed = seed_param.value
# Test parameter value change
seed_param.value = original_seed + 1
assert seed_param.value == original_seed + 1, "Parameter value not updated"
# Test parameter bounds
seed_param.value = -10 # Should clamp to min (0)
assert seed_param.value >= 0, "Parameter min bound not enforced"
# Test increment/decrement
seed_param.value = 100
old_val = seed_param.value
seed_param.increment()
assert seed_param.value > old_val, "Increment failed"
seed_param.decrement()
assert seed_param.value == old_val, "Decrement failed"
print(" Parameter changes OK")
return True
def test_layer_visibility(demo=None):
"""Test layer visibility toggling."""
print("Testing layer visibility...")
# Reuse existing demo if provided (to avoid scene name conflict)
if demo is None:
demo = CaveDemo()
demo.activate()
# Get a layer
final_layer = demo.get_layer("final")
assert final_layer is not None, "Layer not found"
# Test visibility toggle
original_visible = final_layer.visible
final_layer.visible = not original_visible
assert final_layer.visible == (not original_visible), "Visibility not toggled"
# Toggle back
final_layer.visible = original_visible
assert final_layer.visible == original_visible, "Visibility not restored"
print(" Layer visibility OK")
return True
def main():
"""Run all tests."""
print("=" * 50)
print("Interactive Procgen Demo System Tests")
print("=" * 50)
print()
passed = 0
failed = 0
# Demo creation tests
demo_tests = [
("test_cave_demo", test_cave_demo),
("test_dungeon_demo", test_dungeon_demo),
("test_terrain_demo", test_terrain_demo),
("test_town_demo", test_town_demo),
]
# Create a fresh cave demo for parameter/layer tests
cave_demo = None
for name, test in demo_tests:
try:
if test():
passed += 1
# Save cave demo for later tests
if name == "test_cave_demo":
cave_demo = CaveDemo.__last_instance__ if hasattr(CaveDemo, '__last_instance__') else None
else:
failed += 1
print(f" FAILED: {name}")
except Exception as e:
failed += 1
print(f" ERROR in {name}: {e}")
import traceback
traceback.print_exc()
# Parameter and layer tests use the last cave demo created
# (or create a new one if cave test didn't run)
try:
# These tests are about the parameter/layer system, not demo creation
# We test with the first cave demo's parameters and layers
from procgen_interactive.core.parameter import Parameter
print("Testing parameter system...")
p = Parameter(name="test", display="Test", type="int", default=50, min_val=0, max_val=100)
p.value = 75
assert p.value == 75, "Parameter set failed"
p.increment()
assert p.value == 76, "Increment failed"
p.value = -10
assert p.value == 0, "Min bound not enforced"
p.value = 200
assert p.value == 100, "Max bound not enforced"
print(" Parameter system OK")
passed += 1
print("Testing float parameter...")
p = Parameter(name="test", display="Test", type="float", default=0.5, min_val=0.0, max_val=1.0, step=0.1)
p.value = 0.7
assert abs(p.value - 0.7) < 0.001, "Float parameter set failed"
p.increment()
assert abs(p.value - 0.8) < 0.001, "Float increment failed"
print(" Float parameter OK")
passed += 1
except Exception as e:
failed += 1
print(f" ERROR in parameter tests: {e}")
import traceback
traceback.print_exc()
print()
print("=" * 50)
print(f"Results: {passed} passed, {failed} failed")
print("=" * 50)
if failed == 0:
print("PASS")
sys.exit(0)
else:
print("FAIL")
sys.exit(1)
if __name__ == "__main__":
main()