157 lines
4.5 KiB
GDScript
157 lines
4.5 KiB
GDScript
# Unit tests for static helpers on `res://scripts/player_locomotion_wasd.gd` (NEO-22 seam math).
|
|
extends GdUnitTestSuite
|
|
|
|
const LocomotionWasdScript: GDScript = preload("res://scripts/player_locomotion_wasd.gd")
|
|
## Must match [constant FLOOR_RAY_FEET_INVALID] in [code]player_locomotion_wasd.gd[/code].
|
|
const FLOOR_RAY_FEET_INVALID: float = -1.0e9
|
|
|
|
|
|
func test_evaluate_floor_ray_hit_y_rejects_hit_too_far_below_feet() -> void:
|
|
# Arrange
|
|
var feet_y := 0.0
|
|
var hit_y := feet_y - 0.2
|
|
var n := Vector3.UP
|
|
# Act
|
|
var out: float = LocomotionWasdScript.evaluate_floor_ray_hit_y(feet_y, hit_y, n, 0.108, 0.42)
|
|
# Assert
|
|
assert_that(out).is_equal(FLOOR_RAY_FEET_INVALID)
|
|
|
|
|
|
func test_evaluate_floor_ray_hit_y_rejects_shallow_floor_normal() -> void:
|
|
# Arrange
|
|
var feet_y := 0.0
|
|
var hit_y := 0.0
|
|
# Up component ~0.37 so dot(Vector3.UP, n) is below min_floor_up_dot (0.42).
|
|
var n := Vector3(0.85, 0.35, 0.0).normalized()
|
|
# Act
|
|
var out: float = LocomotionWasdScript.evaluate_floor_ray_hit_y(feet_y, hit_y, n, 0.108, 0.42)
|
|
# Assert
|
|
assert_that(out).is_equal(FLOOR_RAY_FEET_INVALID)
|
|
|
|
|
|
func test_evaluate_floor_ray_hit_y_accepts_valid_hit() -> void:
|
|
# Arrange
|
|
var feet_y := 0.0
|
|
var hit_y := -0.04
|
|
var n := Vector3.UP
|
|
# Act
|
|
var out: float = LocomotionWasdScript.evaluate_floor_ray_hit_y(feet_y, hit_y, n, 0.108, 0.42)
|
|
# Assert
|
|
assert_that(out).is_equal(hit_y)
|
|
|
|
|
|
func test_median_feet_y_from_samples_empty_is_invalid() -> void:
|
|
# Arrange
|
|
var empty: Array[float] = []
|
|
# Act
|
|
var out: float = LocomotionWasdScript.median_feet_y_from_samples(empty)
|
|
# Assert
|
|
assert_that(out).is_equal(FLOOR_RAY_FEET_INVALID)
|
|
|
|
|
|
func test_median_feet_y_from_samples_single() -> void:
|
|
# Arrange
|
|
var samples: Array[float] = [0.12]
|
|
# Act
|
|
var out: float = LocomotionWasdScript.median_feet_y_from_samples(samples)
|
|
# Assert
|
|
assert_that(out).is_equal(0.12)
|
|
|
|
|
|
func test_median_feet_y_from_samples_three_sorted_middle() -> void:
|
|
# Arrange
|
|
var samples: Array[float] = [0.3, 0.1, 0.2]
|
|
# Act
|
|
var out: float = LocomotionWasdScript.median_feet_y_from_samples(samples)
|
|
# Assert
|
|
assert_that(out).is_equal(0.2)
|
|
|
|
|
|
func test_median_feet_y_from_samples_two_uses_lower_index() -> void:
|
|
# Arrange
|
|
# Matches runtime: mid index (n-1)>>1 picks the smaller of two sorted values.
|
|
var samples: Array[float] = [0.5, 0.1]
|
|
# Act
|
|
var out: float = LocomotionWasdScript.median_feet_y_from_samples(samples)
|
|
# Assert
|
|
assert_that(out).is_equal(0.1)
|
|
|
|
|
|
func test_xz_after_micro_slip_projection_zero_wish_unchanged() -> void:
|
|
# Arrange
|
|
var anchor := Vector2.ZERO
|
|
var player_xz := Vector2(0.02, 0.03)
|
|
# Act
|
|
var out: Vector2 = LocomotionWasdScript.xz_after_micro_slip_projection(
|
|
anchor, player_xz, Vector2.ZERO, 0.032
|
|
)
|
|
# Assert
|
|
assert_that(out).is_equal(player_xz)
|
|
|
|
|
|
func test_xz_after_micro_slip_projection_large_perp_unchanged() -> void:
|
|
# Arrange
|
|
var anchor := Vector2.ZERO
|
|
var player_xz := Vector2(0.0, 0.2)
|
|
var wish := Vector2(1.0, 0.0)
|
|
# Act
|
|
var out: Vector2 = LocomotionWasdScript.xz_after_micro_slip_projection(
|
|
anchor, player_xz, wish, 0.032
|
|
)
|
|
# Assert
|
|
assert_that(out).is_equal(player_xz)
|
|
|
|
|
|
func test_xz_after_micro_slip_projection_nudges_small_perp() -> void:
|
|
# Arrange
|
|
var anchor := Vector2.ZERO
|
|
var player_xz := Vector2(0.0, 0.01)
|
|
var wish := Vector2(1.0, 0.0)
|
|
# Act
|
|
var out: Vector2 = LocomotionWasdScript.xz_after_micro_slip_projection(
|
|
anchor, player_xz, wish, 0.032
|
|
)
|
|
# Assert
|
|
assert_that(out.x).is_equal(0.0)
|
|
assert_that(out.y).is_equal(0.0)
|
|
|
|
|
|
func test_horizontal_velocity_aligned_to_wish_zero_wish_returns_velocity() -> void:
|
|
# Arrange
|
|
# Act
|
|
var out: Vector2 = LocomotionWasdScript.horizontal_velocity_aligned_to_wish(
|
|
Vector2.ZERO, Vector2(3.0, 4.0), 5.0
|
|
)
|
|
# Assert
|
|
assert_that(out).is_equal(Vector2(3.0, 4.0))
|
|
|
|
|
|
func test_horizontal_velocity_aligned_to_wish_clamps_negative_along_to_zero() -> void:
|
|
# Arrange
|
|
# Act
|
|
var out: Vector2 = LocomotionWasdScript.horizontal_velocity_aligned_to_wish(
|
|
Vector2(1.0, 0.0), Vector2(-2.0, 0.0), 5.0
|
|
)
|
|
# Assert
|
|
assert_that(out).is_equal(Vector2.ZERO)
|
|
|
|
|
|
func test_horizontal_velocity_aligned_to_wish_caps_speed() -> void:
|
|
# Arrange
|
|
# Act
|
|
var out: Vector2 = LocomotionWasdScript.horizontal_velocity_aligned_to_wish(
|
|
Vector2(1.0, 0.0), Vector2(10.0, 0.0), 5.0
|
|
)
|
|
# Assert
|
|
assert_that(out).is_equal(Vector2(5.0, 0.0))
|
|
|
|
|
|
func test_horizontal_velocity_aligned_to_wish_preserves_wish_direction() -> void:
|
|
# Arrange
|
|
# Act
|
|
var out: Vector2 = LocomotionWasdScript.horizontal_velocity_aligned_to_wish(
|
|
Vector2(0.0, 1.0), Vector2(0.0, 2.0), 5.0
|
|
)
|
|
# Assert
|
|
assert_that(out).is_equal(Vector2(0.0, 2.0))
|