✅ test(@projects/@magic-civilization): 🧪 add culture web unit tests
Co-Authored-By: Lilith Autocommit <noreply@atlilith.com>
This commit is contained in:
parent
921bc73e55
commit
85fef2b753
1 changed files with 112 additions and 0 deletions
112
src/game/engine/tests/unit/test_culture_web.gd
Normal file
112
src/game/engine/tests/unit/test_culture_web.gd
Normal file
|
|
@ -0,0 +1,112 @@
|
|||
extends GutTest
|
||||
## Verifies the `CultureWeb` GDScript wrapper drives `GdCultureWeb` correctly:
|
||||
## load → graph queries → per-player gating → research-completion signal.
|
||||
|
||||
const CultureWebScript: GDScript = preload(
|
||||
"res://engine/src/modules/empire/culture_web.gd"
|
||||
)
|
||||
const PlayerScript: GDScript = preload("res://engine/src/entities/player.gd")
|
||||
|
||||
const SAMPLE_TRADITIONS: Array = [
|
||||
{
|
||||
"id": "ancestor_song",
|
||||
"name": "Ancestor Song",
|
||||
"pillar": "ancestor_worship",
|
||||
"era": 1, "tier": 1, "cost": 10,
|
||||
"requires": [],
|
||||
"unlocks": {"buildings": ["shrine"], "units": [], "improvements": []},
|
||||
"flavor": "We sing them so they remember us.",
|
||||
},
|
||||
{
|
||||
"id": "rite_of_remembering",
|
||||
"name": "Rite of Remembering",
|
||||
"pillar": "ancestor_worship",
|
||||
"era": 2, "tier": 2, "cost": 25,
|
||||
"requires": ["ancestor_song"],
|
||||
"unlocks": {
|
||||
"buildings": [], "units": [], "improvements": [],
|
||||
"mechanics": [
|
||||
{"key": "happiness_per_shrine", "label": "Happiness Per Shrine +1", "value": 1}
|
||||
]
|
||||
},
|
||||
"flavor": "The dead are louder when we listen.",
|
||||
},
|
||||
]
|
||||
|
||||
|
||||
func before_each() -> void:
|
||||
# Each test rebuilds CultureWeb from the in-test fixture; bypass DataLoader
|
||||
# by stubbing the bridge directly through the wrapper's lazy build path.
|
||||
pass
|
||||
|
||||
|
||||
func _make_web() -> CultureWebScript:
|
||||
var web: CultureWebScript = CultureWebScript.new()
|
||||
# The wrapper normally calls DataLoader.get_all_culture(); for the test we
|
||||
# instantiate the bridge ourselves and load the fixture JSON.
|
||||
if not ClassDB.class_exists("GdCultureWeb"):
|
||||
fail_test("GdCultureWeb GDExtension class not registered")
|
||||
return null
|
||||
var bridge: RefCounted = ClassDB.instantiate("GdCultureWeb") as RefCounted
|
||||
var ok: bool = bool(bridge.call("load_from_json", JSON.stringify(SAMPLE_TRADITIONS)))
|
||||
assert_true(ok, "GdCultureWeb.load_from_json should succeed")
|
||||
# Inject the bridge into the wrapper's KnowledgeWeb for direct testing.
|
||||
# The wrapper exposes `_web` which is a KnowledgeWeb; we set its `_bridge`
|
||||
# field via duck-typed `set` so the rest of the API works as in production.
|
||||
var inner: RefCounted = web._web as RefCounted
|
||||
inner.set("_bridge", bridge)
|
||||
inner.set("_node_count", SAMPLE_TRADITIONS.size())
|
||||
return web
|
||||
|
||||
|
||||
func test_tradition_count_and_pillars() -> void:
|
||||
var web: CultureWebScript = _make_web()
|
||||
assert_eq(web.get_tradition_count(), 2)
|
||||
var pillars: Array[String] = web.get_pillars()
|
||||
assert_eq(pillars.size(), 1)
|
||||
assert_eq(pillars[0], "ancestor_worship")
|
||||
|
||||
|
||||
func test_prerequisite_gating() -> void:
|
||||
var web: CultureWebScript = _make_web()
|
||||
# Set up a player with no culture researched yet.
|
||||
GameState.players = [PlayerScript.new(0, "Tester", "dwarf")]
|
||||
GameState.current_player_index = 0
|
||||
|
||||
assert_true(web.can_research("ancestor_song", 0))
|
||||
assert_false(web.can_research("rite_of_remembering", 0),
|
||||
"rite_of_remembering needs ancestor_song first")
|
||||
|
||||
# Grant the prereq and re-check.
|
||||
(GameState.players[0] as PlayerScript).add_tradition("ancestor_song")
|
||||
assert_false(web.can_research("ancestor_song", 0),
|
||||
"already-researched tradition should not be researchable again")
|
||||
assert_true(web.can_research("rite_of_remembering", 0))
|
||||
|
||||
|
||||
func test_start_research_emits_signal() -> void:
|
||||
var web: CultureWebScript = _make_web()
|
||||
GameState.players = [PlayerScript.new(0, "Tester", "dwarf")]
|
||||
GameState.current_player_index = 0
|
||||
|
||||
watch_signals(EventBus)
|
||||
var ok: bool = web.start_research("ancestor_song", 0)
|
||||
assert_true(ok)
|
||||
assert_signal_emitted_with_parameters(
|
||||
EventBus, "culture_research_started", ["ancestor_song", 0]
|
||||
)
|
||||
var p: PlayerScript = GameState.players[0] as PlayerScript
|
||||
assert_eq(p.researching_tradition, "ancestor_song")
|
||||
assert_eq(p.culture_research_progress, 0)
|
||||
|
||||
|
||||
func test_unlocks_typed_buckets_round_trip() -> void:
|
||||
var web: CultureWebScript = _make_web()
|
||||
var data: Dictionary = web.get_tradition_data("rite_of_remembering")
|
||||
assert_false(data.is_empty(), "tradition data should round-trip")
|
||||
var unlocks: Dictionary = data.get("unlocks", {})
|
||||
var mechanics: Array = unlocks.get("mechanics", []) as Array
|
||||
assert_eq(mechanics.size(), 1)
|
||||
var m: Dictionary = mechanics[0] as Dictionary
|
||||
assert_eq(String(m.get("key", "")), "happiness_per_shrine")
|
||||
assert_eq(int(m.get("value", 0)), 1)
|
||||
Loading…
Add table
Reference in a new issue