extends SceneTree const Controller = preload("res://entry/contract_choice_page_controller.gd") var failures: Array[String] = [] func _initialize() -> void: call_deferred("run_test") func run_test() -> void: var controller := Controller.new() var company := _fixture_company() var view: Dictionary = controller.snapshot(company, "stormbound", "en") expect(view.ok and view.page_id == "contract_choice", "snapshot identifies Contract Choice") expect(view.selected_difficulty == "stormbound", "snapshot preserves the selected legal difficulty") expect(view.company.owned_count == 2 and view.company.recruits.size() == 2, "snapshot copies the opening Company facts") expect(view.contract.contract_id == "CTR-R1-01" and view.contract.route_id == "windglass_verge", "snapshot exposes the First Windglass Crossing descriptor") expect(view.contract.starting_coin == 52 and view.contract.line_capacity == 4, "snapshot exposes authoritative starting resources") expect(view.contract.market_counts.recruit == 3 and view.contract.market_counts.equipment == 4 and view.contract.market_counts.battle == 3, "snapshot exposes the protected 3/4/3 creation shape") expect(view.difficulties.size() == 4 and view.difficulties[1].id == "standard" and view.difficulties[2].selected, "snapshot exposes all four difficulty options and selection") expect(view.difficulties[2].name == "Stormbound" and not view.difficulties[2].copy.is_empty(), "snapshot localizes difficulty facts") expect(view.confirm.eligible and view.confirm.reason == "ready", "valid Company exposes the Confirm boundary") var fallback: Dictionary = controller.snapshot(company, "unknown", "zh_CN") expect(fallback.ok and fallback.selected_difficulty == "standard" and fallback.difficulties[1].selected, "unknown difficulty falls back to Standard") var missing: Dictionary = controller.snapshot({}, "standard", "zh_CN") expect(not missing.ok and missing.code == "COMPANY_REQUIRED", "missing Company is rejected") var active := company.duplicate(true) active.active_contract = {"status": "market"} var active_view: Dictionary = controller.snapshot(active, "standard", "zh_CN") expect(not active_view.ok and active_view.code == "CONTRACT_ALREADY_ACTIVE", "active Contract cannot reopen Contract Choice") var blocked: Dictionary = controller.confirm_state(active, "standard") expect(not blocked.eligible and blocked.reason == "contract_already_active", "Confirm guard blocks an active Contract") var invalid: Dictionary = controller.confirm_state(company, "unknown") expect(not invalid.eligible and invalid.reason == "invalid_difficulty", "Confirm guard rejects an invalid difficulty") var copied: Array = view.company.recruits copied[0].recruit_id = "changed" expect(company.owned_recruits[0].recruit_id == "owned-001", "view data is isolated from Company input") if failures.is_empty(): print("ABG_M19_CONTRACT_CHOICE_CONTROLLER_OK company=2 route=windglass_verge difficulties=4 selected=fallback localized=true creation=coin52,line4,market3_4_3 confirm=ready,blocked copies=true") quit(0) else: for failure in failures: push_error(failure) quit(1) func _fixture_company() -> Dictionary: return { "company_id": "company-001", "owned_recruits": [ {"recruit_id": "owned-001", "profession_id": "PF-B01"}, {"recruit_id": "owned-002", "profession_id": "PF-B02"}, ], "active_contract": {}, } func expect(condition: bool, message: String) -> void: if not condition: failures.append("M19 Contract Choice Controller: %s" % message)