Files
aetherbound-guild/runtime/tests/fg4/contract2_activation_test.gd
T

108 lines
4.3 KiB
GDScript

extends SceneTree
const Activation = preload("res://fg4/contract2_activation_service.gd")
const Fixture = preload("res://tests/fg4/contract1_fixture.gd")
const State = preload("res://fg4/run_state.gd")
var failures: Array[String] = []
var rejected_cases := 0
func _initialize() -> void:
call_deferred("run_test")
func run_test() -> void:
verify_exact_activation_and_preservation()
verify_activation_boundaries()
if failures.is_empty():
print("ABG_FG4_CONTRACT2_ACTIVATION_OK source=CLEAR-RG03-C01 contract=CTR-R3-02 phase=contract2_market market=1 board=3,4,3 prior_routes=36 company,growth,hp,equipment,economy,artifact,receipts=exact duplicate=true rejected_cases=%d" % rejected_cases)
quit(0)
else:
for failure in failures:
push_error(failure)
quit(1)
func verify_exact_activation_and_preservation() -> void:
var before := Fixture.new().contract2_handoff_snapshot()
expect(not before.is_empty(), "Contract-1 close fixture exists")
var service := Activation.new(before)
expect(service.valid and service.state.current_run.phase == "contract2_handoff", "handoff restores")
if not service.valid:
return
var handoff_hash := String(service.state.current_run.market_board.handoff_hash)
var revision_before := service.state.revision
var preserved_before := preserved_projection(service.state.snapshot())
var activated := service.activate_contract(
"fg4-contract2-activate",
revision_before,
handoff_hash
)
expect(activated.ok and not activated.duplicate, "Contract 2 activates exactly once")
if not activated.ok:
return
var run: Dictionary = service.state.current_run
expect(run.contract_id == "CTR-R3-02" and run.phase == "contract2_market", "Contract 2 identity and phase are exact")
expect(run.market_index == 1 and run.round_index == 1 and run.cleared_rounds == 36, "Market and lineage are exact")
expect(run.market_board.recruit_slots.size() == 3 and run.market_board.equipment_offers.size() == 4 and run.market_board.battle_offers.size() == 3, "Market 1 has exact 3/4/3 board")
expect(run.market_board.spark_disclosure.repeat_threshold == 3, "repeat threshold is disclosed before commitment")
expect(preserved_projection(service.state.snapshot()) == preserved_before, "activation preserves Company and carried consequences byte-equivalent")
var duplicate := service.activate_contract(
"fg4-contract2-activate",
revision_before,
handoff_hash
)
expect(duplicate.ok and duplicate.duplicate and duplicate.revision == activated.revision, "duplicate activation is inert")
var roundtrip := State.new()
expect(roundtrip.restore_snapshot(service.state.snapshot()) and roundtrip.snapshot() == service.state.snapshot(), "activated state roundtrips exactly")
func verify_activation_boundaries() -> void:
var before := Fixture.new().contract2_handoff_snapshot()
if before.is_empty():
return
var service := Activation.new(before)
var original := service.state.snapshot()
expect_rejected(
service.activate_contract("fg4-contract2-bad-hash", service.state.revision, "0".repeat(64)),
"handoff hash tamper",
"handoff_hash_mismatch"
)
expect(service.state.snapshot() == original, "rejected activation does not mutate state")
var invalid := before.duplicate(true)
invalid.current_run.market_board.handoff_hash = "0".repeat(64)
expect(not State.new().restore_snapshot(invalid), "tampered handoff state rejects before activation")
rejected_cases += 1
func preserved_projection(snapshot_value: Dictionary) -> Dictionary:
var run: Dictionary = snapshot_value.current_run
return {
"run_id": run.run_id,
"run_seed": run.run_seed,
"company": run.company,
"deployed": run.deployed_recruit_ids,
"reserve": run.reserve_recruit_ids,
"recruit_records": run.recruit_records,
"inventory": run.inventory,
"equipped": run.equipped_by_recruit,
"coin": run.coin,
"credit": run.replacement_credit,
"artifacts": run.active_artifact_ids,
"history": run.route_history,
"guild_profile": snapshot_value.guild_profile,
}
func expect_rejected(result: Dictionary, label: String, code: String) -> void:
var rejected := not bool(result.get("ok", false)) and String(result.get("code", "")) == code
expect(rejected, "%s rejects with %s" % [label, code])
if rejected:
rejected_cases += 1
func expect(condition: bool, message: String) -> void:
if not condition:
failures.append("FG-4 Contract-2 activation: %s" % message)