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>
157 lines
5.9 KiB
GDScript
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()
|