Preserve production code, regression fixtures, audio assets and provenance, test infrastructure, and the original-completion plan and progress ledger. Final game and Windows acceptance remain pending; excluded local artifacts and native experiments are not part of this snapshot.
106 lines
5.6 KiB
GDScript
106 lines
5.6 KiB
GDScript
extends SceneTree
|
|
|
|
const AudioTeardown := preload("res://tests/helpers/ui_audio_teardown.gd")
|
|
|
|
var _checks := 0
|
|
var _failures := 0
|
|
var _main: Control
|
|
var _runtime: Variant
|
|
var _clock: Variant
|
|
var _module_id: StringName = &""
|
|
var _shaft_id: StringName = &""
|
|
|
|
func _initialize() -> void:
|
|
call_deferred("_run")
|
|
|
|
func _run() -> void:
|
|
_clock = root.get_node("GameClock")
|
|
_runtime = root.get_node("SimulationRuntime")
|
|
var state: Variant = root.get_node("GameState")
|
|
_clock.reset(1, 6, 0)
|
|
state.reset()
|
|
_runtime.initialize(_clock, state, 924263)
|
|
_clock.set_paused(true)
|
|
root.size = Vector2i(1280, 720)
|
|
_main = load("res://scenes/main/main.tscn").instantiate() as Control
|
|
_main.set("manual_save_path", "user://tests/elevator_ui_%d/manual" % OS.get_process_id())
|
|
root.add_child(_main)
|
|
_runtime.configure_save_policy({&"enabled": false, &"daily_checkpoint_enabled": false})
|
|
await process_frame
|
|
await process_frame
|
|
_expect(not _main.get("selected_elevator_controls").visible, "empty inspector hides lift controls")
|
|
_main.call("_select_build_definition", &"guest_elevator")
|
|
_main.call("_on_map_cell_clicked", Vector3i(0, 0, 0))
|
|
_expect(_runtime.construction_service.get_jobs().size() == 1, "normal build UI pays for lift construction")
|
|
_clock.advance_minutes(300)
|
|
_main.call("_clear_build_selection")
|
|
var report: Dictionary = _runtime.elevators.get_report()
|
|
_expect(report[&"shafts"].size() == 1, "completed paid lift registers one real car")
|
|
if report[&"shafts"].size() != 1:
|
|
await _finish()
|
|
return
|
|
_shaft_id = report[&"shafts"][0][&"shaft_id"]
|
|
_module_id = report[&"shafts"][0][&"module_ids"][0]
|
|
_main.call("_on_facility_selected", _module_id)
|
|
_expect(_main.get("selected_elevator_controls").visible and _main.get("management_panel").visible, "selecting finished lift opens existing inspector controls")
|
|
_expect(_main.get("selected_heading_label").text == "客用昇降機", "proxy lift gets localized title instead of syncing placeholder")
|
|
var detail: String = _main.get("selected_detail_label").text
|
|
_expect("現在階" in detail and "目的階" in detail and "乗客" in detail and "待機" in detail and "1F 〜 2F" in detail, "inspector displays real cabin floors, occupancy, queue and stops")
|
|
var button: Button = _main.get("elevator_operation_button")
|
|
_expect(not button.disabled and button.text == "昇降機を停止", "idle powered car exposes stop command")
|
|
button.pressed.emit()
|
|
_expect(not _shaft()[&"operator_open"] and button.text == "運行を再開", "paused stop applies real operator state and swaps button")
|
|
_expect("手動停止" in _main.get("selected_detail_label").text, "stopped inspector state is explicit")
|
|
_expect(_runtime.path_service.find_path(Vector3i(0, 0, 0), Vector3i(0, 1, 0)).is_empty(), "UI stop removes usable ride route while shaft blocks climbing")
|
|
button.pressed.emit()
|
|
_expect(_shaft()[&"operator_open"] and bool(_shaft()[&"operational"]) == bool(_shaft()[&"powered"]), "UI resume respects actual cabin power availability")
|
|
_expect(bool(_shaft()[&"powered"]) or "魔力供給なし" in _main.get("selected_detail_label").text, "unpowered cabin cannot appear as running after operator resume")
|
|
_clock.set_paused(false)
|
|
button.pressed.emit()
|
|
_expect(button.disabled and _runtime.command_queue.pending_count() == 1, "running-clock command locks further submission")
|
|
_main.call("_on_elevator_operation_pressed")
|
|
_expect(_runtime.command_queue.pending_count() == 1, "repeated stop press cannot enqueue duplicate command")
|
|
_main.call("_save_manual")
|
|
_clock.advance_minutes(1)
|
|
_expect(not _shaft()[&"operator_open"], "queued command applies at next simulation minute")
|
|
_main.call("_load_manual")
|
|
_main.call("_on_facility_selected", _module_id)
|
|
_expect(_runtime.command_queue.pending_count() == 1 and button.disabled, "manual load restores queued lift command and disables duplicate submission")
|
|
_clock.advance_minutes(1)
|
|
_clock.set_paused(true)
|
|
_expect(not _shaft()[&"operator_open"] and not button.disabled, "restored command applies exactly once and unlocks control")
|
|
button.pressed.emit()
|
|
_expect(_shaft()[&"operator_open"], "post-load UI uses fresh idempotency sequence and can resume")
|
|
_main.call("_on_map_cell_clicked", Vector3i(10, 0, 0))
|
|
_expect(not _main.get("selected_elevator_controls").visible, "selecting empty ground removes obsolete operation control")
|
|
_main.call("_on_facility_selected", _module_id)
|
|
await process_frame
|
|
await process_frame
|
|
var panel_rect: Rect2 = _main.get("management_panel").get_global_rect()
|
|
_expect(panel_rect.encloses(button.get_global_rect()) and _main.get_global_rect().encloses(panel_rect), "operation button remains visible inside inspector at a 1280 by 720 window")
|
|
if OS.get_environment("THE_TREE_ELEVATOR_UI_CAPTURE") == "1":
|
|
await RenderingServer.frame_post_draw
|
|
var image_value := root.get_texture().get_image()
|
|
DirAccess.make_dir_recursive_absolute(ProjectSettings.globalize_path("res://artifacts/transport"))
|
|
image_value.save_png("res://artifacts/transport/elevator-inspector.png")
|
|
await _finish()
|
|
|
|
func _shaft() -> Dictionary:
|
|
for row: Dictionary in _runtime.elevators.get_report()[&"shafts"]:
|
|
if row[&"shaft_id"] == _shaft_id:
|
|
return row
|
|
return {}
|
|
|
|
func _finish() -> void:
|
|
_clock.set_paused(true)
|
|
var teardown: Dictionary = await AudioTeardown.free_owner_and_wait(self, _main)
|
|
_expect(bool(teardown.get(&"passed", false)) and not bool(teardown.get(&"deadline_reached", true)), "owned audio references release before bounded teardown deadline with whole Runtime unchanged")
|
|
print("Elevator management UI: %d checks, %d failures" % [_checks, _failures])
|
|
quit(_failures)
|
|
|
|
func _expect(ok: bool, label: String) -> void:
|
|
_checks += 1
|
|
if not ok:
|
|
_failures += 1
|
|
push_error(label)
|