test(civics): Update unit tests for civic query bridge with new/modified test cases

Co-Authored-By: Lilith Autocommit <noreply@atlilith.com>
This commit is contained in:
autocommit 2026-06-04 08:53:01 -07:00
parent 5b74c282a0
commit b4e13aaf22

View file

@ -0,0 +1,95 @@
extends GutTest
## p3-05a-gdext-bridge: read-side civic query surface on GdGameState.
##
## Exercises GdGameState::civic(pi, axis) -> Dictionary:
## { "choice": String, "anarchy_turns_remaining": int, "in_anarchy": bool }
##
## A fresh player (add_empty_player_with_axes) carries CivicState::default():
## authority = chieftainship, labor = labor_pool, economy = mercantilism,
## anarchy_turns_remaining = 0.
##
## Headless-safe per Rail 5: no display server required.
## Requires the api-gdext GDExtension to be loaded.
const PLAYER_IDX: int = 0
func _skip_if_extension_absent() -> bool:
if not ClassDB.class_exists("GdGameState"):
pending("api-gdext GDExtension not loaded (GdGameState absent) — skipping civic query")
return true
return false
func _make_state() -> RefCounted:
var state: RefCounted = ClassDB.instantiate("GdGameState") as RefCounted
state.call("add_empty_player_with_axes", {})
return state
func test_default_authority_returns_chieftainship() -> void:
if _skip_if_extension_absent():
return
var state: RefCounted = _make_state()
var d: Dictionary = state.call("civic", PLAYER_IDX, "authority")
assert_eq(d.get("choice", ""), "chieftainship", "default authority civic id")
assert_eq(d.get("anarchy_turns_remaining", -1), 0, "no anarchy on a fresh player")
assert_false(d.get("in_anarchy", true), "fresh player is not in anarchy")
func test_default_labor_and_economy_ids() -> void:
if _skip_if_extension_absent():
return
var state: RefCounted = _make_state()
var labor: Dictionary = state.call("civic", PLAYER_IDX, "labor")
var economy: Dictionary = state.call("civic", PLAYER_IDX, "economy")
assert_eq(labor.get("choice", ""), "labor_pool", "default labor civic id")
assert_eq(economy.get("choice", ""), "mercantilism", "default economy civic id")
func test_axis_label_is_case_insensitive() -> void:
if _skip_if_extension_absent():
return
var state: RefCounted = _make_state()
var d: Dictionary = state.call("civic", PLAYER_IDX, "AUTHORITY")
assert_eq(d.get("choice", ""), "chieftainship", "uppercase axis label resolves")
func test_switch_is_reflected_in_read_side_with_anarchy() -> void:
if _skip_if_extension_absent():
return
var state: RefCounted = _make_state()
var changed: bool = state.call("request_civic_switch", PLAYER_IDX, "authority", "monarchy")
assert_true(changed, "real switch reports changed=true")
var d: Dictionary = state.call("civic", PLAYER_IDX, "authority")
assert_eq(d.get("choice", ""), "monarchy", "read-side reflects the switched civic")
assert_eq(d.get("anarchy_turns_remaining", -1), 5, "switch triggers 5-turn anarchy")
assert_true(d.get("in_anarchy", false), "in_anarchy true while timer > 0")
# Anarchy is empire-wide, so an untouched axis reports the same timer.
var labor: Dictionary = state.call("civic", PLAYER_IDX, "labor")
assert_eq(labor.get("anarchy_turns_remaining", -1), 5, "anarchy is shared across axes")
func test_custom_civic_id_round_trips() -> void:
if _skip_if_extension_absent():
return
var state: RefCounted = _make_state()
state.call("request_civic_switch", PLAYER_IDX, "authority", "warband_council")
var d: Dictionary = state.call("civic", PLAYER_IDX, "authority")
assert_eq(d.get("choice", ""), "warband_council", "custom civic id round-trips verbatim")
func test_unknown_axis_returns_empty_dict() -> void:
if _skip_if_extension_absent():
return
var state: RefCounted = _make_state()
var d: Dictionary = state.call("civic", PLAYER_IDX, "religion")
assert_eq(d.size(), 0, "unknown axis returns an empty Dictionary")
func test_out_of_range_player_returns_empty_dict() -> void:
if _skip_if_extension_absent():
return
var state: RefCounted = _make_state()
var d: Dictionary = state.call("civic", 99, "authority")
assert_eq(d.size(), 0, "out-of-range player index returns an empty Dictionary")