From 268c9303cdfe5832bdc25d6aadb1cee6b397b83b Mon Sep 17 00:00:00 2001 From: autocommit Date: Thu, 16 Apr 2026 11:29:47 -0700 Subject: [PATCH] =?UTF-8?q?test(game-engine):=20=E2=9C=85=20Add=20unit=20t?= =?UTF-8?q?ests=20for=20city=20bridge=20functionality?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Lilith Autocommit --- .../engine/tests/unit/test_city_bridge.gd | 45 +++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/src/game/engine/tests/unit/test_city_bridge.gd b/src/game/engine/tests/unit/test_city_bridge.gd index 5cc18c0a..192e32ac 100644 --- a/src/game/engine/tests/unit/test_city_bridge.gd +++ b/src/game/engine/tests/unit/test_city_bridge.gd @@ -111,3 +111,48 @@ func test_happy_path_enqueue_tick_emits_item_crafted() -> void: assert_eq(treasury.call("total_count"), 1) assert_true(treasury.call("contains", "iron_axe")) + + +func test_enqueue_rejects_when_strategic_resource_missing() -> void: + ## Task #4: Rust-side enforcement of requires_resource. A resource-gated + ## item must be rejected when the player does NOT control the resource, + ## and accepted when they do. Mirrors mc-city test + ## `production_rejects_resource_gated_without_resource`. + if not ClassDB.class_exists("GdCity"): + pass_test("GdCity extension not loaded in this test run") + return + if not ClassDB.class_exists("GdStockpile"): + pass_test("GdStockpile extension not loaded in this test run") + return + + var city: RefCounted = CityScript.new("khazad", ["smithy"] as Array[String]) + var items_json: String = JSON.stringify([ + { + "id": "cavalry_axe", + "production": { + "building": "smithy", + "production_cost": 30, + "materials": [{"resource": "iron_ore", "amount": 2}], + "requires_tech": "bronze_working", + "requires_resource": "horses", + }, + }, + ]) + assert_true(city.load_items_json(items_json)) + + var stockpile: RefCounted = ClassDB.instantiate("GdStockpile") as RefCounted + stockpile.call("add", "iron_ore", 4) + var techs: Array[String] = ["bronze_working"] + + var err_no: String = city.enqueue_item("cavalry_axe", stockpile, techs, [] as Array[String]) + assert_ne(err_no, "", "enqueue must reject when strategic resource missing") + assert_true("horses" in err_no, "error should name the missing resource") + assert_eq(stockpile.call("available", "iron_ore"), 4, "no materials consumed on rejection") + assert_eq(city.queue_len("smithy"), 0) + + var err_ok: String = city.enqueue_item( + "cavalry_axe", stockpile, techs, ["horses"] as Array[String] + ) + assert_eq(err_ok, "", "enqueue should succeed once resource is controlled") + assert_eq(stockpile.call("available", "iron_ore"), 2, "materials consumed on success") + assert_eq(city.queue_len("smithy"), 1)