Files
settled-reach/client/tests/test_game_state.gd
T
jpmschweitzerandClaude Opus 4.6 a7541aa27b test(client): scene testing utilities and GameState tests (#206)
SceneHelper class for gdUnit4: load scenes into test tree with
assert_node_exists, assert_signal_emitted, get_node_at helpers.
14 tests for GameState.apply_snapshot() covering v2+ fields.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 11:45:39 +01:00

157 lines
5.9 KiB
GDScript

## GameState.apply_snapshot() tests — v2+ field coverage.
##
## Complements test_snapshot_parsing.gd (which covers v1 basics: tick, entities,
## player_position). This file covers v2+ fields and derived state.
##
## D-030: fixture-based, server-free, no subprocess required.
class_name TestGameState
extends GdUnitTestSuite
func before_each() -> void:
# Reset fields touched by these tests to known defaults.
GameState.current_tick = 0
GameState.player_position = Vector2.ZERO
GameState.player_facing = "North"
GameState.game_time = {}
GameState.nearby_interactions = []
GameState.current_monologue = null
GameState.player_stance = "Walk"
GameState.player_inventory = []
GameState.stationary_ticks = 0
GameState.insert_active = true
# -- v2: game_time (D-031) -------------------------------------------------
func test_apply_snapshot_sets_game_time() -> void:
var snapshot := {
"tick": 10,
"entities": [],
"game_time": {"day": 3, "time_of_day": 480, "day_phase": "Morning", "tick_rate": 1},
}
GameState.apply_snapshot(snapshot)
assert_that(GameState.game_time).is_not_null()
assert_that(GameState.game_time.get("day")).is_equal(3)
assert_that(GameState.game_time.get("time_of_day")).is_equal(480)
func test_apply_snapshot_game_time_missing_keeps_previous() -> void:
GameState.game_time = {"day": 2, "time_of_day": 360}
GameState.apply_snapshot({"tick": 5, "entities": []})
# No "game_time" key → field unchanged
assert_that(GameState.game_time.get("day")).is_equal(2)
# -- v2: player_facing (D-015) --------------------------------------------
func test_apply_snapshot_sets_player_facing() -> void:
var snapshot := {
"tick": 1,
"entities": [],
"player_facing": "Southeast",
}
GameState.apply_snapshot(snapshot)
assert_that(GameState.player_facing).is_equal("Southeast")
func test_apply_snapshot_player_facing_missing_keeps_default() -> void:
GameState.player_facing = "West"
GameState.apply_snapshot({"tick": 1, "entities": []})
assert_that(GameState.player_facing).is_equal("West")
# -- v4: nearby_interactions (#404/#405) ----------------------------------
func test_apply_snapshot_sets_nearby_interactions() -> void:
var interactions := [
{"entity_id": 5, "entity_type": "Npc", "distance": 1.2, "verbs": [{"kind": "Talk", "label": "Talk", "priority": 1, "available": true}]},
]
GameState.apply_snapshot({"tick": 1, "entities": [], "nearby_interactions": interactions})
assert_that(GameState.nearby_interactions.size()).is_equal(1)
assert_that(GameState.nearby_interactions[0].get("entity_id")).is_equal(5)
func test_apply_snapshot_nearby_interactions_absent_clears_list() -> void:
GameState.nearby_interactions = [{"entity_id": 1}]
GameState.apply_snapshot({"tick": 2, "entities": []})
assert_that(GameState.nearby_interactions.size()).is_equal(0)
# -- v5: current_monologue (#414) -----------------------------------------
func test_apply_snapshot_sets_monologue() -> void:
var monologue := {"id": "m1", "text": "Something is off here.", "duration_seconds": 4.0, "priority": 1, "is_urgent": false}
GameState.apply_snapshot({"tick": 1, "entities": [], "current_monologue": monologue})
assert_that(GameState.current_monologue).is_not_null()
assert_that(GameState.current_monologue.get("text")).is_equal("Something is off here.")
func test_apply_snapshot_monologue_absent_clears_field() -> void:
GameState.current_monologue = {"id": "old", "text": "Old line."}
GameState.apply_snapshot({"tick": 2, "entities": []})
assert_that(GameState.current_monologue).is_null()
# -- v6: player_stance (#449, D-053) --------------------------------------
func test_apply_snapshot_sets_player_stance() -> void:
GameState.apply_snapshot({"tick": 1, "entities": [], "player_stance": "Crouch"})
assert_that(GameState.player_stance).is_equal("Crouch")
# -- v6: player_inventory (#449, D-065) -----------------------------------
func test_apply_snapshot_sets_player_inventory() -> void:
var inventory := [{"item_id": 42, "name": "Security pass", "slot": 0}]
GameState.apply_snapshot({"tick": 1, "entities": [], "player_inventory": inventory})
assert_that(GameState.player_inventory.size()).is_equal(1)
assert_that(GameState.player_inventory[0].get("name")).is_equal("Security pass")
func test_apply_snapshot_inventory_absent_clears_list() -> void:
GameState.player_inventory = [{"item_id": 1}]
GameState.apply_snapshot({"tick": 2, "entities": []})
assert_that(GameState.player_inventory.size()).is_equal(0)
# -- Stationary tick counter (D-071) -------------------------------------
func test_stationary_ticks_increments_when_player_position_unchanged() -> void:
var snapshot := {
"tick": 1,
"entities": [{"entity_id": 1, "x": 10.0, "y": 10.0, "z": 0, "kind": {"variant": "Player", "data": null}}],
}
GameState.apply_snapshot(snapshot) # first call: position changes from ZERO
GameState.apply_snapshot(snapshot) # second call: position unchanged → +1
assert_int(GameState.stationary_ticks).is_greater(0)
func test_stationary_ticks_resets_on_player_movement() -> void:
var s1 := {
"tick": 1,
"entities": [{"entity_id": 1, "x": 10.0, "y": 10.0, "z": 0, "kind": {"variant": "Player", "data": null}}],
}
var s2 := {
"tick": 2,
"entities": [{"entity_id": 1, "x": 11.0, "y": 10.0, "z": 0, "kind": {"variant": "Player", "data": null}}],
}
GameState.apply_snapshot(s1)
GameState.apply_snapshot(s1) # stationary
assert_int(GameState.stationary_ticks).is_greater(0)
GameState.apply_snapshot(s2) # moved → reset
assert_int(GameState.stationary_ticks).is_equal(0)
# -- insert_active (OQ-07, #522) -----------------------------------------
func test_apply_snapshot_insert_active_false() -> void:
GameState.apply_snapshot({"tick": 1, "entities": [], "insert_active": false})
assert_bool(GameState.insert_active).is_false()
func test_apply_snapshot_insert_active_defaults_true_when_absent() -> void:
GameState.insert_active = false
GameState.apply_snapshot({"tick": 2, "entities": []})
assert_bool(GameState.insert_active).is_true()