From 0ebd417a1f288e58527c0b07680515e8ae62aa9f Mon Sep 17 00:00:00 2001 From: Jeroen Schweitzer Date: Mon, 23 Feb 2026 21:06:35 +0100 Subject: [PATCH] test(client): add direction mapping tests for octant and entity facing (#540 review) 14 tests covering _octant_to_direction (all 8 octants + 2 fallbacks) and _entity_direction (NPC default south, player facing 3 cases). Closes review warning on zero test coverage for direction system. Co-Authored-By: Claude Opus 4.6 --- client/tests/test_sprite_integration.gd | 97 +++++++++++++++++++++++++ 1 file changed, 97 insertions(+) diff --git a/client/tests/test_sprite_integration.gd b/client/tests/test_sprite_integration.gd index e9405c91a..1a9e76e30 100644 --- a/client/tests/test_sprite_integration.gd +++ b/client/tests/test_sprite_integration.gd @@ -193,3 +193,100 @@ func test_fog_update_runs_independently_of_entity_renderer_state() -> void: ).is_not_null() GameState.visible_positions.clear() GameState.visibility_sectors.clear() + + +# -- Direction mapping: _octant_to_direction (S16-S12 through S16-S21) -------- + +func test_octant_north_maps_to_north() -> void: + # S16-S12: "North" → "north" + assert_that(EntityRenderer._octant_to_direction("North")).is_equal("north") + +func test_octant_northwest_maps_to_north() -> void: + # S16-S13: "Northwest" → "north" (grouped with North per mapping spec) + assert_that(EntityRenderer._octant_to_direction("Northwest")).is_equal("north") + +func test_octant_northeast_maps_to_east() -> void: + # S16-S14: "Northeast" → "east" + assert_that(EntityRenderer._octant_to_direction("Northeast")).is_equal("east") + +func test_octant_east_maps_to_east() -> void: + # S16-S15: "East" → "east" + assert_that(EntityRenderer._octant_to_direction("East")).is_equal("east") + +func test_octant_southeast_maps_to_south() -> void: + # S16-S16: "Southeast" → "south" + assert_that(EntityRenderer._octant_to_direction("Southeast")).is_equal("south") + +func test_octant_south_maps_to_south() -> void: + # S16-S17: "South" → "south" + assert_that(EntityRenderer._octant_to_direction("South")).is_equal("south") + +func test_octant_southwest_maps_to_west() -> void: + # S16-S18: "Southwest" → "west" + assert_that(EntityRenderer._octant_to_direction("Southwest")).is_equal("west") + +func test_octant_west_maps_to_west() -> void: + # S16-S19: "West" → "west" + assert_that(EntityRenderer._octant_to_direction("West")).is_equal("west") + +func test_octant_unknown_string_falls_back_to_south() -> void: + # S16-S20: Unknown string → "south" fallback (safe default — viewer-facing per D-019) + assert_that(EntityRenderer._octant_to_direction("Unknown")).is_equal("south") + assert_that(EntityRenderer._octant_to_direction("invalid")).is_equal("south") + +func test_octant_empty_string_falls_back_to_south() -> void: + # S16-S21: Empty string → "south" fallback + assert_that(EntityRenderer._octant_to_direction("")).is_equal("south") + + +# -- Direction mapping: _entity_direction (S16-S22 through S16-S25) ---------- + +func test_entity_direction_npc_always_south() -> void: + # S16-S22: NPC entity → always "south" regardless of any data field. + # NPCs have no facing in v1 entity format; south is viewer-facing (D-019 angle). + var renderer := _make_entity_renderer() + GameState.player_entity_id = 1 + # entity_id 99 is not the player + var dir := renderer._entity_direction(99, {"entity_id": 99, + "kind": {"variant": "Npc", "data": null}}) + assert_that(dir).override_failure_message( + "NPC entity must always return 'south'" + ).is_equal("south") + renderer.queue_free() + +func test_entity_direction_player_uses_player_facing() -> void: + # S16-S23: Player entity → uses GameState.player_facing via _octant_to_direction. + var renderer := _make_entity_renderer() + GameState.player_entity_id = 1 + GameState.player_facing = "North" + var dir := renderer._entity_direction(1, {"entity_id": 1, + "kind": {"variant": "Player", "data": null}}) + assert_that(dir).override_failure_message( + "Player entity with player_facing='North' must return 'north'" + ).is_equal("north") + renderer.queue_free() + +func test_entity_direction_player_facing_east() -> void: + # S16-S24: Player facing "East" → "east" + var renderer := _make_entity_renderer() + GameState.player_entity_id = 1 + GameState.player_facing = "East" + var dir := renderer._entity_direction(1, {"entity_id": 1, + "kind": {"variant": "Player", "data": null}}) + assert_that(dir).override_failure_message( + "Player entity with player_facing='East' must return 'east'" + ).is_equal("east") + renderer.queue_free() + +func test_entity_direction_player_facing_diagonal_uses_nearest_cardinal() -> void: + # S16-S25: Player facing "Northwest" → "north" (nearest cardinal mapping). + # Diagonal octants map to one of the four cardinal sprite sets. + var renderer := _make_entity_renderer() + GameState.player_entity_id = 1 + GameState.player_facing = "Northwest" + var dir := renderer._entity_direction(1, {"entity_id": 1, + "kind": {"variant": "Player", "data": null}}) + assert_that(dir).override_failure_message( + "Player entity with player_facing='Northwest' must return 'north'" + ).is_equal("north") + renderer.queue_free()