84 lines
3.3 KiB
GDScript
84 lines
3.3 KiB
GDScript
extends SceneTree
|
|
|
|
const MainScene = preload("res://main.tscn")
|
|
const RunState = preload("res://domain/run_state.gd")
|
|
|
|
var failures: Array[String] = []
|
|
|
|
|
|
func _initialize() -> void:
|
|
call_deferred("run_test")
|
|
|
|
|
|
func run_test() -> void:
|
|
var game := MainScene.instantiate()
|
|
game.auto_boot = false
|
|
root.add_child(game)
|
|
await settle()
|
|
var initial_snapshot: Dictionary = game.run.snapshot()
|
|
expect(game.page == game.AppPage.BOOT, "fresh instance starts at Boot")
|
|
expect(find_control(game, "BootScreen") != null, "Boot screen is visible")
|
|
expect(find_control(game, "StartNewGame") == null, "run action hidden before verification")
|
|
|
|
game.boot_paths_override.assign(["res://missing/p9_0_required_resource.tres"])
|
|
await game.run_boot_verification()
|
|
expect(game.page == game.AppPage.BOOT, "failed verification retains Boot")
|
|
expect(game.boot_failed_path == "res://missing/p9_0_required_resource.tres", "failed path retained")
|
|
expect(find_control(game, "BootRetry") != null, "failed verification offers Retry")
|
|
expect(game.run.snapshot() == initial_snapshot, "failed verification does not mutate run")
|
|
|
|
game.boot_paths_override.clear()
|
|
await game.run_boot_verification()
|
|
expect(game.boot_verified, "required local content verified")
|
|
expect(game.theme != null and game.theme.default_font != null, "runtime uses an embedded UI font")
|
|
expect(game.boot_success_presented, "successful Boot presented a verified terminal before Title")
|
|
expect(game.page == game.AppPage.TITLE, "verified Boot reaches Title")
|
|
expect(find_control(game, "TitleScreen") != null, "Title screen is visible")
|
|
expect(find_control(game, "NoRunStatus") != null, "Title states no expedition")
|
|
expect(find_control(game, "StartNewGame") != null, "Title exposes Start New Game")
|
|
expect(game.get_viewport().gui_get_focus_owner() == find_control(game, "StartNewGame"), "Title focuses Start New Game for keyboard and controller")
|
|
expect(game.run.snapshot() == initial_snapshot, "Boot and Title do not mutate run")
|
|
|
|
game.start_new_game()
|
|
expect(game.page == game.AppPage.RUN, "Start New Game opens run setup")
|
|
var snapshot: Dictionary = game.run.snapshot()
|
|
expect(snapshot.step == RunState.Step.CONTRACT, "handoff opens Contract state")
|
|
expect(snapshot.coin == 52 and snapshot.company.is_empty(), "handoff preserves fresh resources")
|
|
expect(snapshot.contract.is_empty() and snapshot.difficulty.is_empty(), "handoff makes no setup choice")
|
|
expect(snapshot.operation_counts.opening == 0, "handoff creates no expedition")
|
|
|
|
game.queue_free()
|
|
await drain_cleanup()
|
|
if failures.is_empty():
|
|
print("ABG_P9_0_BOOT_TITLE_OK checks=23 required=10 embedded_font=1 failure_retry=1 verified_terminal=1 no_run=1 focus=start contract_handoff=1 mutation=0")
|
|
quit(0)
|
|
else:
|
|
for failure in failures:
|
|
push_error(failure)
|
|
quit(1)
|
|
|
|
|
|
func find_control(node: Node, node_name: String) -> Control:
|
|
if node.name == node_name and node is Control and not node.is_queued_for_deletion():
|
|
return node
|
|
for child in node.get_children():
|
|
var found := find_control(child, node_name)
|
|
if found != null:
|
|
return found
|
|
return null
|
|
|
|
|
|
func settle() -> void:
|
|
for frame in range(8):
|
|
await process_frame
|
|
|
|
|
|
func drain_cleanup() -> void:
|
|
for frame in range(40):
|
|
await process_frame
|
|
|
|
|
|
func expect(condition: bool, message: String) -> void:
|
|
if not condition:
|
|
failures.append("P9.0 Boot/Title: %s" % message)
|