Files
modbison/scripts/smoke_test_studio_shell.gd

128 lines
5.1 KiB
GDScript

extends SceneTree
## Headless smoke test for ModBison Studio application shell, menu dispatch,
## docking layout, and project serialization (Task b67bc0dfd35c).
var _failures: int = 0
var _checks: int = 0
const StudioMainClass = preload("res://scripts/studio/studio_main.gd")
const MBWorldProjectIOClass = preload("res://scripts/studio/mbworld_project_io.gd")
const TransformGizmo3DClass = preload("res://scripts/studio/gizmos/transform_gizmo_3d.gd")
const StudioViewportCameraClass = preload("res://scripts/studio/studio_viewport_camera.gd")
func _init() -> void:
print("--- Running Smoke Test: ModBison Studio Application Shell ---")
test_studio_shell_initialization()
test_menu_and_toolbar_actions()
test_template_and_project_io()
test_gizmo_and_camera_controls()
if _failures == 0:
print("--- PASS: All %d studio shell checks passed! ---" % _checks)
quit(0)
else:
printerr("--- FAIL: %d failures out of %d checks ---" % [_failures, _checks])
quit(1)
func _check(desc: String, cond: bool) -> void:
_checks += 1
if cond:
print(" ✓ %s" % desc)
else:
_failures += 1
printerr(" ✗ FAIL: %s" % desc)
func test_studio_shell_initialization() -> void:
print("Testing Studio shell instantiation and docking layout...")
var studio := StudioMainClass.new()
root.add_child(studio)
_check("Studio shell instantiated", studio != null)
_check("EditorCore initialized", studio.core != null)
_check("Top MenuBar exists", studio._menu_bar != null)
_check("Toolbar exists", studio._toolbar != null)
_check("3D SubViewport exists", studio._sub_viewport != null)
_check("Studio Camera exists", studio._camera_3d != null)
_check("3D Transform Gizmo exists", studio._gizmo_3d != null)
_check("Scene Hierarchy Dock exists", studio._hierarchy_dock != null)
_check("Property Inspector Dock exists", studio._inspector_dock != null)
_check("Collections Dock exists", studio._collections_dock != null)
studio.queue_free()
func test_menu_and_toolbar_actions() -> void:
print("Testing Menu Bar registration and tool switching...")
var studio := StudioMainClass.new()
root.add_child(studio)
# Verify menu bar menus
var menu_names: Array[String] = []
for child in studio._menu_bar.get_children():
menu_names.append(child.name)
_check("MenuBar has 'File' menu", menu_names.has("File"))
_check("MenuBar has 'Edit' menu", menu_names.has("Edit"))
_check("MenuBar has 'View' menu", menu_names.has("View"))
_check("MenuBar has 'Model' menu", menu_names.has("Model"))
_check("MenuBar has 'Test' menu", menu_names.has("Test"))
_check("MenuBar has 'Publish' menu", menu_names.has("Publish"))
# Test gizmo mode toggles
studio._set_gizmo_mode(TransformGizmo3DClass.Mode.TRANSLATE)
_check("Gizmo set to TRANSLATE mode", studio._gizmo_3d.current_mode == TransformGizmo3DClass.Mode.TRANSLATE)
studio._set_gizmo_mode(TransformGizmo3DClass.Mode.ROTATE)
_check("Gizmo set to ROTATE mode", studio._gizmo_3d.current_mode == TransformGizmo3DClass.Mode.ROTATE)
studio._set_gizmo_mode(TransformGizmo3DClass.Mode.SCALE)
_check("Gizmo set to SCALE mode", studio._gizmo_3d.current_mode == TransformGizmo3DClass.Mode.SCALE)
studio.queue_free()
func test_template_and_project_io() -> void:
print("Testing Starter Templates and .mbworld Project Serialization...")
# 1. Baseplate template
var baseplate_data := MBWorldProjectIOClass.create_template("baseplate")
_check("Baseplate template has spawn pad object", baseplate_data["objects"].size() >= 1)
# 2. Obby template
var obby_data := MBWorldProjectIOClass.create_template("obby")
_check("Obby template has multiple platforms", obby_data["objects"].size() >= 3)
# 3. Save to disk and reload
var test_path := "user://smoke_test_project.mbworld"
var save_ok := MBWorldProjectIOClass.save_project(test_path, obby_data)
_check("Successfully saved .mbworld project file", save_ok)
_check("Project file exists on disk", FileAccess.file_exists(test_path))
var loaded_data := MBWorldProjectIOClass.load_project(test_path)
_check("Loaded project contains matching title", loaded_data.get("title") == obby_data.get("title"))
_check("Loaded project contains same object count", loaded_data.get("objects", []).size() == obby_data.get("objects", []).size())
# Clean up file
DirAccess.remove_absolute(test_path)
func test_gizmo_and_camera_controls() -> void:
print("Testing Camera presets and Gizmo snapping...")
var studio := StudioMainClass.new()
root.add_child(studio)
# Test camera presets
studio._camera_3d.set_view_preset(StudioViewportCameraClass.ViewPreset.TOP)
_check("Camera switched to Top orthographic view", studio._camera_3d.projection == Camera3D.PROJECTION_ORTHOGONAL)
studio._camera_3d.set_view_preset(StudioViewportCameraClass.ViewPreset.PERSPECTIVE)
_check("Camera returned to Perspective projection", studio._camera_3d.projection == Camera3D.PROJECTION_PERSPECTIVE)
# Test gizmo snapping
studio._gizmo_3d.set_snap(true, 2.0, 45.0)
_check("Gizmo translate snap set to 2.0", is_equal_approx(studio._gizmo_3d.snap_translate, 2.0))
_check("Gizmo rotate snap set to 45 degrees", is_equal_approx(studio._gizmo_3d.snap_rotate_deg, 45.0))
studio.queue_free()