extends "res://tests/test_case.gd" const AdaptiveInputDepthController = preload("res://scripts/adaptive_input_depth_controller.gd") func test_starts_safe_and_enters_zero_only_after_sustained_clean_samples() -> void: var policy := AdaptiveInputDepthController.new() assert_eq(policy.target_depth, 1, "starts at one buffered tick") for _i in AdaptiveInputDepthController.REQUIRED_STABLE_TICKS - 1: assert_eq(policy.update(8.0, 2.0, 0), 1, "does not enter zero before enough stable observations") assert_eq(policy.update(8.0, 2.0, 0), 0, "enters zero after the stable observation threshold") func test_starvation_exits_zero_immediately_and_enforces_cooldown() -> void: var policy := AdaptiveInputDepthController.new() for _i in AdaptiveInputDepthController.REQUIRED_STABLE_TICKS: policy.update(8.0, 2.0, 0) assert_eq(policy.target_depth, 0, "precondition: clean link entered zero") assert_eq(policy.update(8.0, 2.0, -2), 1, "starvation sentinel immediately restores one tick") for _i in AdaptiveInputDepthController.REENTRY_COOLDOWN_TICKS: assert_eq(policy.update(8.0, 2.0, 0), 1, "cooldown prevents immediate zero-depth re-entry") for _i in AdaptiveInputDepthController.REQUIRED_STABLE_TICKS: policy.update(8.0, 2.0, 0) assert_eq(policy.target_depth, 0, "zero-depth can re-enter only after cooldown plus a fresh stable window") func test_high_jitter_exits_zero_immediately() -> void: var policy := AdaptiveInputDepthController.new() for _i in AdaptiveInputDepthController.REQUIRED_STABLE_TICKS: policy.update(8.0, 2.0, 0) assert_eq(policy.update(8.0, 5.1, 0), 1, "jitter above exit threshold restores safe depth immediately")