Files
modbison/scripts/smoke_test_player.gd
T

85 lines
3.1 KiB
GDScript

extends SceneTree
## Smoke test for the player character scene and its spawn behavior.
##
## Run with:
## godot --headless --path . --script res://scripts/smoke_test_player.gd
##
## Loads the test level, verifies the player is present, spawned at the
## PlayerSpawn marker, and has the expected CharacterBody3D structure.
var _passed := 0
var _failed := 0
func _initialize() -> void:
print("SMOKE: starting player smoke test")
_run()
func _run() -> void:
await process_frame
print("SMOKE: loading test level scene")
# Load the test level scene (which includes the player).
var packed: PackedScene = load("res://scenes/worlds/test_level.tscn")
var level: Node3D = packed.instantiate()
# Order matters: set_current_scene() requires the node's parent to already
# be root, so add_child() must come first. This mirrors what a real
# change_scene_to_packed() does at runtime.
root.add_child(level)
current_scene = level
print("SMOKE: level instantiated, waiting for ready")
await level.ready
print("SMOKE: level ready")
# 1. Verify the player node exists in the scene tree.
var player: Node = level.get_node("Player")
_check("Player node exists in test level", player != null)
_check("Player is a CharacterBody3D", player is CharacterBody3D)
# 2. Verify the player has the expected child structure.
var collision: Node = player.get_node("CollisionShape3D")
_check("Player has CollisionShape3D", collision != null)
_check("CollisionShape3D has a shape",
collision is CollisionShape3D and (collision as CollisionShape3D).shape != null)
var mesh: Node = player.get_node("CapsuleMesh")
_check("Player has CapsuleMesh", mesh != null)
_check("CapsuleMesh has a mesh",
mesh is MeshInstance3D and (mesh as MeshInstance3D).mesh != null)
# 3. Verify the player spawned at the PlayerSpawn marker position.
var spawn_marker: Marker3D = level.get_node("PlayerSpawn")
_check("PlayerSpawn marker exists", spawn_marker != null)
# The player's _ready() should have moved it to the spawn marker's
# global position. Since both are direct children of the level root
# (and the level root is at the origin), their global positions equal
# their local positions.
var expected_pos: Vector3 = spawn_marker.global_position
_check("Player spawned at PlayerSpawn position",
player.global_position == expected_pos)
# 4. Verify the player script class_name is correct and has the
# movement constants defined.
var script: GDScript = player.get_script() as GDScript
_check("Player has a script attached", script != null)
var constants: Dictionary = script.get_script_constant_map()
_check("Player has WALK_SPEED constant", constants.has("WALK_SPEED"))
_check("Player has GRAVITY constant", constants.has("GRAVITY"))
_check("Player has JUMP_VELOCITY constant", constants.has("JUMP_VELOCITY"))
print("\n=== SMOKE RESULT: %d/%d passed ===" % [_passed, _passed + _failed])
quit(0 if _failed == 0 else 1)
func _check(description: String, condition: bool) -> void:
if condition:
print(" PASS: ", description)
_passed += 1
else:
printerr(" FAIL: ", description)
_failed += 1