96 lines
3.4 KiB
Python
96 lines
3.4 KiB
Python
#!/usr/bin/env python3
|
|
|
|
import importlib.util
|
|
import unittest
|
|
from pathlib import Path
|
|
|
|
from engine import maze
|
|
|
|
|
|
MODULE_PATH = Path(__file__).resolve().parent / "tools" / "level_editor.py"
|
|
SPEC = importlib.util.spec_from_file_location("level_editor_module", MODULE_PATH)
|
|
level_editor = importlib.util.module_from_spec(SPEC)
|
|
SPEC.loader.exec_module(level_editor)
|
|
|
|
|
|
class LevelEditorLogicTests(unittest.TestCase):
|
|
def test_compute_canvas_layout_scales_to_viewport(self):
|
|
layout = level_editor.compute_canvas_layout(
|
|
maze.LEVEL_WIDTH,
|
|
maze.LEVEL_HEIGHT,
|
|
1200,
|
|
900,
|
|
level_editor.DEFAULT_CELL_SIZE,
|
|
True,
|
|
)
|
|
|
|
self.assertGreater(layout["cell_size"], level_editor.DEFAULT_CELL_SIZE)
|
|
self.assertAlmostEqual(layout["cell_size"], (900 - level_editor.VIEWPORT_PADDING * 2) / maze.LEVEL_HEIGHT)
|
|
self.assertAlmostEqual(layout["origin_y"], level_editor.VIEWPORT_PADDING)
|
|
self.assertGreater(layout["origin_x"], 0)
|
|
|
|
def test_compute_canvas_layout_centers_manual_zoom(self):
|
|
layout = level_editor.compute_canvas_layout(
|
|
maze.LEVEL_WIDTH,
|
|
maze.LEVEL_HEIGHT,
|
|
1000,
|
|
800,
|
|
16,
|
|
False,
|
|
)
|
|
|
|
self.assertEqual(layout["cell_size"], 16)
|
|
self.assertGreater(layout["origin_x"], 0)
|
|
self.assertGreater(layout["origin_y"], 0)
|
|
|
|
def test_fit_level_to_dat_size_centers_small_map(self):
|
|
source = [
|
|
[maze.MAP_WALL, maze.MAP_EMPTY],
|
|
[maze.MAP_TUNNEL, maze.MAP_EMPTY],
|
|
]
|
|
|
|
fitted = level_editor.fit_level_to_dat_size(source)
|
|
|
|
self.assertEqual(len(fitted), maze.LEVEL_HEIGHT)
|
|
self.assertEqual(len(fitted[0]), maze.LEVEL_WIDTH)
|
|
|
|
start_x = (maze.LEVEL_WIDTH - len(source[0])) // 2
|
|
start_y = (maze.LEVEL_HEIGHT - len(source)) // 2
|
|
self.assertEqual(fitted[start_y][start_x], maze.MAP_WALL)
|
|
self.assertEqual(fitted[start_y][start_x + 1], maze.MAP_EMPTY)
|
|
self.assertEqual(fitted[start_y + 1][start_x], maze.MAP_TUNNEL)
|
|
self.assertEqual(fitted[start_y + 1][start_x + 1], maze.MAP_EMPTY)
|
|
|
|
def test_compute_level_stats_reports_spawnable_default_level(self):
|
|
level = maze.create_level()
|
|
|
|
stats = level_editor.compute_level_stats(level)
|
|
|
|
self.assertEqual(stats["width"], maze.LEVEL_WIDTH)
|
|
self.assertEqual(stats["height"], maze.LEVEL_HEIGHT)
|
|
self.assertEqual(stats["border_openings"], 0)
|
|
self.assertEqual(stats["component_count"], 1)
|
|
self.assertGreater(stats["spawnable_count"], 0)
|
|
self.assertEqual(stats["warnings"], [])
|
|
|
|
def test_compute_level_stats_flags_unusable_map(self):
|
|
level = [[maze.MAP_WALL for _ in range(maze.LEVEL_WIDTH)] for _ in range(maze.LEVEL_HEIGHT)]
|
|
|
|
stats = level_editor.compute_level_stats(level)
|
|
|
|
self.assertEqual(stats["traversable_count"], 0)
|
|
self.assertEqual(stats["spawnable_count"], 0)
|
|
self.assertIn("nessuna cella attraversabile", stats["warnings"])
|
|
self.assertIn("nessuna cella EMPTY: niente spawn e niente armi", stats["warnings"])
|
|
|
|
def test_missing_tkinter_is_reported_cleanly(self):
|
|
if level_editor.TKINTER_IMPORT_ERROR is None:
|
|
level_editor.ensure_tkinter_available()
|
|
return
|
|
|
|
with self.assertRaises(RuntimeError):
|
|
level_editor.ensure_tkinter_available()
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main() |