109 lines
6.1 KiB
GDScript
109 lines
6.1 KiB
GDScript
extends SceneTree
|
|
|
|
const Adapter = preload("res://campaign/fg3_adapter.gd")
|
|
const Contract1Battle = preload("res://fg3/contract1_battle_service.gd")
|
|
const Contract2Battle = preload("res://fg3/contract2_battle_service.gd")
|
|
const Fixture = preload("res://tests/fg3/contract1_fixture.gd")
|
|
|
|
var failures: Array[String] = []
|
|
|
|
|
|
func _initialize() -> void:
|
|
call_deferred("run_test")
|
|
|
|
|
|
func run_test() -> void:
|
|
verify_complete_region_flow()
|
|
verify_recovery_flow()
|
|
if failures.is_empty():
|
|
print("ABG_FG3_CAMPAIGN_ADAPTER_OK market8_to_rg03=true rounds=17 bosses=2 records=2 modes=market,plan,battle,recovery,record,handoff,closed events=source_bound save_authority=unchanged")
|
|
quit(0)
|
|
else:
|
|
for failure in failures:
|
|
push_error(failure)
|
|
quit(1)
|
|
|
|
|
|
func verify_complete_region_flow() -> void:
|
|
var source := Fixture.new().fg3_market_8_snapshot()
|
|
var source_hash := Adapter.hash_value(source)
|
|
var adapter := Adapter.new()
|
|
var configured := adapter.configure(source)
|
|
expect(configured.ok and configured.view.mode == "market" and configured.view.market_index == 8, "real saved Market 8 configures")
|
|
expect(Adapter.hash_value(source) == source_hash, "adapter never mutates caller snapshot")
|
|
if not configured.ok:
|
|
return
|
|
for market_index in [8, 9, 10, 11, 12]:
|
|
var route: Dictionary = adapter.view_state().routes[0]
|
|
var prepared := adapter.prepare_route(String(route.offer_id))
|
|
expect(prepared.ok and prepared.view.mode == "plan", "Contract 1 Market %d opens response plans" % market_index)
|
|
var plan_id := String(Contract1Battle.PREFERRED_PLAN[String(route.route_id)])
|
|
var started := adapter.start_plan(plan_id)
|
|
expect(started.ok, "Contract 1 Market %d starts authoritative battle" % market_index)
|
|
var terminal := adapter.run_battle_to_terminal()
|
|
expect(terminal.ok and terminal.view.battle.terminal and terminal.view.battle.outcome == "victory", "Contract 1 Market %d reaches visible victory" % market_index)
|
|
expect(has_kind(terminal.events, "wave_arrived") and has_kind(terminal.events, "damage") and has_kind(terminal.events, "outcome"), "Contract 1 Market %d forwards event-bound presentation" % market_index)
|
|
var settled := adapter.settle_terminal()
|
|
expect(settled.ok, "Contract 1 Market %d settles" % market_index)
|
|
expect(adapter.view_state().mode == "boss_muster" and adapter.view_state().plans.size() == 2, "Sluiceback Muster exposes two plans")
|
|
expect(adapter.start_plan("follow_index_clear_eggs").ok, "first Boss plan starts")
|
|
expect(adapter.run_battle_to_terminal().view.battle.outcome == "victory", "Sluiceback reaches visible victory")
|
|
expect(adapter.settle_terminal().view.mode == "contract_record", "first Boss opens first Record")
|
|
expect(adapter.continue_result().view.mode == "contract_handoff", "first Record closes into explicit handoff")
|
|
expect(adapter.continue_result().view.mode == "market", "handoff opens Contract-2 Market 1")
|
|
for market_index in range(1, 13):
|
|
var route: Dictionary = adapter.view_state().routes[0]
|
|
expect(adapter.prepare_route(String(route.offer_id)).ok, "Contract 2 Market %d prepares" % market_index)
|
|
var plan_id := String(Contract2Battle.PRIMARY_PLAN[market_index])
|
|
expect(adapter.start_plan(plan_id).ok, "Contract 2 Market %d starts" % market_index)
|
|
var terminal := adapter.run_battle_to_terminal()
|
|
expect(terminal.view.battle.outcome == "victory", "Contract 2 Market %d reaches visible victory" % market_index)
|
|
expect(adapter.settle_terminal().ok, "Contract 2 Market %d settles" % market_index)
|
|
expect(adapter.view_state().mode == "boss_muster" and adapter.view_state().boss_id == "BO-R2-02", "Drowned Bell Muster is distinct")
|
|
expect(adapter.start_plan("interrupt_pulse_family").ok, "Drowned Bell interrupt plan starts")
|
|
var bell_terminal := adapter.run_battle_to_terminal()
|
|
expect(bell_terminal.view.battle.outcome == "victory", "Drowned Bell reaches visible victory")
|
|
expect(has_kind(bell_terminal.events, "linked_positions_disclosed") and has_kind(bell_terminal.events, "third_pulse_link"), "Drowned Bell forwards pair and triple disclosures")
|
|
expect(adapter.settle_terminal().view.mode == "region_record", "Drowned Bell opens second Record")
|
|
var closed := adapter.continue_result()
|
|
expect(closed.ok and closed.view.mode == "region_closed", "Region result closes visibly")
|
|
expect(closed.view.records_count == 2 and closed.view.unlocked_region_ids.count("RG-03") == 1, "two Records and RG-03 persist exactly once")
|
|
|
|
|
|
func verify_recovery_flow() -> void:
|
|
var snapshot := Fixture.new().fg3_market_8_snapshot()
|
|
var company: Array = Array(snapshot.current_run.company).duplicate()
|
|
var deployed_count := mini(4, company.size())
|
|
snapshot.current_run.deployed_recruit_ids = company.slice(0, deployed_count)
|
|
snapshot.current_run.reserve_recruit_ids = company.slice(deployed_count)
|
|
snapshot.current_run.formation_proposal = company.slice(0, deployed_count)
|
|
var adapter := Adapter.new()
|
|
expect(adapter.configure(snapshot).ok, "bounded recovery snapshot configures")
|
|
var route: Dictionary = adapter.view_state().routes[2]
|
|
expect(adapter.prepare_route(String(route.offer_id)).ok, "risk-two recovery route prepares")
|
|
var preferred := String(Contract1Battle.PREFERRED_PLAN[String(route.route_id)])
|
|
var wrong_plan := "hold_line"
|
|
if wrong_plan == preferred:
|
|
wrong_plan = "guard_center"
|
|
expect(adapter.start_plan(wrong_plan).ok, "nonpreferred response starts")
|
|
var terminal := adapter.run_battle_to_terminal()
|
|
expect(terminal.view.battle.outcome == "defeat" and terminal.view.battle.fallen_recruit_ids.size() == 1, "visible defeat names one Fallen Recruit")
|
|
var settled := adapter.settle_terminal()
|
|
expect(settled.ok and settled.view.mode == "recovery", "defeat opens recovery presentation")
|
|
var survivors: int = settled.view.company.size()
|
|
var recovered := adapter.recover()
|
|
expect(recovered.ok and recovered.view.mode == "market", "recovery returns to the same Market")
|
|
expect(recovered.view.company.size() == survivors, "recovery never resurrects or auto-substitutes")
|
|
|
|
|
|
func has_kind(events: Array, kind: String) -> bool:
|
|
for event in events:
|
|
if String(event.get("kind", "")) == kind:
|
|
return true
|
|
return false
|
|
|
|
|
|
func expect(condition: bool, message: String) -> void:
|
|
if not condition:
|
|
failures.append("FG-3 campaign adapter: %s" % message)
|