# Static helpers for res://scripts/isometric_follow_camera.gd (NEO-15 framing, NEO-17/28 guards). extends GdUnitTestSuite const IsoScript := preload("res://scripts/isometric_follow_camera.gd") const ZoomBandConfigScript := preload("res://scripts/zoom_band_config.gd") const OcclusionPolicyScript := preload("res://scripts/occlusion_policy.gd") func test_desired_eye_matches_previous_static_camera_frame() -> void: # Arrange var focus := Vector3(-5.0, 0.9, -5.0) var want := Vector3(12.0, 10.0, 12.0) # Act var eye: Vector3 = IsoScript.desired_eye_world( focus, 25.709, deg_to_rad(20.693), deg_to_rad(45.0) ) # Assert assert_that(eye.distance_to(want)).is_less(0.06) func test_effective_follow_distance_fallback_when_config_null() -> void: # Arrange # Act var d: float = IsoScript.effective_follow_distance(null, 3, 12.5) # Assert assert_that(d).is_equal(12.5) func test_effective_follow_distance_uses_config_when_valid() -> void: # Arrange var cfg = ZoomBandConfigScript.new() cfg.band_distances = PackedFloat32Array([10.0, 20.0, 30.0]) # Act var d: float = IsoScript.effective_follow_distance(cfg, 1, 99.0) # Assert assert_that(d).is_equal(20.0) func test_effective_follow_distance_clamps_band_index() -> void: # Arrange var cfg = ZoomBandConfigScript.new() cfg.band_distances = PackedFloat32Array([10.0, 20.0]) # Act var high: float = IsoScript.effective_follow_distance(cfg, 99, 1.0) var low: float = IsoScript.effective_follow_distance(cfg, -3, 1.0) # Assert assert_that(high).is_equal(20.0) assert_that(low).is_equal(10.0) func test_effective_follow_distance_empty_config_bands_falls_back() -> void: # Arrange var cfg = ZoomBandConfigScript.new() cfg.band_distances = PackedFloat32Array() # Act var d: float = IsoScript.effective_follow_distance(cfg, 0, 7.5) # Assert assert_that(d).is_equal(7.5) func test_effective_follow_distance_fallback_when_band_non_positive() -> void: # Arrange var cfg = ZoomBandConfigScript.new() cfg.band_distances = PackedFloat32Array([10.0, 0.0, 30.0]) # Act var d: float = IsoScript.effective_follow_distance(cfg, 2, 99.0) # Assert assert_that(d).is_equal(99.0) func test_occlusion_policy_is_valid_null() -> void: # Arrange # Act var ok: bool = IsoScript.occlusion_policy_is_valid(null) # Assert assert_that(ok).is_false() func test_occlusion_policy_is_valid_wrong_script() -> void: # Arrange var wrong = ZoomBandConfigScript.new() # Act var ok: bool = IsoScript.occlusion_policy_is_valid(wrong) # Assert assert_that(ok).is_false() func test_occlusion_policy_is_valid_correct_script() -> void: # Arrange var p = OcclusionPolicyScript.new() # Act var ok: bool = IsoScript.occlusion_policy_is_valid(p) # Assert assert_that(ok).is_true() func test_occlusion_policy_is_valid_false_when_disabled() -> void: # Arrange var p = OcclusionPolicyScript.new() p.enabled = false # Act var ok: bool = IsoScript.occlusion_policy_is_valid(p) # Assert assert_that(ok).is_false() func test_occluder_override_key_is_valid_null() -> void: # Arrange # Act var ok: bool = IsoScript.occluder_override_key_is_valid(null) # Assert assert_that(ok).is_false() func test_occluder_override_key_is_valid_non_node() -> void: # Arrange # Act var ok: bool = IsoScript.occluder_override_key_is_valid(42) # Assert assert_that(ok).is_false() func test_occluder_override_key_is_valid_live_node3d() -> void: # Arrange var n := Node3D.new() # Act var ok: bool = IsoScript.occluder_override_key_is_valid(n) # Assert assert_that(ok).is_true() n.free() func test_occluder_override_key_is_valid_false_after_free() -> void: # Arrange var n := Node3D.new() n.free() # Act var ok: bool = IsoScript.occluder_override_key_is_valid(n) # Assert assert_that(ok).is_false() func test_consume_pan_zoom_accumulator_ignores_horizontal_pan() -> void: # Arrange # Act var result: Dictionary = IsoScript.consume_pan_zoom_accumulator(0.0, Vector2(0.2, 0.0)) # Assert assert_that(int(result.get("step", -9))).is_equal(0) assert_that(float(result.get("accumulator", -1.0))).is_equal(0.0) func test_consume_pan_zoom_accumulator_requires_threshold_before_step() -> void: # Arrange # Act var partial: Dictionary = IsoScript.consume_pan_zoom_accumulator(0.0, Vector2(0.0, -0.4)) var complete: Dictionary = IsoScript.consume_pan_zoom_accumulator( float(partial.get("accumulator", 0.0)), Vector2(0.0, -0.9) ) # Assert assert_that(int(partial.get("step", -9))).is_equal(0) assert_that(int(complete.get("step", -9))).is_equal(-1) func test_consume_pan_zoom_accumulator_emits_one_step_per_call_even_for_large_delta() -> void: # Arrange # Act var result: Dictionary = IsoScript.consume_pan_zoom_accumulator(0.0, Vector2(0.0, -5.0)) # Assert assert_that(int(result.get("step", -9))).is_equal(-1) assert_that(float(result.get("accumulator", 0.0))).is_equal(-3.75) func test_consume_magnify_zoom_accumulator_requires_threshold_before_step() -> void: # Arrange # Act var partial: Dictionary = IsoScript.consume_magnify_zoom_accumulator(0.0, 1.05) var complete: Dictionary = IsoScript.consume_magnify_zoom_accumulator( float(partial.get("accumulator", 0.0)), 1.12 ) # Assert assert_that(int(partial.get("step", -9))).is_equal(0) assert_that(int(complete.get("step", -9))).is_equal(-1)