Test suite modernization
This commit is contained in:
parent
0969f7c2f6
commit
52fdfd0347
141 changed files with 9947 additions and 4665 deletions
286
tests/integration/3d_full_test.py
Normal file
286
tests/integration/3d_full_test.py
Normal file
|
|
@ -0,0 +1,286 @@
|
|||
# 3d_full_test.py - Integration tests for complete 3D system
|
||||
# Tests all 3D features working together
|
||||
|
||||
import mcrfpy
|
||||
import sys
|
||||
|
||||
def test_viewport_creation():
|
||||
"""Test Viewport3D creation and basic properties"""
|
||||
viewport = mcrfpy.Viewport3D(
|
||||
pos=(0, 0),
|
||||
size=(800, 600),
|
||||
render_resolution=(320, 240),
|
||||
fov=60.0,
|
||||
camera_pos=(10.0, 10.0, 10.0),
|
||||
camera_target=(0.0, 0.0, 0.0)
|
||||
)
|
||||
|
||||
assert viewport.w == 800, f"Width mismatch: {viewport.w}"
|
||||
assert viewport.h == 600, f"Height mismatch: {viewport.h}"
|
||||
assert viewport.fov == 60.0, f"FOV mismatch: {viewport.fov}"
|
||||
|
||||
print("[PASS] test_viewport_creation")
|
||||
return viewport
|
||||
|
||||
def test_navigation_grid(viewport):
|
||||
"""Test navigation grid setup"""
|
||||
viewport.set_grid_size(16, 16)
|
||||
|
||||
assert viewport.grid_size == (16, 16), f"Grid size mismatch: {viewport.grid_size}"
|
||||
|
||||
# Test cell access
|
||||
cell = viewport.at(5, 5)
|
||||
assert cell is not None, "Cell access failed"
|
||||
assert cell.walkable == True, "Default cell should be walkable"
|
||||
|
||||
# Test setting cell properties
|
||||
cell.walkable = False
|
||||
cell2 = viewport.at(5, 5)
|
||||
assert cell2.walkable == False, "Cell walkable not persisted"
|
||||
cell.walkable = True # Reset
|
||||
|
||||
print("[PASS] test_navigation_grid")
|
||||
|
||||
def test_heightmap_and_terrain(viewport):
|
||||
"""Test heightmap and terrain generation"""
|
||||
hm = mcrfpy.HeightMap((16, 16))
|
||||
hm.mid_point_displacement(roughness=0.4)
|
||||
hm.normalize(0.0, 1.0)
|
||||
|
||||
# Check heightmap values are in range
|
||||
for x in range(16):
|
||||
for z in range(16):
|
||||
h = hm[x, z]
|
||||
assert 0.0 <= h <= 1.0, f"Height out of range at ({x},{z}): {h}"
|
||||
|
||||
# Build terrain
|
||||
vertex_count = viewport.build_terrain(
|
||||
layer_name="terrain",
|
||||
heightmap=hm,
|
||||
y_scale=2.0,
|
||||
cell_size=1.0
|
||||
)
|
||||
|
||||
assert vertex_count > 0, "No vertices generated"
|
||||
|
||||
# Apply heightmap to navigation
|
||||
viewport.apply_heightmap(hm, 2.0)
|
||||
|
||||
print("[PASS] test_heightmap_and_terrain")
|
||||
|
||||
def test_terrain_colors(viewport):
|
||||
"""Test terrain color application"""
|
||||
r_map = mcrfpy.HeightMap((16, 16))
|
||||
g_map = mcrfpy.HeightMap((16, 16))
|
||||
b_map = mcrfpy.HeightMap((16, 16))
|
||||
|
||||
# Set all green
|
||||
for x in range(16):
|
||||
for z in range(16):
|
||||
r_map[x, z] = 0.2
|
||||
g_map[x, z] = 0.5
|
||||
b_map[x, z] = 0.2
|
||||
|
||||
viewport.apply_terrain_colors("terrain", r_map, g_map, b_map)
|
||||
|
||||
print("[PASS] test_terrain_colors")
|
||||
|
||||
def test_entity_creation(viewport):
|
||||
"""Test Entity3D creation and properties"""
|
||||
entity = mcrfpy.Entity3D(pos=(8, 8), scale=1.0, color=mcrfpy.Color(255, 100, 50))
|
||||
viewport.entities.append(entity)
|
||||
|
||||
assert entity.pos == (8, 8), f"Position mismatch: {entity.pos}"
|
||||
assert entity.scale == 1.0, f"Scale mismatch: {entity.scale}"
|
||||
assert entity.is_moving == False, "New entity should not be moving"
|
||||
|
||||
print("[PASS] test_entity_creation")
|
||||
return entity
|
||||
|
||||
def test_pathfinding(viewport, entity):
|
||||
"""Test A* pathfinding"""
|
||||
# Find path to another location
|
||||
path = entity.path_to(12, 12)
|
||||
|
||||
assert isinstance(path, list), "path_to should return list"
|
||||
|
||||
# Path may be empty if blocked, but should not error
|
||||
if path:
|
||||
assert len(path) > 0, "Path should have steps"
|
||||
# First step should be adjacent to start or the start itself
|
||||
|
||||
# Test find_path on viewport
|
||||
vp_path = viewport.find_path((8, 8), (12, 12))
|
||||
assert isinstance(vp_path, list), "viewport.find_path should return list"
|
||||
|
||||
print("[PASS] test_pathfinding")
|
||||
return path
|
||||
|
||||
def test_entity_movement(entity, path):
|
||||
"""Test Entity3D movement via follow_path"""
|
||||
if not path:
|
||||
print("[SKIP] test_entity_movement - no path available")
|
||||
return
|
||||
|
||||
# Test follow_path
|
||||
entity.follow_path(path[:3]) # Just first 3 steps
|
||||
|
||||
# After queueing moves, entity should be moving
|
||||
assert entity.is_moving == True, "Entity should be moving after follow_path"
|
||||
|
||||
# Test clear_path
|
||||
entity.clear_path()
|
||||
|
||||
print("[PASS] test_entity_movement")
|
||||
|
||||
def test_fov_computation(viewport):
|
||||
"""Test field of view computation"""
|
||||
visible = viewport.compute_fov((8, 8), radius=5)
|
||||
|
||||
assert isinstance(visible, list), "compute_fov should return list"
|
||||
assert len(visible) > 0, "FOV should see some cells"
|
||||
|
||||
# Origin should be visible
|
||||
origin_visible = (8, 8) in [(c[0], c[1]) for c in visible]
|
||||
assert origin_visible, "Origin should be in FOV"
|
||||
|
||||
# Test is_in_fov
|
||||
assert viewport.is_in_fov(8, 8) == True, "Origin should be in FOV"
|
||||
|
||||
print("[PASS] test_fov_computation")
|
||||
|
||||
def test_screen_to_world(viewport):
|
||||
"""Test screen-to-world ray casting"""
|
||||
# Test center of viewport
|
||||
result = viewport.screen_to_world(160, 120) # Half of 320x240 render resolution
|
||||
|
||||
# May return None if ray misses ground
|
||||
if result is not None:
|
||||
assert len(result) == 3, "Should return (x, y, z)"
|
||||
assert result[1] == 0.0, "Y should be 0 (ground plane)"
|
||||
|
||||
print("[PASS] test_screen_to_world")
|
||||
|
||||
def test_camera_follow(viewport, entity):
|
||||
"""Test camera follow method"""
|
||||
original_pos = viewport.camera_pos
|
||||
|
||||
viewport.follow(entity, distance=10.0, height=5.0)
|
||||
|
||||
new_pos = viewport.camera_pos
|
||||
# Camera should have moved
|
||||
# (Position may or may not change significantly depending on entity location)
|
||||
|
||||
print("[PASS] test_camera_follow")
|
||||
|
||||
def test_layer_management(viewport):
|
||||
"""Test mesh layer management"""
|
||||
# Add layer
|
||||
layer = viewport.add_layer("test_layer", z_index=5)
|
||||
assert layer is not None, "add_layer should return layer dict"
|
||||
|
||||
# Get layer
|
||||
layer2 = viewport.get_layer("test_layer")
|
||||
assert layer2 is not None, "get_layer should find layer"
|
||||
|
||||
# Layer count
|
||||
count = viewport.layer_count()
|
||||
assert count >= 1, "Should have at least 1 layer"
|
||||
|
||||
# Remove layer
|
||||
removed = viewport.remove_layer("test_layer")
|
||||
assert removed == True, "remove_layer should return True"
|
||||
|
||||
# Verify removed
|
||||
layer3 = viewport.get_layer("test_layer")
|
||||
assert layer3 is None, "Layer should be removed"
|
||||
|
||||
print("[PASS] test_layer_management")
|
||||
|
||||
def test_threshold_and_slope(viewport):
|
||||
"""Test walkability threshold and slope cost"""
|
||||
hm = mcrfpy.HeightMap((16, 16))
|
||||
hm.normalize(0.0, 1.0)
|
||||
|
||||
# Apply threshold - mark low areas unwalkable
|
||||
viewport.apply_threshold(hm, 0.0, 0.2, False)
|
||||
|
||||
# Set slope cost
|
||||
viewport.set_slope_cost(0.5, 2.0)
|
||||
|
||||
print("[PASS] test_threshold_and_slope")
|
||||
|
||||
def test_place_blocking(viewport):
|
||||
"""Test place_blocking for marking cells"""
|
||||
# Mark a 2x2 area as blocking
|
||||
viewport.place_blocking((10, 10), (2, 2), walkable=False, transparent=False)
|
||||
|
||||
# Verify cells are blocked
|
||||
cell = viewport.at(10, 10)
|
||||
assert cell.walkable == False, "Cell should be unwalkable after place_blocking"
|
||||
|
||||
print("[PASS] test_place_blocking")
|
||||
|
||||
def run_all_tests():
|
||||
"""Run all integration tests"""
|
||||
print("=" * 60)
|
||||
print("3D Full Integration Test Suite")
|
||||
print("=" * 60)
|
||||
|
||||
passed = 0
|
||||
failed = 0
|
||||
|
||||
try:
|
||||
viewport = test_viewport_creation()
|
||||
passed += 1
|
||||
except Exception as e:
|
||||
print(f"[FAIL] test_viewport_creation: {e}")
|
||||
failed += 1
|
||||
return
|
||||
|
||||
tests = [
|
||||
lambda: test_navigation_grid(viewport),
|
||||
lambda: test_heightmap_and_terrain(viewport),
|
||||
lambda: test_terrain_colors(viewport),
|
||||
lambda: test_layer_management(viewport),
|
||||
lambda: test_threshold_and_slope(viewport),
|
||||
lambda: test_place_blocking(viewport),
|
||||
lambda: test_fov_computation(viewport),
|
||||
lambda: test_screen_to_world(viewport),
|
||||
]
|
||||
|
||||
for test in tests:
|
||||
try:
|
||||
test()
|
||||
passed += 1
|
||||
except Exception as e:
|
||||
print(f"[FAIL] {test.__name__ if hasattr(test, '__name__') else 'test'}: {e}")
|
||||
failed += 1
|
||||
|
||||
# Entity tests
|
||||
try:
|
||||
entity = test_entity_creation(viewport)
|
||||
passed += 1
|
||||
|
||||
path = test_pathfinding(viewport, entity)
|
||||
passed += 1
|
||||
|
||||
test_entity_movement(entity, path)
|
||||
passed += 1
|
||||
|
||||
test_camera_follow(viewport, entity)
|
||||
passed += 1
|
||||
except Exception as e:
|
||||
print(f"[FAIL] Entity tests: {e}")
|
||||
failed += 1
|
||||
|
||||
print("=" * 60)
|
||||
print(f"Results: {passed} passed, {failed} failed")
|
||||
print("=" * 60)
|
||||
|
||||
return failed == 0
|
||||
|
||||
# Run tests
|
||||
if __name__ == "__main__":
|
||||
success = run_all_tests()
|
||||
sys.exit(0 if success else 1)
|
||||
Loading…
Add table
Add a link
Reference in a new issue