Files
TheTree_mock/tests/s1/test_route_subslot_path_adapter.gd
T
Takeshi 5dde0c5ec2 Record original-alignment implementation and traceability checkpoint
Capture current source, content data, tests, asset licenses, and original-specification traceability. Original implementation remains incomplete. The accepted matching UI generation passed 154 suites and 12,253 checks, with eight rendered staff-contract screens reviewed. Latest native Windows and full-original acceptance remain outstanding.
2026-09-30 23:52:24 +09:00

527 lines
31 KiB
GDScript

extends SceneTree
const AdapterType = preload("res://scripts/world/route_subslot_path_adapter.gd")
const SpatialType = preload("res://scripts/world/spatial_subslot_service.gd")
const PathType = preload("res://scripts/world/path_service.gd")
const WorldType = preload("res://scripts/world/world_service.gd")
const CommandResultType = preload("res://scripts/core/command_result.gd")
class ControlledPathService:
extends PathService
var fail_next_rebuild_after_mutation := false
var reject_restore := false
var reenter_next_rebuild := false
var tamper_adapter_next_rebuild := false
var adapter: Variant = null
var reentry_result: Variant = null
func rebuild_graph(passable_cells: Variant) -> bool:
var should_fail := fail_next_rebuild_after_mutation
fail_next_rebuild_after_mutation = false
var should_reenter := reenter_next_rebuild
reenter_next_rebuild = false
var should_tamper := tamper_adapter_next_rebuild
tamper_adapter_next_rebuild = false
var rebuilt := super.rebuild_graph(passable_cells)
if should_reenter and adapter != null:
reentry_result = adapter.place_route(
&"nested_path_request",
&"nested_path_route",
[Vector3i(40, 0, 0)]
)
if should_tamper and adapter != null:
adapter.projection_revision += 99
if should_fail:
last_error = "Injected Path rebuild failure after mutation."
return false
return rebuilt
func restore_snapshot(snapshot: Dictionary) -> bool:
if reject_restore:
last_error = "Injected Path restore failure."
return false
return super.restore_snapshot(snapshot)
var _checks := 0
var _failures := 0
func _initialize() -> void:
call_deferred("_run")
func _run() -> void:
print("S1: atomic ROUTE subslot Path projection")
_test_basic_projection_and_world_coexistence()
_test_replace_and_layer_separation()
_test_idempotency_and_defensive_queries()
_test_stale_detection_and_synchronization()
_test_path_failure_rolls_both_services_back()
_test_callback_reentry_and_tamper_defense()
_test_uncertain_rollback_quarantines_and_recovers()
_test_strict_snapshot_round_trip_and_atomic_rejection()
_test_strict_input_and_route_only_boundary()
_test_validation_cache_checks_history_and_live_graph()
if _failures == 0:
print("PASS: %d checks" % _checks)
else:
push_error("FAIL: %d of %d checks failed" % [_failures, _checks])
quit(_failures)
func _test_basic_projection_and_world_coexistence() -> void:
var source := SpatialType.new()
var path := PathType.new()
var world := WorldType.new()
world.reset({&"min_x": -2, &"max_x": 4, &"min_y": -2, &"max_y": 2})
var start := Vector3i(0, 0, 0)
var bridge := Vector3i(1, 0, 0)
var goal := Vector3i(2, 0, 0)
_expect(world.occupy(&"major_facility", [bridge], &"facility_large"), "major World occupancy exists independently")
var adapter := AdapterType.new()
_expect(adapter.configure(source, path, [goal, start]), "base walkable cells configure the initial Path projection")
_expect(path.find_path(start, goal).is_empty(), "disconnected base cells are initially unreachable")
var placed = adapter.place_route(&"route_place_1", &"route_bridge", [bridge])
_expect(placed.is_success(), "ROUTE placement and Path rebuild commit together")
_expect(path.find_path(start, goal) == [start, bridge, goal], "ROUTE subslot makes the real Path graph reachable")
_expect(world.get_occupant(bridge) == &"major_facility", "ROUTE projection preserves primary World occupancy")
_expect(adapter.source_revision == 1 and adapter.projection_revision == 2, "source and projection revisions advance deterministically")
_expect(not adapter.is_projection_stale(), "committed projection is fresh")
_expect(adapter.remove_route(&"route_remove_1", &"route_bridge").is_success(), "ROUTE removal and Path rebuild commit together")
_expect(path.find_path(start, goal).is_empty(), "removing the ROUTE makes the real Path graph unreachable again")
_expect(adapter.validate_invariants()[&"ok"], "basic projection crosslinks remain valid")
func _test_replace_and_layer_separation() -> void:
var source := SpatialType.new()
var path := PathType.new()
var front_start := Vector3i(0, 2, 0)
var front_mid := Vector3i(1, 2, 0)
var front_goal := Vector3i(2, 2, 0)
var back_start := Vector3i(0, 2, 1)
var back_mid := Vector3i(1, 2, 1)
var back_goal := Vector3i(2, 2, 1)
var adapter := AdapterType.new()
_expect(
adapter.configure(source, path, [back_goal, front_goal, back_start, front_start]),
"two-layer base projection configures in canonical order"
)
_expect(
adapter.place_route(&"layers_place", &"dual_layer_route", [back_mid, front_mid]).is_success(),
"one ROUTE entity can project cells on both layers"
)
_expect(path.find_path(front_start, front_goal) == [front_start, front_mid, front_goal], "FRONT route is reachable")
_expect(path.find_path(back_start, back_goal) == [back_start, back_mid, back_goal], "BACK route is reachable")
_expect(path.find_path(front_start, back_goal).is_empty(), "FRONT and BACK remain disconnected without a connector")
var replaced = adapter.replace_route(&"layers_replace", &"dual_layer_route", [front_mid])
_expect(replaced.is_success() and replaced.details[&"changed"], "ROUTE replacement commits atomically")
_expect(path.find_path(front_start, front_goal).size() == 3, "replacement retains the FRONT route")
_expect(path.find_path(back_start, back_goal).is_empty(), "replacement removes the BACK projection")
var base_route := adapter.place_route(&"base_overlap_place", &"base_overlap_route", [front_start])
_expect(base_route.is_success(), "ROUTE may overlap a base walkable cell")
_expect(adapter.remove_route(&"base_overlap_remove", &"base_overlap_route").is_success(), "base-overlap ROUTE removes cleanly")
_expect(path.has_cell(front_start), "removing a ROUTE never removes the overlapping base cell")
_expect(adapter.validate_invariants()[&"ok"], "replacement and layer projection crosslinks remain valid")
func _test_idempotency_and_defensive_queries() -> void:
var source := SpatialType.new()
var path := PathType.new()
var adapter := AdapterType.new()
var start := Vector3i(0, 0, 0)
var middle := Vector3i(1, 0, 0)
var goal := Vector3i(2, 0, 0)
adapter.configure(source, path, [goal, start])
var first = adapter.place_route(&"z_request", &"route_idem", [middle])
var after_first_adapter := adapter.create_snapshot()
var after_first_source := source.create_snapshot()
var after_first_path := path.create_snapshot()
var replay = adapter.place_route(&"z_request", &"route_idem", [middle])
_expect(first.is_success() and replay.is_success() and replay.is_replay, "same request ID and fingerprint replays")
_expect(replay.details == first.details, "idempotent replay preserves exact result details")
_expect(adapter.create_snapshot() == after_first_adapter, "replay does not advance adapter state")
_expect(source.create_snapshot() == after_first_source and path.create_snapshot() == after_first_path, "replay does not touch either authoritative service")
var conflict = adapter.place_route(&"z_request", &"route_idem", [Vector3i(1, 1, 0)])
_expect(conflict.code == CommandResultType.Code.DUPLICATE_IDEMPOTENCY_KEY, "same request ID with another fingerprint conflicts")
var before_noop_revision := adapter.projection_revision
var noop = adapter.replace_route(&"a_request", &"route_idem", [middle])
_expect(noop.is_success() and not noop.details[&"changed"], "canonical-equivalent replace is a successful no-op")
_expect(adapter.projection_revision == before_noop_revision, "no-op request does not advance projection revision")
_expect(adapter.get_processed_request_ids() == [&"a_request", &"z_request"], "processed request IDs are lexical")
var returned_base := adapter.get_base_walkable_cells()
var returned_route := adapter.get_projected_route_cells()
var returned_walkable := adapter.get_projected_walkable_cells()
var returned_status := adapter.get_projection_status()
returned_base.clear()
returned_route.clear()
returned_walkable.clear()
returned_status[&"source_changed"] = true
_expect(adapter.get_base_walkable_cells().size() == 2, "base-cell query is defensive")
_expect(adapter.get_projected_route_cells() == [middle], "route projection query is defensive")
_expect(adapter.get_projected_walkable_cells().size() == 3, "walkable projection query is defensive")
_expect(not adapter.get_projection_status()[&"source_changed"], "projection status query is defensive")
func _test_stale_detection_and_synchronization() -> void:
var source := SpatialType.new()
var path := PathType.new()
var adapter := AdapterType.new()
var start := Vector3i(0, 0, 0)
var middle := Vector3i(1, 0, 0)
var goal := Vector3i(2, 0, 0)
var base := [start, goal]
adapter.configure(source, path, base)
_expect(source.place(&"external_route", source.CATEGORY_ROUTE, [middle]).is_success(), "direct source mutation can occur outside the adapter boundary")
var stale_status := adapter.get_projection_status()
_expect(stale_status[&"stale"] and stale_status[&"source_changed"], "direct ROUTE mutation is detected as stale")
var blocked = adapter.place_route(&"blocked_while_stale", &"blocked_route", [Vector3i(3, 0, 0)])
_expect(blocked.code == CommandResultType.Code.TRANSACTION_CLOSED, "route mutation is blocked while projection is stale")
var synchronized = adapter.synchronize_projection(&"sync_source_1")
_expect(synchronized.is_success() and synchronized.details[&"changed"], "explicit synchronization projects the external ROUTE change")
_expect(path.find_path(start, goal) == [start, middle, goal], "source synchronization repairs real Path reachability")
_expect(adapter.source_revision == source.get_revision_for_category(source.CATEGORY_ROUTE), "synchronization records the exact source revision")
var sync_replay = adapter.synchronize_projection(&"sync_source_1")
_expect(sync_replay.is_success() and sync_replay.is_replay, "synchronization request is idempotently replayed")
path.rebuild_graph(base)
_expect(adapter.get_projection_status()[&"path_changed"], "direct Path topology drift is detected")
var repaired = adapter.synchronize_projection(&"sync_path_2")
_expect(repaired.is_success() and repaired.details[&"changed"], "synchronization repairs direct Path drift")
_expect(path.find_path(start, goal).size() == 3 and not adapter.is_projection_stale(), "Path drift repair restores a fresh route")
var projection_before_decoration := adapter.projection_revision
_expect(source.place(&"external_decor", source.CATEGORY_DECORATION, [middle]).is_success(), "non-ROUTE source category changes independently")
_expect(not adapter.is_projection_stale(), "DECORATION revision does not stale the ROUTE projection")
_expect(adapter.projection_revision == projection_before_decoration, "unrelated source mutation does not advance projection revision")
var base_source := SpatialType.new()
var base_path := PathType.new()
var base_adapter := AdapterType.new()
base_adapter.configure(base_source, base_path, base)
var base_added = base_adapter.synchronize_projection(&"base_add", [goal, middle, start])
_expect(base_added.is_success() and base_added.details[&"changed"], "synchronization atomically replaces the base walkable set")
_expect(base_path.find_path(start, goal).size() == 3, "new base walkability participates in the rebuilt graph")
_expect(base_adapter.get_base_walkable_cells() == [start, middle, goal], "updated base cells are canonical and queryable")
var base_removed = base_adapter.synchronize_projection(&"base_remove", base)
_expect(base_removed.is_success() and base_removed.details[&"changed"], "base walkability can be removed atomically")
_expect(base_path.find_path(start, goal).is_empty(), "removed base walkability disappears from the graph")
_expect(base_adapter.validate_invariants()[&"ok"], "dynamic base synchronization preserves crosslinks")
func _test_path_failure_rolls_both_services_back() -> void:
var source := SpatialType.new()
var path := ControlledPathService.new()
var adapter := AdapterType.new()
path.adapter = adapter
var start := Vector3i(0, 0, 0)
var middle := Vector3i(1, 0, 0)
var alternate := Vector3i(1, 1, 0)
var goal := Vector3i(2, 0, 0)
adapter.configure(source, path, [start, goal])
var before_adapter := adapter.create_snapshot()
var before_source := source.create_snapshot()
var before_path := path.create_snapshot()
path.fail_next_rebuild_after_mutation = true
var failed_place = adapter.place_route(&"retryable_place", &"route_atomic", [middle])
_assert_exact_rollback(adapter, source, path, before_adapter, before_source, before_path, failed_place, "failed place")
_expect(not adapter.is_quarantined(), "exact place rollback does not quarantine")
_expect(not source.has_entity(&"route_atomic") and path.find_path(start, goal).is_empty(), "failed place leaves neither side applied")
_expect(adapter.place_route(&"retryable_place", &"route_atomic", [middle]).is_success(), "failed request ID can be retried after exact rollback")
before_adapter = adapter.create_snapshot()
before_source = source.create_snapshot()
before_path = path.create_snapshot()
path.fail_next_rebuild_after_mutation = true
var failed_replace = adapter.replace_route(&"retryable_replace", &"route_atomic", [alternate])
_assert_exact_rollback(adapter, source, path, before_adapter, before_source, before_path, failed_replace, "failed replace")
_expect(source.get_entity_cells(&"route_atomic") == [middle], "failed replacement restores the original ROUTE cells")
_expect(adapter.replace_route(&"retryable_replace", &"route_atomic", [alternate]).is_success(), "replacement retries after exact rollback")
before_adapter = adapter.create_snapshot()
before_source = source.create_snapshot()
before_path = path.create_snapshot()
path.fail_next_rebuild_after_mutation = true
var failed_remove = adapter.remove_route(&"retryable_remove", &"route_atomic")
_assert_exact_rollback(adapter, source, path, before_adapter, before_source, before_path, failed_remove, "failed remove")
_expect(source.has_entity(&"route_atomic"), "failed removal restores the ROUTE entity")
_expect(adapter.remove_route(&"retryable_remove", &"route_atomic").is_success(), "removal retries after exact rollback")
path.adapter = null
func _test_callback_reentry_and_tamper_defense() -> void:
var source := SpatialType.new()
var path := ControlledPathService.new()
var adapter := AdapterType.new()
path.adapter = adapter
adapter.configure(source, path, [Vector3i(0, 0, 0), Vector3i(2, 0, 0)])
path.reenter_next_rebuild = true
var outer = adapter.place_route(&"outer_path_callback", &"outer_route", [Vector3i(1, 0, 0)])
_expect(outer.is_success(), "outer transaction commits when Path callback only attempts reentry")
_expect(path.reentry_result != null and not path.reentry_result.is_success(), "Path callback reentry is rejected")
_expect(not source.has_entity(&"nested_path_route"), "reentrant Path callback cannot create a nested ROUTE")
var nested_source_result: Array = [null]
source.configure_compatibility_validator(
func(_payload: Dictionary) -> Dictionary:
nested_source_result[0] = adapter.place_route(
&"nested_source_request",
&"nested_source_route",
[Vector3i(5, 0, 0)]
)
return {&"ok": true}
)
var source_outer = adapter.place_route(&"outer_source_callback", &"second_route", [Vector3i(3, 0, 0)])
_expect(source_outer.is_success(), "outer transaction commits when Spatial validator only attempts reentry")
_expect(nested_source_result[0] != null and not nested_source_result[0].is_success(), "Spatial callback reentry is rejected")
_expect(not source.has_entity(&"nested_source_route"), "reentrant Spatial callback cannot create a nested ROUTE")
source.configure_compatibility_validator(Callable())
var before_adapter := adapter.create_snapshot()
var before_source := source.create_snapshot()
var before_path := path.create_snapshot()
path.tamper_adapter_next_rebuild = true
var tampered = adapter.replace_route(&"path_tamper_request", &"second_route", [Vector3i(4, 0, 0)])
_assert_exact_rollback(adapter, source, path, before_adapter, before_source, before_path, tampered, "Path callback adapter tamper")
_expect(not adapter.is_quarantined(), "detected callback tamper with exact rollback stays available")
source.configure_compatibility_validator(
func(_payload: Dictionary) -> Dictionary:
return {&"ok": false, &"reason": &"WORLD_POLICY_REJECTED"}
)
before_adapter = adapter.create_snapshot()
before_source = source.create_snapshot()
before_path = path.create_snapshot()
var rejected = adapter.place_route(&"source_rejection", &"rejected_route", [Vector3i(6, 0, 0)])
_assert_exact_rollback(adapter, source, path, before_adapter, before_source, before_path, rejected, "Spatial validator rejection")
source.configure_compatibility_validator(Callable())
path.adapter = null
func _test_uncertain_rollback_quarantines_and_recovers() -> void:
var source := SpatialType.new()
var path := ControlledPathService.new()
var adapter := AdapterType.new()
path.adapter = adapter
var start := Vector3i(0, 0, 0)
var middle := Vector3i(1, 0, 0)
var goal := Vector3i(2, 0, 0)
var base := [start, goal]
adapter.configure(source, path, base)
var recovery_adapter := adapter.create_snapshot()
var recovery_source := source.create_snapshot()
var recovery_path := path.create_snapshot()
path.fail_next_rebuild_after_mutation = true
path.reject_restore = true
var failed = adapter.place_route(&"uncertain_request", &"uncertain_route", [middle])
_expect(not failed.is_success() and not failed.details[&"rollback_ok"], "uncertain rollback reports failure explicitly")
_expect(adapter.is_quarantined() and adapter.get_quarantine_reason() == adapter.QUARANTINE_TRANSACTION_ROLLBACK, "uncertain rollback quarantines the adapter")
_expect(adapter.is_projection_stale(), "quarantined projection reports stale")
var blocked = adapter.place_route(&"blocked_in_quarantine", &"blocked_route", [Vector3i(3, 0, 0)])
_expect(blocked.code == CommandResultType.Code.TRANSACTION_CLOSED, "quarantine blocks further mutations")
path.reject_restore = false
_expect(source.restore_snapshot(recovery_source), "recovery restores the Spatial source snapshot")
_restore_path_for_test(path, base, recovery_path)
_expect(path.create_snapshot() == recovery_path, "recovery restores the exact Path snapshot")
_expect(adapter.restore_snapshot(recovery_adapter), "exact adapter snapshot clears quarantine after dependencies recover")
_expect(not adapter.is_quarantined() and not adapter.is_projection_stale(), "snapshot recovery returns the adapter to service")
_expect(adapter.place_route(&"post_recovery", &"recovered_route", [middle]).is_success(), "route transaction succeeds after quarantine recovery")
path.adapter = null
func _test_strict_snapshot_round_trip_and_atomic_rejection() -> void:
var source := SpatialType.new()
var path := PathType.new()
var adapter := AdapterType.new()
var base := [Vector3i(0, 0, 0), Vector3i(3, 0, 0)]
adapter.configure(source, path, base)
adapter.place_route(&"z_place", &"route_z", [Vector3i(1, 0, 0)])
adapter.place_route(&"a_place", &"route_a", [Vector3i(2, 0, 0)])
adapter.synchronize_projection(&"b_sync_base", base)
adapter.replace_route(&"m_noop", &"route_a", [Vector3i(2, 0, 0)])
var snapshot := adapter.create_snapshot()
_expect(
snapshot[&"processed_requests"].map(func(row: Dictionary) -> String: return row[&"request_id"]) == ["a_place", "b_sync_base", "m_noop", "z_place"],
"snapshot request history is lexical"
)
var restored_source := SpatialType.new()
_expect(restored_source.restore_snapshot(source.create_snapshot()), "snapshot test restores a matching Spatial source")
var restored_path := PathType.new()
var restored := AdapterType.new()
_expect(restored.configure(restored_source, restored_path, base), "snapshot test configures matching dependencies")
_expect(restored.restore_snapshot(snapshot), "strict current adapter snapshot restores")
_expect(restored.create_snapshot() == snapshot, "adapter snapshot round trip is exact")
_expect(restored.validate_invariants()[&"ok"], "restored adapter snapshot crosslinks are valid")
var replay = restored.place_route(&"z_place", &"route_z", [Vector3i(1, 0, 0)])
_expect(replay.is_success() and replay.is_replay, "restored idempotency history replays exactly")
var before := restored.create_snapshot()
var source_before := restored_source.create_snapshot()
var path_before := restored_path.create_snapshot()
var version_type := snapshot.duplicate(true)
version_type[&"schema_version"] = "1"
_atomic_snapshot_reject(restored, restored_source, restored_path, version_type, before, source_before, path_before, "string schema version")
var unknown := snapshot.duplicate(true)
unknown[&"unknown"] = true
_atomic_snapshot_reject(restored, restored_source, restored_path, unknown, before, source_before, path_before, "unknown root field")
var source_revision_type := snapshot.duplicate(true)
source_revision_type[&"source_revision"] = float(source_revision_type[&"source_revision"])
_atomic_snapshot_reject(restored, restored_source, restored_path, source_revision_type, before, source_before, path_before, "floating source revision")
var projection_bound := snapshot.duplicate(true)
projection_bound[&"projection_revision"] = 0
_atomic_snapshot_reject(restored, restored_source, restored_path, projection_bound, before, source_before, path_before, "zero projection revision")
var projection_history_gap := snapshot.duplicate(true)
projection_history_gap[&"projection_revision"] = int(projection_history_gap[&"projection_revision"]) + 1
_atomic_snapshot_reject(restored, restored_source, restored_path, projection_history_gap, before, source_before, path_before, "projection revision without request evidence")
var unordered_base := snapshot.duplicate(true)
unordered_base[&"base_walkable_cells"].reverse()
_atomic_snapshot_reject(restored, restored_source, restored_path, unordered_base, before, source_before, path_before, "unordered base cells")
var duplicate_route := snapshot.duplicate(true)
duplicate_route[&"projected_route_cells"].append(duplicate_route[&"projected_route_cells"][0])
_atomic_snapshot_reject(restored, restored_source, restored_path, duplicate_route, before, source_before, path_before, "duplicate projected route cell")
var broken_union := snapshot.duplicate(true)
broken_union[&"projected_walkable_cells"].remove_at(1)
_atomic_snapshot_reject(restored, restored_source, restored_path, broken_union, before, source_before, path_before, "broken projected union")
var quarantine_reason := snapshot.duplicate(true)
quarantine_reason[&"quarantine_reason"] = "UNKNOWN_REASON"
_atomic_snapshot_reject(restored, restored_source, restored_path, quarantine_reason, before, source_before, path_before, "orphan quarantine reason")
var request_order := snapshot.duplicate(true)
request_order[&"processed_requests"].reverse()
_atomic_snapshot_reject(restored, restored_source, restored_path, request_order, before, source_before, path_before, "unordered request history")
var request_extra := snapshot.duplicate(true)
request_extra[&"processed_requests"][0][&"extra"] = true
_atomic_snapshot_reject(restored, restored_source, restored_path, request_extra, before, source_before, path_before, "unknown request field")
var fingerprint := snapshot.duplicate(true)
fingerprint[&"processed_requests"][0][&"fingerprint"] = "tampered"
_atomic_snapshot_reject(restored, restored_source, restored_path, fingerprint, before, source_before, path_before, "request fingerprint tamper")
var sync_input := snapshot.duplicate(true)
sync_input[&"processed_requests"][1][&"input_cells"] = [Vector3i(9, 0, 0)]
_atomic_snapshot_reject(restored, restored_source, restored_path, sync_input, before, source_before, path_before, "synchronization base fingerprint tamper")
var detail_revision := snapshot.duplicate(true)
detail_revision[&"processed_requests"][0][&"details"][&"projection_revision"] = int(snapshot[&"projection_revision"]) + 1
_atomic_snapshot_reject(restored, restored_source, restored_path, detail_revision, before, source_before, path_before, "request result revision tamper")
var detail_cells := snapshot.duplicate(true)
detail_cells[&"processed_requests"][0][&"details"][&"cells"] = [Vector3i(8, 0, 0)]
_atomic_snapshot_reject(restored, restored_source, restored_path, detail_cells, before, source_before, path_before, "request result cell tamper")
var deep := snapshot.duplicate(true)
var deep_value: Variant = []
for _index: int in range(adapter.MAX_SNAPSHOT_DEPTH + 2):
deep_value = [deep_value]
deep[&"processed_requests"] = deep_value
_atomic_snapshot_reject(restored, restored_source, restored_path, deep, before, source_before, path_before, "excessive snapshot depth")
restored_path.rebuild_graph(base)
var stale_before := restored.create_snapshot()
_expect(not restored.restore_snapshot(snapshot), "valid metadata snapshot rejects mismatched live Path topology")
_expect(restored.create_snapshot() == stale_before, "live-crosslink rejection is adapter-atomic")
_expect(restored.synchronize_projection(&"repair_after_restore_reject").is_success(), "synchronization repairs live mismatch after restore rejection")
func _test_strict_input_and_route_only_boundary() -> void:
var invalid_adapter := AdapterType.new()
_expect(not invalid_adapter.configure(SpatialType.new(), PathType.new(), Vector3i.ZERO), "non-Array base cells are rejected")
_expect(not invalid_adapter.configure(SpatialType.new(), PathType.new(), [Vector3i.ZERO, Vector3i.ZERO]), "duplicate base cells are rejected")
_expect(not invalid_adapter.configure(SpatialType.new(), PathType.new(), [Vector3i(0, 0, 2)]), "invalid base layer is rejected")
var source := SpatialType.new()
var path := PathType.new()
var adapter := AdapterType.new()
adapter.configure(source, path, [Vector3i.ZERO])
_expect(adapter.is_bound_to(source, path), "adapter reports its exact authoritative service binding")
_expect(not adapter.is_bound_to(SpatialType.new(), path), "binding check rejects another equal Spatial instance")
_expect(not adapter.is_bound_to(source, PathType.new()), "binding check rejects another equal Path instance")
var before := adapter.create_snapshot()
_expect(not adapter.place_route(1, &"route", [Vector3i(1, 0, 0)]).is_success(), "numeric request ID is rejected")
_expect(not adapter.place_route(&"bad_entity", 1, [Vector3i(1, 0, 0)]).is_success(), "numeric entity ID is rejected")
_expect(not adapter.place_route(&"bad_cells", &"route", Vector3i(1, 0, 0)).is_success(), "non-Array route cells are rejected")
_expect(not adapter.place_route(&"empty_cells", &"route", []).is_success(), "empty route placement is rejected")
_expect(not adapter.place_route(&"duplicate_cells", &"route", [Vector3i(1, 0, 0), Vector3i(1, 0, 0)]).is_success(), "duplicate route cells are rejected")
_expect(not adapter.place_route(&"invalid_layer", &"route", [Vector3i(1, 0, 2)]).is_success(), "invalid route layer is rejected")
_expect(adapter.create_snapshot() == before, "malformed route requests preserve adapter state")
_expect(source.place(&"decor_only", source.CATEGORY_DECORATION, [Vector3i.ZERO]).is_success(), "DECORATION entity exists beside adapter boundary")
var source_before := source.create_snapshot()
var path_before := path.create_snapshot()
var wrong_category = adapter.remove_route(&"remove_decor", &"decor_only")
_expect(not wrong_category.is_success(), "adapter refuses to remove a non-ROUTE entity")
_expect(source.create_snapshot() == source_before and path.create_snapshot() == path_before, "route-only rejection leaves both services untouched")
_expect(not adapter.configure(source, path, [Vector3i.ZERO]), "configured adapter rejects reconfiguration")
func _test_validation_cache_checks_history_and_live_graph() -> void:
var source := SpatialType.new()
var path := PathType.new()
var adapter := AdapterType.new()
var start := Vector3i(0, 0, 0)
var middle := Vector3i(1, 0, 0)
var goal := Vector3i(2, 0, 0)
_expect(adapter.configure(source, path, [start, goal]), "cache fixture configures")
_expect(adapter.place_route(&"cache_place", &"cache_route", [middle]).is_success(), "cache fixture places route")
_expect(adapter.validate_invariants()[&"ok"] and adapter.validate_invariants()[&"ok"], "fresh and unchanged validations succeed")
var exported := adapter.create_snapshot()
exported[&"projected_walkable_cells"].clear()
exported[&"processed_requests"][0][&"input_cells"].clear()
_expect(adapter.validate_invariants()[&"ok"], "snapshot mutation cannot change live state or cached input")
var requests: Dictionary = adapter.get("_processed_requests")
var fingerprint: String = requests[&"cache_place"][&"fingerprint"]
requests[&"cache_place"][&"fingerprint"] = "invalid"
_expect(not adapter.validate_invariants()[&"ok"], "warm cache detects history corruption without revision change")
requests[&"cache_place"][&"fingerprint"] = fingerprint
_expect(adapter.validate_invariants()[&"ok"], "restored history validates")
var before := path.create_snapshot()
_expect(path.rebuild_graph([start, goal]), "remove live bridge independently")
_expect(not adapter.validate_invariants()[&"ok"], "warm cache still detects live graph divergence")
_expect(path.rebuild_graph([start, middle, goal]) and path.restore_snapshot(before), "restore live path")
_expect(adapter.validate_invariants()[&"ok"], "repaired graph validates")
_expect(adapter.remove_route(&"cache_remove", &"cache_route").is_success(), "route removal updates cached history input")
_expect(adapter.validate_invariants()[&"ok"], "updated history validates fully")
func _assert_exact_rollback(
adapter: RouteSubslotPathAdapter,
source: SpatialSubslotService,
path: PathService,
adapter_before: Dictionary,
source_before: Dictionary,
path_before: Dictionary,
result: CommandResult,
label: String
) -> void:
_expect(not result.is_success() and bool(result.details.get(&"rollback_ok", false)), "%s reports exact rollback" % label)
_expect(adapter.create_snapshot() == adapter_before, "%s restores exact adapter snapshot" % label)
_expect(source.create_snapshot() == source_before, "%s restores exact Spatial snapshot" % label)
_expect(path.create_snapshot() == path_before, "%s restores exact Path snapshot" % label)
func _atomic_snapshot_reject(
adapter: RouteSubslotPathAdapter,
source: SpatialSubslotService,
path: PathService,
candidate: Dictionary,
adapter_before: Dictionary,
source_before: Dictionary,
path_before: Dictionary,
label: String
) -> void:
_expect(not adapter.restore_snapshot(candidate), "%s is rejected" % label)
_expect(adapter.create_snapshot() == adapter_before, "%s rejection is adapter-atomic" % label)
_expect(source.create_snapshot() == source_before and path.create_snapshot() == path_before, "%s rejection leaves dependencies untouched" % label)
func _restore_path_for_test(path: PathService, cells: Array, snapshot: Dictionary) -> void:
path.rebuild_graph(cells)
path.restore_snapshot(snapshot)
path.rebuild_graph(cells)
func _expect(condition: bool, label: String) -> void:
_checks += 1
if condition:
print(" ✓ %s" % label)
return
_failures += 1
push_error(" ✗ %s" % label)