## Free camera mode tests (#898). ## Covers GameState flag default, InputMapper suppression, and zoom clamping. class_name TestFreeCamera extends GdUnitTestSuite func before_test() -> void: GameState.free_camera_mode = false func after_test() -> void: GameState.free_camera_mode = false # -- GameState.free_camera_mode default ---------------------------------------- func test_free_camera_mode_starts_false() -> void: ## #898: Free camera is off by default — normal gameplay on startup. assert_bool(GameState.free_camera_mode).override_failure_message( "GameState.free_camera_mode must default to false" ).is_false() # -- InputMapper suppression --------------------------------------------------- func test_input_mapper_suppresses_movement_in_free_camera_mode() -> void: ## #898: While free camera is active, InputMapper._process() returns early so ## no movement actions enter the queue. GameState.free_camera_mode = true var before := InputMapper.input_queue.size() InputMapper._process(0.016) var after := InputMapper.input_queue.size() assert_int(after).override_failure_message( "InputMapper must not enqueue movement while free_camera_mode is true" ).is_equal(before) InputMapper.input_queue.clear() func test_input_mapper_suppresses_discrete_actions_in_free_camera_mode() -> void: ## #898: _unhandled_input returns early in free camera — INTERACT and stance ## actions must not be queued. GameState.free_camera_mode = true var before := InputMapper.input_queue.size() var fake_event := InputEventAction.new() fake_event.action = "interact" fake_event.pressed = true InputMapper._unhandled_input(fake_event) assert_int(InputMapper.input_queue.size()).override_failure_message( "InputMapper must not enqueue discrete actions while free_camera_mode is true" ).is_equal(before) InputMapper.input_queue.clear() func test_input_mapper_resumes_after_free_camera_off() -> void: ## Turning free camera off lifts the suppression — _process runs normally again. GameState.free_camera_mode = true GameState.free_camera_mode = false ## _process should no longer return early (queue may or may not grow depending ## on held keys, but no crash and guard is lifted). InputMapper._process(0.016) assert_bool(true).is_true() # no crash = pass InputMapper.input_queue.clear() # -- Zoom clamp contract ------------------------------------------------------- func test_zoom_min_constant_is_0_5() -> void: ## #898: Minimum zoom keeps the world recognisable. var main_script = load("res://scripts/main.gd") assert_float(main_script.FREE_CAMERA_ZOOM_MIN).override_failure_message( "FREE_CAMERA_ZOOM_MIN must be 0.5" ).is_equal_approx(0.5, 0.001) func test_zoom_max_constant_is_8() -> void: ## #898: Maximum zoom must not exceed 8× per spec. var main_script = load("res://scripts/main.gd") assert_float(main_script.FREE_CAMERA_ZOOM_MAX).override_failure_message( "FREE_CAMERA_ZOOM_MAX must be 8.0" ).is_equal_approx(8.0, 0.001) func test_zoom_step_is_positive() -> void: ## Zoom step must be > 0 so scroll wheel does something. var main_script = load("res://scripts/main.gd") assert_float(main_script.FREE_CAMERA_ZOOM_STEP).override_failure_message( "FREE_CAMERA_ZOOM_STEP must be positive" ).is_greater(0.0)