From b90fedf7a8e79ecc4c4ed2ec8be3cb75b0d8c9d1 Mon Sep 17 00:00:00 2001 From: VinPropane Date: Mon, 25 May 2026 13:32:51 -0400 Subject: [PATCH] NEO-85: Fix flaky GdUnit signal assertions in full suite runs. Await async assert_signal calls and match emitted payload args with any() where tests only care that the signal fired, preventing orphaned 2s timeouts that surfaced as false failures in later suites (e.g. hotbar_loadout_client_test). --- client/test/combat_feedback_refresh_test.gd | 2 +- client/test/craft_feedback_refresh_test.gd | 2 +- client/test/gather_feedback_refresh_test.gd | 4 +++- client/test/hotbar_loadout_client_test.gd | 2 +- client/test/interaction_request_client_test.gd | 6 +++--- client/test/inventory_client_test.gd | 6 +++--- client/test/item_definitions_client_test.gd | 4 ++-- client/test/position_authority_client_test.gd | 18 +++++++++--------- client/test/recipe_definitions_client_test.gd | 4 ++-- client/test/skill_progression_client_test.gd | 4 ++-- client/test/target_selection_client_test.gd | 4 ++-- 11 files changed, 29 insertions(+), 27 deletions(-) diff --git a/client/test/combat_feedback_refresh_test.gd b/client/test/combat_feedback_refresh_test.gd index 3eca876..592bb55 100644 --- a/client/test/combat_feedback_refresh_test.gd +++ b/client/test/combat_feedback_refresh_test.gd @@ -91,7 +91,7 @@ func test_successful_cast_triggers_combat_target_sync() -> void: # Act harness.request_cast() # Assert - assert_signal(harness._cast).is_emitted("cast_result_received") + await assert_signal(harness._cast).is_emitted("cast_result_received", true, "", any()) assert_that(harness.combat_sync_calls).is_equal(1) assert_that(harness._combat.sync_calls).is_equal(1) diff --git a/client/test/craft_feedback_refresh_test.gd b/client/test/craft_feedback_refresh_test.gd index 10ed5d0..9025467 100644 --- a/client/test/craft_feedback_refresh_test.gd +++ b/client/test/craft_feedback_refresh_test.gd @@ -72,7 +72,7 @@ func test_successful_craft_triggers_both_refreshes() -> void: # Act harness.post_craft("refine_scrap_standard") # Assert - assert_signal(harness._craft).is_emitted("craft_result_received") + await assert_signal(harness._craft).is_emitted("craft_result_received", "refine_scrap_standard", any()) assert_that(harness._inventory.sync_calls).is_equal(1) assert_that(harness._skill.sync_calls).is_equal(1) diff --git a/client/test/gather_feedback_refresh_test.gd b/client/test/gather_feedback_refresh_test.gd index 87768ac..26939e7 100644 --- a/client/test/gather_feedback_refresh_test.gd +++ b/client/test/gather_feedback_refresh_test.gd @@ -109,7 +109,9 @@ func test_allowed_resource_interact_triggers_both_refreshes() -> void: # Act harness.post_resource_alpha() # Assert - assert_signal(harness._ix).is_emitted("interaction_result_received") + await assert_signal(harness._ix).is_emitted( + "interaction_result_received", "prototype_resource_node_alpha", true, "" + ) assert_that(harness._inventory.sync_calls).is_equal(1) assert_that(harness._skill.sync_calls).is_equal(1) diff --git a/client/test/hotbar_loadout_client_test.gd b/client/test/hotbar_loadout_client_test.gd index 4cf358d..671bb51 100644 --- a/client/test/hotbar_loadout_client_test.gd +++ b/client/test/hotbar_loadout_client_test.gd @@ -156,7 +156,7 @@ func test_denied_update_emits_reason_signal() -> void: # Act c.call("request_bind_slot", 1, "not_real") # Assert - assert_signal(c).is_emitted("loadout_update_denied") + await assert_signal(c).is_emitted("loadout_update_denied", "unknown_ability", any()) func test_bind_slot_while_busy_is_ignored() -> void: diff --git a/client/test/interaction_request_client_test.gd b/client/test/interaction_request_client_test.gd index d26cd47..4e90c96 100644 --- a/client/test/interaction_request_client_test.gd +++ b/client/test/interaction_request_client_test.gd @@ -118,7 +118,7 @@ func test_interaction_result_emits_allow_signal() -> void: # Act ix.call("post_interact_id", "prototype_resource_node_alpha") # Assert - assert_signal(ix).is_emitted( + await assert_signal(ix).is_emitted( "interaction_result_received", "prototype_resource_node_alpha", true, "" ) @@ -132,7 +132,7 @@ func test_interaction_result_emits_deny_signal() -> void: # Act ix.call("post_interact_id", "prototype_urban_bulk_delta") # Assert - assert_signal(ix).is_emitted( + await assert_signal(ix).is_emitted( "interaction_result_received", "prototype_urban_bulk_delta", false, "node_depleted" ) @@ -146,7 +146,7 @@ func test_interaction_request_failed_emits_on_http_error() -> void: # Act ix.call("post_interact_id", "prototype_resource_node_alpha") # Assert - assert_signal(ix).is_emitted( + await assert_signal(ix).is_emitted( "interaction_request_failed", "prototype_resource_node_alpha", "HTTP 500" ) diff --git a/client/test/inventory_client_test.gd b/client/test/inventory_client_test.gd index 2b0820a..ea39ebb 100644 --- a/client/test/inventory_client_test.gd +++ b/client/test/inventory_client_test.gd @@ -82,7 +82,7 @@ func test_request_sync_emits_inventory_received() -> void: # Act c.call("request_sync_from_server") # Assert - assert_signal(c).is_emitted("inventory_received") + await assert_signal(c).is_emitted("inventory_received", any()) assert_that(_inventory_capture.has("bagSlots")).is_true() assert_that((_inventory_capture["bagSlots"] as Array).size()).is_equal(24) assert_that((_inventory_capture["equipmentSlots"] as Array).size()).is_equal(1) @@ -98,7 +98,7 @@ func test_http_404_emits_inventory_sync_failed() -> void: # Act c.call("request_sync_from_server") # Assert - assert_signal(c).is_emitted("inventory_sync_failed", "HTTP 404 (player unknown)") + await assert_signal(c).is_emitted("inventory_sync_failed", "HTTP 404 (player unknown)") func test_malformed_json_emits_inventory_sync_failed() -> void: @@ -110,4 +110,4 @@ func test_malformed_json_emits_inventory_sync_failed() -> void: # Act c.call("request_sync_from_server") # Assert - assert_signal(c).is_emitted("inventory_sync_failed") + await assert_signal(c).is_emitted("inventory_sync_failed", any()) diff --git a/client/test/item_definitions_client_test.gd b/client/test/item_definitions_client_test.gd index cea7b47..e7dffc4 100644 --- a/client/test/item_definitions_client_test.gd +++ b/client/test/item_definitions_client_test.gd @@ -84,7 +84,7 @@ func test_request_sync_hits_definitions_endpoint_and_emits() -> void: c.call("request_sync_from_server") # Assert assert_that(transport.last_url).contains("/game/world/item-definitions") - assert_signal(c).is_emitted("definitions_ready") + await assert_signal(c).is_emitted("definitions_ready", any()) func test_display_name_for_after_request_sync() -> void: @@ -107,4 +107,4 @@ func test_http_error_does_not_emit_definitions_ready() -> void: # Act c.call("request_sync_from_server") # Assert - assert_signal(c).wait_until(400).is_not_emitted("definitions_ready") + await assert_signal(c).wait_until(400).is_not_emitted("definitions_ready") diff --git a/client/test/position_authority_client_test.gd b/client/test/position_authority_client_test.gd index 89acc39..8690f9d 100644 --- a/client/test/position_authority_client_test.gd +++ b/client/test/position_authority_client_test.gd @@ -65,7 +65,7 @@ func test_sync_boot_get_200_emits_snap() -> void: # Act c.sync_from_server() # Assert - assert_signal(c).is_emitted("authoritative_position_received", Vector3(1.0, 0.9, -5.0), true) + await assert_signal(c).is_emitted("authoritative_position_received", Vector3(1.0, 0.9, -5.0), true) # NEO-24: boot sync also emits the cooldown-throttled heartbeat. @@ -78,7 +78,7 @@ func test_sync_boot_get_200_emits_authoritative_ack() -> void: # Act c.sync_from_server() # Assert - assert_signal(c).is_emitted("authoritative_ack", Vector3(1.0, 0.9, -5.0)) + await assert_signal(c).is_emitted("authoritative_ack", Vector3(1.0, 0.9, -5.0)) func test_sync_boot_get_200_malformed_position_does_not_emit() -> void: @@ -90,7 +90,7 @@ func test_sync_boot_get_200_malformed_position_does_not_emit() -> void: # Act c.sync_from_server() # Assert - assert_signal(c).wait_until(400).is_not_emitted("authoritative_position_received") + await assert_signal(c).wait_until(400).is_not_emitted("authoritative_position_received") func test_move_stream_post_400_emits_move_rejected_then_boot_get() -> void: @@ -103,8 +103,8 @@ func test_move_stream_post_400_emits_move_rejected_then_boot_get() -> void: # Act c.submit_stream_targets([Vector3(1.0, 2.0, 3.0)]) # Assert - assert_signal(c).is_emitted("move_rejected", "vertical_step_exceeded") - assert_signal(c).is_emitted("authoritative_position_received", Vector3(0.0, 0.9, 0.0), true) + await assert_signal(c).is_emitted("move_rejected", "vertical_step_exceeded") + await assert_signal(c).is_emitted("authoritative_position_received", Vector3(0.0, 0.9, 0.0), true) func test_move_stream_post_400_without_reason_emits_unknown() -> void: @@ -117,8 +117,8 @@ func test_move_stream_post_400_without_reason_emits_unknown() -> void: # Act c.submit_stream_targets([Vector3.ZERO]) # Assert - assert_signal(c).is_emitted("move_rejected", "unknown") - assert_signal(c).is_emitted("authoritative_position_received", Vector3(1.0, 0.9, 1.0), true) + await assert_signal(c).is_emitted("move_rejected", "unknown") + await assert_signal(c).is_emitted("authoritative_position_received", Vector3(1.0, 0.9, 1.0), true) func test_second_sync_while_busy_is_ignored() -> void: @@ -148,7 +148,7 @@ func test_move_stream_post_200_does_not_emit_position() -> void: # Act c.submit_stream_targets([Vector3(-4.9, 0.9, -5.0)]) # Assert - assert_signal(c).wait_until(400).is_not_emitted("authoritative_position_received") + await assert_signal(c).wait_until(400).is_not_emitted("authoritative_position_received") # NEO-24: move-stream 200 must emit `authoritative_ack` so a held target lock can re-validate @@ -169,4 +169,4 @@ func test_move_stream_post_200_emits_authoritative_ack() -> void: # Act c.submit_stream_targets([Vector3(-4.9, 0.9, -5.0)]) # Assert - assert_signal(c).is_emitted("authoritative_ack", Vector3(-4.9, 0.9, -5.0)) + await assert_signal(c).is_emitted("authoritative_ack", Vector3(-4.9, 0.9, -5.0)) diff --git a/client/test/recipe_definitions_client_test.gd b/client/test/recipe_definitions_client_test.gd index 21f7d28..7c0d2cf 100644 --- a/client/test/recipe_definitions_client_test.gd +++ b/client/test/recipe_definitions_client_test.gd @@ -80,7 +80,7 @@ func test_request_sync_emits_recipes_ready_in_order() -> void: # Act c.call("request_sync_from_server") # Assert - assert_signal(c).is_emitted("recipes_ready") + await assert_signal(c).is_emitted("recipes_ready", any()) assert_that(_recipes_capture.size()).is_equal(2) assert_that(str(_recipes_capture[0].get("id", ""))).is_equal("make_armor_quick") assert_that(transport.last_url).contains("/recipe-definitions") @@ -95,7 +95,7 @@ func test_schema_mismatch_emits_recipes_sync_failed() -> void: # Act c.call("request_sync_from_server") # Assert - assert_signal(c).is_emitted("recipes_sync_failed") + await assert_signal(c).is_emitted("recipes_sync_failed", any()) func test_http_error_emits_recipes_sync_failed_with_status() -> void: diff --git a/client/test/skill_progression_client_test.gd b/client/test/skill_progression_client_test.gd index a5c3d0d..334df4e 100644 --- a/client/test/skill_progression_client_test.gd +++ b/client/test/skill_progression_client_test.gd @@ -80,7 +80,7 @@ func test_request_sync_emits_progression_received() -> void: # Act c.call("request_sync_from_server") # Assert - assert_signal(c).is_emitted("progression_received") + await assert_signal(c).is_emitted("progression_received", any()) assert_that(_progression_capture.has("skills")).is_true() assert_that(transport.last_url).contains("/skill-progression") @@ -94,4 +94,4 @@ func test_http_404_emits_progression_sync_failed() -> void: # Act c.call("request_sync_from_server") # Assert - assert_signal(c).is_emitted("progression_sync_failed", "HTTP 404 (player unknown)") + await assert_signal(c).is_emitted("progression_sync_failed", "HTTP 404 (player unknown)") diff --git a/client/test/target_selection_client_test.gd b/client/test/target_selection_client_test.gd index 27ad8e3..d4e65d1 100644 --- a/client/test/target_selection_client_test.gd +++ b/client/test/target_selection_client_test.gd @@ -91,7 +91,7 @@ func test_sync_get_200_emits_state() -> void: # Act c.request_sync_from_server() # Assert - assert_signal(c).is_emitted("target_state_changed") + await assert_signal(c).is_emitted("target_state_changed", any()) var state: Dictionary = c.cached_state() assert_that(state.get("validity", "")).is_equal("none") assert_that(state.get("lockedTargetId", "non-null-sentinel")).is_null() @@ -111,7 +111,7 @@ func test_tab_from_no_lock_selects_first_id() -> void: assert_that(transport.last_url).contains("/target/select") assert_that(transport.last_method).is_equal(HTTPClient.METHOD_POST) assert_that(transport.last_body).contains('"targetId":"%s"' % ALPHA_ID) - assert_signal(c).is_emitted("target_state_changed") + await assert_signal(c).is_emitted("target_state_changed", any()) assert_that(c.cached_state().get("lockedTargetId")).is_equal(ALPHA_ID)