extends RefCounted ## Headless tests for movement constants, surface lookup, gamepad bindings, and ## the settings that drive the camera feel. const GuardController := preload("res://src/game/guard_controller.gd") func test_surface_lookup_covers_the_block() -> bool: var guard := GuardController.new() var a := TestUtils.check_eq(guard._surface_at(Vector3(0, 0.2, 2.0)), "stone", "the entrance steps are stone") var b := TestUtils.check_eq(guard._surface_at(Vector3(3, 0.2, 8.0)), "concrete", "the sidewalk is concrete") var c := TestUtils.check_eq(guard._surface_at(Vector3(2, 0.1, 18.0)), "asphalt", "the roadway is asphalt") guard.free() return a and b and c func test_step_and_stride_stay_modest() -> bool: var a := TestUtils.check(GuardController.STEP_HEIGHT <= 0.35, "step-up stays at kerb height") var b := TestUtils.check(GuardController.STRIDE_LENGTH >= 0.5 and GuardController.STRIDE_LENGTH <= 1.2, "stride stays human-sized") var c := TestUtils.check(GuardController.SLOW_WALK_FACTOR < 1.0 and GuardController.SLOW_WALK_FACTOR > 0.3, "precision walk is slower but usable") return a and b and c func test_gamepad_bindings_are_added_once() -> bool: GuardController._ensure_gamepad_bindings() GuardController._ensure_gamepad_bindings() var expected := ["look_left", "look_right", "look_up", "look_down", "move_forward", "move_back", "move_left", "move_right"] var problems: Array[String] = [] for action in expected: if not InputMap.has_action(action): problems.append("%s missing" % action) continue var motions := 0 for event in InputMap.action_get_events(action): if event is InputEventJoypadMotion: motions += 1 if motions == 0: problems.append("%s has no joypad axis" % action) if InputMap.action_get_deadzone(action) > 0.25: problems.append("%s deadzone too high" % action) var buttons := {"action_menu": JOY_BUTTON_A, "cancel": JOY_BUTTON_B, "ui_accept": JOY_BUTTON_A, "ui_cancel": JOY_BUTTON_B, "inspect": JOY_BUTTON_X, "walk_slow": JOY_BUTTON_LEFT_SHOULDER} for action in buttons.keys(): var found := false for event in InputMap.action_get_events(action): if event is InputEventJoypadButton and event.button_index == buttons[action]: found = true if not found: problems.append("%s has no gamepad button" % action) return TestUtils.check(problems.is_empty(), "gamepad actions bound (%s)" % str(problems))