Files
TheTree_mock/tests/transport/test_runtime_build_preview.gd
T

148 lines
8.7 KiB
GDScript

extends SceneTree
var _checks := 0
var _failures := 0
var _serial := 0
var _runtime: Variant
var _clock: Variant
var _state: Variant
func _initialize() -> void:
call_deferred("_run")
func _run() -> void:
_clock = load("res://autoload/game_clock.gd").new()
_state = load("res://autoload/game_state.gd").new()
var base_script: Variant = load("res://autoload/simulation_runtime.gd")
if base_script == null or not base_script.can_instantiate():
push_error("Runtime preview base script could not be loaded.")
quit(1)
return
# Seed diagnostic switches isolate precedence; the operations gate itself is real.
var diagnostic_script := GDScript.new()
diagnostic_script.source_code = """extends "res://autoload/simulation_runtime.gd"
var block_operations := false
var block_vertical := false
func _operations_total_arrears() -> int:
return 1 if block_operations else super._operations_total_arrears()
func _facility_definition_is_unsupported_vertical_proxy(definition: Variant) -> bool:
return block_vertical or super._facility_definition_is_unsupported_vertical_proxy(definition)
"""
var reload_error := diagnostic_script.reload()
if reload_error != OK:
push_error("Runtime preview diagnostic script reload failed: %s" % reload_error)
quit(1)
return
_runtime = diagnostic_script.new()
if _runtime == null:
push_error("Runtime preview diagnostic instance is null.")
quit(1)
return
for method: StringName in [&"initialize", &"create_snapshot", &"enable_production_operations"]:
if not _runtime.has_method(method):
push_error("Runtime preview diagnostic instance lacks method: %s" % method)
quit(1)
return
var infrastructure_projector: Variant = load("res://scripts/world/facility_infrastructure_projector.gd")
_reset()
var cell := Vector3i(-8, 2, 0)
_failure_case(&"unknown.preview.definition", cell, 0, "NOT_FOUND", "Facility definition was not found.")
check(_runtime.enable_production_operations().get(&"ok", false), "enable real operations gate")
_runtime.block_operations = true
_runtime.block_vertical = true
_failure_case(&"unknown.preview.definition", cell, 999, "UNPAID_EXPENSES", "Operations currently block construction and investment.")
_failure_case(&"guest_stairs", cell, 999, "UNPAID_EXPENSES", "Operations currently block construction and investment.")
_runtime.block_operations = false
_failure_case(&"guest_stairs", cell, 999, String(infrastructure_projector.REASON_UNSUPPORTED_VERTICAL_TOPOLOGY), "Vertical infrastructure topology is not supported.")
_reset()
_failure_case(&"guest_stairs", cell, 999, "STAIR_LANDING_MISSING", "先に階段の一つ下の階に通路を作ってください。")
_failure_case(&"guest_corridor", cell, 999, "INVALID_PAYLOAD", "The selected rotation is not allowed.")
# origin INVALID_PAYLOAD cannot be reached through preview's Vector3i API.
_reset()
var lower_stairs := _command(&"guest_stairs", Vector3i(4, 1, 0), 0)
check(lower_stairs.is_success(), "build real lower stairs: %s" % lower_stairs.message)
_clock.advance_minutes(_runtime.definition_registry.get_facility(&"guest_stairs").build_minutes)
var lower_exists := false
for facility: Dictionary in _runtime.construction_service.get_facilities():
if facility[&"origin"] == Vector3i(4, 1, 0):
lower_exists = true
check(lower_exists, "real lower stairs construction completes")
var report := _pure_preview(&"guest_stairs", Vector3i(4, 2, 0), 0)
var accepted: Variant = _command(&"guest_stairs", Vector3i(4, 2, 0), 0)
if not (report[&"can_build"] and accepted.is_success()):
var first_reason: Dictionary = report[&"reasons"][0] if not report[&"reasons"].is_empty() else {}
var command_code := String(accepted.details.get(&"reason", CommandResult.Code.keys()[accepted.code]))
print("Runtime preview positive: can_build=%s error_codes=%s first_code=%s first_message=%s command_code=%s command_message=%s" % [report[&"can_build"], JSON.stringify(report[&"error_codes"]).left(256), JSON.stringify(first_reason.get(&"code", "none")).left(256), JSON.stringify(first_reason.get(&"message", "none")).left(512), JSON.stringify(command_code).left(256), JSON.stringify(accepted.message).left(512)])
check(report[&"can_build"] and accepted.is_success(), "positive landing preview and command agree")
_reset()
check(_command(&"guest_elevator", Vector3i.ZERO, 0).is_success(), "build real elevator")
_clock.advance_minutes(310)
check(_runtime.submit_command(&"hire_staff_candidate", {&"candidate_id": &"staff_akane"}).is_success(), "hire elevator actor")
var access: Array[StringName] = [&"staff"]
var queued: Dictionary = _runtime.elevators.request_trip(&"staff:staff_akane", Vector3i.ZERO, Vector3i(0, 1, 0), _clock.absolute_minute, access)
check(queued.get(&"ok", false), "queue real elevator trip")
_failure_case(&"guest_elevator", Vector3i(0, 2, 0), 999, "ELEVATOR_BUSY", "Wait until the shaft is idle before extending it.")
_runtime.free()
_clock.free()
_state.free()
print("Runtime build preview: %d checks, %d failures" % [_checks, _failures])
quit(1 if _failures > 0 else 0)
func _reset() -> void:
_runtime.block_operations = false
_runtime.block_vertical = false
_clock.reset(1, 6, 0)
_state.reset()
check(_runtime.initialize(_clock, _state, 90416)[&"valid"], "initialize preview fixture")
_runtime.configure_save_policy({&"enabled": false, &"daily_checkpoint_enabled": false})
_clock.set_paused(true)
func _pure_preview(id: StringName, cell: Vector3i, rotation: int) -> Dictionary:
var before := var_to_bytes(_runtime.create_snapshot())
# CommandQueue contains the accepted command log and processed receipts.
var log_before := var_to_bytes(_runtime.command_queue.create_snapshot())
var commands_before: int = _runtime.command_queue.get_accepted_command_metadata().size()
var processed_before: int = _runtime.command_queue.processed_count()
var events_before: int = _runtime.domain_events.recent_events().size()
var report: Dictionary = _runtime.preview_build_facility(id, cell, rotation)
var after := var_to_bytes(_runtime.create_snapshot())
var log_after := var_to_bytes(_runtime.command_queue.create_snapshot())
var commands_after: int = _runtime.command_queue.get_accepted_command_metadata().size()
var processed_after: int = _runtime.command_queue.processed_count()
var events_after: int = _runtime.domain_events.recent_events().size()
print("Runtime preview proof: case=%s cell=%s rotation=%d snapshot_before=%s snapshot_after=%s queue_before=%s queue_after=%s accepted_before=%d accepted_after=%d processed_before=%d processed_after=%d events_before=%d events_after=%d can_build=%s error_codes=%s" % [JSON.stringify(String(id)).left(256), cell, rotation, _sha256(before), _sha256(after), _sha256(log_before), _sha256(log_after), commands_before, commands_after, processed_before, processed_after, events_before, events_after, report[&"can_build"], JSON.stringify(report[&"error_codes"]).left(256)])
check(before == after, "preview preserves typed snapshot bytes")
check(log_before == log_after, "preview preserves command log bytes")
check(commands_before == commands_after and processed_before == processed_after, "preview preserves command counts")
check(events_before == events_after, "preview preserves event count")
return report
func _sha256(bytes: PackedByteArray) -> String:
var context := HashingContext.new()
context.start(HashingContext.HASH_SHA256)
context.update(bytes)
return context.finish().hex_encode()
func _failure_case(id: StringName, cell: Vector3i, rotation: int, code: String, message: String) -> void:
var report := _pure_preview(id, cell, rotation)
check(not report[&"can_build"] and report[&"error_codes"][0] == code, "preview first code: " + code)
check(report[&"reasons"][0][&"code"] == code and report[&"reasons"][0][&"message"] == message, "preview real message: " + code)
var refused := _command(id, cell, rotation)
var command_code := String(refused.details.get(&"reason", CommandResult.Code.keys()[refused.code]))
check(not refused.is_success() and command_code == code, "submit code agrees: " + code)
check(refused.message == message and refused.message == report[&"reasons"][0][&"message"], "submit message agrees: " + code)
check(refused.details == report[&"reasons"][0][&"details"], "submit details agree: " + code)
if _runtime.definition_registry.get_facility(id) == null:
check(report.size() == 4 and report[&"cells"].is_empty() and report[&"reasons"].size() == 1 and report[&"error_codes"].size() == 1, "unknown definition returns only precheck summary")
func _command(id: StringName, cell: Vector3i, rotation: int) -> CommandResult:
_serial += 1
return _runtime.submit_command(&"build_facility", {&"definition_id": id, &"origin": cell, &"rotation": rotation}, &"manager", &"", 0, -1, StringName("runtime.preview.%d" % _serial))
func check(ok: bool, message: String) -> void:
_checks += 1
if not ok:
_failures += 1
push_error(message)
quit(1)