Files
TheTree_mock/tests/mvp/test_tomari_floor_trouble.gd
Takeshi b84bade045 Save The Tree implementation and acceptance work in progress
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.
2026-10-11 15:58:00 +09:00

137 lines
10 KiB
GDScript

extends SceneTree
var checks := 0
var failures := 0
var runtime: Variant
var clock: Variant
var state: Variant
var upper: FacilityInstance
var front: FacilityInstance
var lower: FacilityInstance
func _initialize() -> void:
call_deferred("run")
func expect(ok: bool, label: String) -> void:
checks += 1
if not ok:
failures += 1
push_error("TOMARI_FLOOR_TROUBLE: " + label)
func enqueue(id: StringName, context: Dictionary = {}) -> CommandResult:
return runtime.event_service.enqueue_candidate(id, [], clock.absolute_minute, {&"context":context})
func define(id: StringName, category: StringName, facility: StringName) -> void:
expect(runtime.event_service.create_definition(id, {&"category":category, &"foreground":false, &"location_rule":{&"facility_id":facility}}).is_success(), "fixture definition registers")
func run() -> void:
runtime = load("res://autoload/simulation_runtime.gd").new()
clock = load("res://autoload/game_clock.gd").new()
state = load("res://autoload/game_state.gd").new()
clock.reset(1,6,0)
state.reset()
expect(runtime.initialize(clock,state,42602)[&"valid"], "actual runtime initializes")
clock.set_paused(true)
for request: Array in [[&"reception",Vector3i(-6,0,0)],[&"warehouse",Vector3i(-6,0,1)],[&"premium_room",Vector3i(-6,2,0)],[&"warehouse",Vector3i(-6,2,1)],[&"service_stairs",Vector3i(-7,1,1)],[&"service_stairs",Vector3i(-7,2,1)]]:
var built: CommandResult = runtime.submit_command(&"build_facility",{&"definition_id":request[0],&"origin":request[1]})
expect(built.is_success(),"public construction succeeds")
if not built.is_success():
finish()
return
clock.advance_minutes(runtime.definition_registry.get_facility(request[0]).build_minutes)
for facility: FacilityInstance in runtime.facility_service.get_instances():
if facility.definition_id==&"warehouse":
if facility.origin.y==2: upper=facility
else: lower=facility
if facility.definition_id==&"premium_room": front=facility
expect(upper!=null and front!=null and lower!=null,"two floors and two layers exist")
if upper==null or front==null or lower==null:
finish()
return
# Controlled role fixture permits normal warehouse assignment. This is not recruitment evidence.
expect(runtime.submit_command(&"register_staff",{&"staff_id":&"heroine_tomari",&"role_id":&"porter",&"options":{&"employment_kind":&"UNIQUE",&"current_cell":Vector3i(-8,0,0)}}).is_success(),"controlled unique identity registers")
define(&"upper_trouble",&"TROUBLE",upper.instance_id)
define(&"front_trouble",&"TROUBLE",front.instance_id)
define(&"lower_trouble",&"TROUBLE",lower.instance_id)
define(&"upper_flavor",&"FLAVOR",upper.instance_id)
define(&"invalid_target",&"TROUBLE",&"unknown_fixture_target")
expect(not runtime.is_floor_trouble_protected(2),"unassigned unique gives no floor protection")
var queued := enqueue(&"upper_trouble")
expect(queued.is_success(),"unassigned trouble enters actual queue")
var pending: EventInstance = runtime.event_service.get_queued_instances()[0]
expect(runtime.submit_command(&"set_staff_work_assignment",{&"staff_id":&"heroine_tomari",&"facility_id":upper.instance_id,&"template_id":&"NIGHT"}).is_success(),"public assignment checks role capacity and route")
expect(runtime.is_floor_trouble_protected(2) and not runtime.is_floor_trouble_protected(0),"protection follows actual assigned floor")
expect(not runtime.event_service.start_next_event(clock.absolute_minute).is_success(),"already queued protected trouble cannot start")
expect(clock.paused,"pre-start placement cancellation preserves explicit player pause")
expect(pending.state==EventInstance.State.CANCELLED and pending.failure_reason=="PLACEMENT_PROTECTION", "queued trouble canceled with explicit reason")
expect(runtime.event_service.get_actor_locks().is_empty() and runtime.event_service.get_queued_instances().is_empty(),"cancel leaves no actor lock or waiting event")
var before: Dictionary = runtime.create_snapshot()
var bytes_before: PackedByteArray = var_to_bytes(before)
for target: StringName in [&"upper_trouble",&"front_trouble",&"invalid_target"]:
expect(not enqueue(target).is_success(),"protected or unknown target rejects enqueue")
expect(not enqueue(&"upper_trouble",{&"facility_id":lower.instance_id}).is_success(),"conflicting target cannot bypass protection")
expect(runtime.create_snapshot()==before and var_to_bytes(runtime.create_snapshot())==bytes_before,"rejection preserves whole live snapshot and IDs RNG queues")
var worker: StaffRuntime = runtime.staff_service.get_staff(&"heroine_tomari")
var old_kind := worker.employment_kind
worker.employment_kind=StaffRuntime.EmploymentKind.FREE_HIRE
expect(not runtime.is_floor_trouble_protected(2),"ordinary name spoof has no passive effect")
worker.employment_kind=old_kind
var old_state := worker.state
worker.state=StaffRuntime.State.OFF_DUTY
expect(runtime.is_floor_trouble_protected(2),"placement passive has no invented attendance gate")
worker.state=old_state
var old_operation := upper.operation_state
upper.operation_state=FacilityInstance.OperationState.SUSPENDED
expect(runtime.is_floor_trouble_protected(2),"placement passive has no invented workplace operation gate")
upper.operation_state=old_operation
expect(runtime.create_snapshot()==before and var_to_bytes(runtime.create_snapshot())==bytes_before,"observation fixtures restored byte exactly")
expect(runtime.restore_snapshot(before),"same existing snapshot schema restores")
expect(not enqueue(&"upper_trouble").is_success(),"restore reinstalls actual eligibility callback")
var save_path := "user://tomari-floor-trouble.save"
expect(runtime.save_to_path(save_path).get(&"ok",false),"actual disk save succeeds")
expect(runtime.load_from_path(save_path).get(&"ok",false),"actual disk load succeeds")
expect(not enqueue(&"front_trouble").is_success(),"disk load restores opposite-layer protection")
expect(SaveService.delete_save(save_path),"owned fixture save cleaned through SaveService")
expect(enqueue(&"lower_trouble").is_success(),"other floor remains eligible")
expect(enqueue(&"upper_flavor").is_success(),"nontrouble on protected floor remains eligible")
var ids: Array[StringName]=[]
for event: EventInstance in runtime.event_service.get_queued_instances(): ids.append(event.event_instance_id)
for id: StringName in ids: expect(runtime.event_service.cancel_event(id).is_success(),"eligible fixture queue cleanup")
var missing: CommandResult = runtime.event_service.create_definition(&"missing_location",{&"category":&"TROUBLE",&"foreground":false})
expect(missing.is_success() and not enqueue(&"missing_location").is_success(),"missing target is fail closed")
filter_boundaries()
reassignment_and_queued_restore()
finish()
func filter_boundaries() -> void:
define(&"safe_replacement",&"FLAVOR",upper.instance_id)
expect(runtime.event_service.create_definition(&"restricted_trouble",{&"category":&"TROUBLE",&"foreground":false,&"location_rule":{&"facility_id":upper.instance_id},&"content_rating":&"RESTRICTED",&"content_tags":[&"restricted_fixture"],&"filter_behavior":&"REPLACE",&"replacement_event_id":&"safe_replacement"}).is_success(),"restricted original fixture registers")
expect(runtime.event_service.create_definition(&"restricted_flavor",{&"category":&"FLAVOR",&"foreground":false,&"content_rating":&"RESTRICTED",&"content_tags":[&"restricted_fixture"],&"filter_behavior":&"REPLACE",&"replacement_event_id":&"upper_trouble"}).is_success(),"restricted replacement fixture registers")
runtime.event_service.configure_content_filter(EventDefinition.FilterBehavior.REPLACE,EventDefinition.ContentRating.GENERAL,[&"restricted_fixture"])
var before: PackedByteArray=var_to_bytes(runtime.create_snapshot())
expect(not enqueue(&"restricted_trouble").is_success(),"original trouble cannot bypass via flavor replacement")
expect(not enqueue(&"restricted_flavor").is_success(),"resolved trouble cannot bypass via flavor original")
expect(var_to_bytes(runtime.create_snapshot())==before,"both filter rejections mutate no live snapshot")
func reassignment_and_queued_restore() -> void:
clock.set_paused(true) # Normal player pause before immediate public command editing.
expect(runtime.submit_command(&"set_staff_work_assignment",{&"staff_id":&"heroine_tomari",&"facility_id":lower.instance_id,&"template_id":&"NIGHT"}).is_success(),"public reassignment succeeds")
expect(runtime.is_floor_trouble_protected(0) and not runtime.is_floor_trouble_protected(2),"protection transfers and releases previous floor")
expect(not enqueue(&"lower_trouble").is_success(),"newly assigned floor is protected")
expect(enqueue(&"restricted_trouble").is_success(),"original trouble queues before placement moves")
expect(enqueue(&"restricted_flavor").is_success(),"replacement trouble queues before placement moves")
expect(runtime.event_service.get_queued_instances().size()==2,"two filtered candidates waiting")
var queued_snapshot: Dictionary=runtime.create_snapshot()
expect(runtime.restore_snapshot(queued_snapshot),"existing schema restores waiting original and resolved IDs")
expect(runtime.submit_command(&"set_staff_work_assignment",{&"staff_id":&"heroine_tomari",&"facility_id":upper.instance_id,&"template_id":&"NIGHT"}).is_success(),"public reassignment restores upper protection")
var save_path := "user://tomari-queued.save"
expect(runtime.save_to_path(save_path).get(&"ok",false) and runtime.load_from_path(save_path).get(&"ok",false),"disk roundtrip preserves already waiting candidates")
var waiting: Array[EventInstance]=runtime.event_service.get_queued_instances()
expect(waiting.size()==2,"disk roundtrip retains both candidate source identities")
var counts := {&"started":0}
runtime.event_service.event_started.connect(func(_event: EventInstance) -> void: counts[&"started"]+=1)
expect(not runtime.event_service.start_next_event(clock.absolute_minute).is_success(),"restored queued originals and replacements cannot start after placement")
expect(clock.paused,"restored placement cancellation preserves saved paused clock")
for event: EventInstance in waiting:
expect(event.state==EventInstance.State.CANCELLED and event.failure_reason=="PLACEMENT_PROTECTION", "each restored waiting candidate canceled before actions")
expect(counts[&"started"]==0 and runtime.event_service.get_actor_locks().is_empty() and runtime.event_service.get_queued_instances().is_empty(),"no start signal actions lock or queue survives")
expect(SaveService.delete_save(save_path),"second owned disk fixture cleaned")
func finish() -> void:
runtime.free()
clock.free()
state.free()
print("TOMARI_FLOOR_TROUBLE checks=%d failures=%d" % [checks,failures])
quit(failures)