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.
427 lines
21 KiB
GDScript
427 lines
21 KiB
GDScript
extends SceneTree
|
|
|
|
## godot --headless --path . --script res://tests/ui/test_pixel_tower.gd
|
|
## Camera coverage uses actual Runtime construction and World occupants: a
|
|
## misplaced pointer must not select the next cell, another floor, or BACK.
|
|
|
|
var _checks := 0
|
|
var _failures := 0
|
|
var _clock: Variant
|
|
var _state: Variant
|
|
var _runtime: Variant
|
|
var _preview: WorldPreview
|
|
var _last_facility: StringName = &""
|
|
var _last_construction: StringName = &""
|
|
var _last_cell: Variant = null
|
|
|
|
|
|
func _initialize() -> void:
|
|
call_deferred("_run")
|
|
|
|
|
|
func _run() -> void:
|
|
_clock = root.get_node("GameClock")
|
|
_state = root.get_node("GameState")
|
|
_runtime = root.get_node("SimulationRuntime")
|
|
_clock.reset(1, 6, 0)
|
|
_state.reset()
|
|
_runtime.initialize(_clock, _state, 724242)
|
|
_clock.set_paused(true)
|
|
root.size = Vector2i(1280, 720)
|
|
_preview = WorldPreview.new()
|
|
_preview.size = Vector2(1100, 600)
|
|
_preview.set_runtime(_runtime)
|
|
var pixel_theme := load("res://assets/themes/japanese_fantasy/visual-theme-v1.tres") as VisualThemeProfile
|
|
_expect(pixel_theme != null and pixel_theme.pixel_dungeon_tiles != null
|
|
and pixel_theme.pixel_town_tiles != null,
|
|
"serialized theme loads both real Kenney atlases for actors and scenery")
|
|
if pixel_theme != null:
|
|
_preview.set_visual_theme(pixel_theme)
|
|
if pixel_theme.pixel_dungeon_tiles != null:
|
|
_expect(pixel_theme.pixel_dungeon_tiles.get_size() == Vector2(192, 176),
|
|
"packed actor atlas matches the 12-column source regions")
|
|
root.add_child(_preview)
|
|
_preview.set_process(false)
|
|
_preview.facility_selected.connect(_on_facility_selected)
|
|
_preview.construction_selected.connect(_on_construction_selected)
|
|
_preview.cell_clicked.connect(_on_cell_clicked)
|
|
await process_frame
|
|
await process_frame
|
|
|
|
_test_zoom_anchor_and_reset()
|
|
_test_construction_and_facility_clicks()
|
|
_test_expanded_world_round_trips()
|
|
_test_grid_preserves_hit_testing()
|
|
_test_animation_pause_and_simulation_isolation()
|
|
await _test_vertical_scroll_and_connection()
|
|
|
|
_preview.queue_free()
|
|
await process_frame
|
|
if _failures == 0:
|
|
print("PASS: %d pixel tower checks" % _checks)
|
|
else:
|
|
push_error("FAIL: %d of %d pixel tower checks failed" % [_failures, _checks])
|
|
quit(_failures)
|
|
|
|
|
|
func _test_zoom_anchor_and_reset() -> void:
|
|
_preview.reset_view()
|
|
var overview := _preview.get_map_rect()
|
|
var anchor_cell := Vector3i(-4, 2, WorldPreview.LayerMode.FRONT)
|
|
var anchor := _preview.cell_to_canvas(anchor_cell)
|
|
_preview.set_zoom(2.0, anchor)
|
|
_expect(_preview.canvas_to_cell(anchor) == anchor_cell,
|
|
"zoom anchored at a room keeps that room under the pointer")
|
|
_expect(_preview.cell_to_canvas(anchor_cell).distance_to(anchor) <= 2.0,
|
|
"cursor-anchored zoom keeps the same location within the room")
|
|
_expect(_preview.get_cell_rect(anchor_cell).size.y > _preview.get_cell_rect(anchor_cell).size.x,
|
|
"tower floors retain the rectangular cell aspect used by hit testing")
|
|
_preview.pan_offset += Vector2(137, -73)
|
|
_preview.reset_view()
|
|
var restored := _preview.get_map_rect()
|
|
_expect(restored.position.is_equal_approx(overview.position) and restored.size.is_equal_approx(overview.size),
|
|
"reset returns to the original full overview after both pan and zoom")
|
|
_expect(_preview.canvas_to_cell(_preview.cell_to_canvas(anchor_cell)) == anchor_cell,
|
|
"reset keeps authoritative world coordinates selectable")
|
|
|
|
|
|
func _test_construction_and_facility_clicks() -> void:
|
|
var origin := Vector3i(-6, 0, WorldPreview.LayerMode.FRONT)
|
|
var result: Variant = _runtime.submit_command(
|
|
&"build_facility", {&"definition_id": &"reception", &"origin": origin, &"rotation": 0},
|
|
&"player", &"", 50, -1, &"pixel.camera.reception"
|
|
)
|
|
_expect(result != null and result.is_success(), "camera fixture builds a reception through Runtime")
|
|
var jobs: Array = _runtime.construction_service.get_jobs()
|
|
_expect(jobs.size() == 1, "fixture creates exactly one real construction site")
|
|
if jobs.size() != 1:
|
|
return
|
|
var job: Variant = jobs[0]
|
|
_preview.layer_mode = WorldPreview.LayerMode.FRONT
|
|
_preview.set_zoom(2.0)
|
|
_center_on(origin)
|
|
_click(_preview.cell_to_canvas(origin))
|
|
_expect(_last_construction == StringName(job.job_id) and _last_facility.is_empty(),
|
|
"zoomed construction click resolves the real job rather than a finished facility")
|
|
_clock.advance_minutes(120)
|
|
var facilities: Array = _runtime.construction_service.get_facilities()
|
|
_expect(facilities.size() == 1, "the clicked construction completes in simulation time")
|
|
if facilities.size() != 1:
|
|
return
|
|
var facility_id := StringName(facilities[0].get(&"instance_id", &""))
|
|
var occupied: Array[Vector3i] = []
|
|
for x: int in range(4):
|
|
for y: int in range(2):
|
|
occupied.append(origin + Vector3i(x, y, 0))
|
|
for zoom: float in [1.0, 2.0, 3.0]:
|
|
_preview.set_zoom(zoom)
|
|
_center_on(origin + Vector3i(1, 1, 0))
|
|
for cell: Vector3i in occupied:
|
|
var rect := _preview.get_cell_rect(cell)
|
|
# Sample near opposite corners to catch square-cell conversions that
|
|
# look correct at the center but select a different floor near edges.
|
|
for fraction: Vector2 in [Vector2(0.15, 0.15), Vector2(0.85, 0.85)]:
|
|
var point := rect.position + rect.size * fraction
|
|
_expect(_preview.canvas_to_cell(point) == cell,
|
|
"zoom %.1f maps interior point to occupied cell %s" % [zoom, cell])
|
|
_expect(_preview.facility_at_canvas(point) == facility_id,
|
|
"zoom %.1f resolves reception footprint at %s" % [zoom, cell])
|
|
_click(point)
|
|
_expect(_last_facility == facility_id and _last_construction.is_empty(),
|
|
"zoom %.1f emits facility selection for the clicked interior" % zoom)
|
|
var empty_neighbor := origin + Vector3i(4, 0, 0)
|
|
var empty_point := _preview.cell_to_canvas(empty_neighbor)
|
|
_click(empty_point)
|
|
_expect(_last_facility.is_empty() and _last_cell == empty_neighbor,
|
|
"zoom %.1f does not extend the reception hit area into the adjacent cell" % zoom)
|
|
var front_point := _preview.cell_to_canvas(origin)
|
|
_preview.layer_mode = WorldPreview.LayerMode.BACK
|
|
_click(front_point)
|
|
_expect(_last_facility.is_empty() and _last_cell == Vector3i(origin.x, origin.y, WorldPreview.LayerMode.BACK),
|
|
"zoom %.1f cannot select the FRONT reception through the BACK layer" % zoom)
|
|
_preview.layer_mode = WorldPreview.LayerMode.FRONT
|
|
_click(_preview.cell_to_canvas(origin))
|
|
_expect(_last_facility == facility_id,
|
|
"zoom %.1f restores reception selection after returning to FRONT" % zoom)
|
|
|
|
|
|
func _test_expanded_world_round_trips() -> void:
|
|
var reputation: Variant = _runtime.submit_command(
|
|
&"update_progression_metrics", {&"metrics": {&"reputation": 25}},
|
|
&"player", &"", 100, -1, &"pixel.camera.rank.reputation"
|
|
)
|
|
var capital: Variant = _runtime.submit_command(
|
|
&"change_resources", {&"deltas": {&"gold": 10000}},
|
|
&"player", &"", 100, -1, &"pixel.camera.rank.capital"
|
|
)
|
|
var promoted: Variant = _runtime.submit_command(
|
|
&"set_world_tree_rank", {&"rank": 2},
|
|
&"player", &"", 100, -1, &"pixel.camera.rank.promote"
|
|
)
|
|
_expect(reputation.is_success() and capital.is_success() and promoted.is_success(),
|
|
"public progression commands expand the camera fixture above and below ground")
|
|
if not promoted.is_success():
|
|
return
|
|
var bounds: Dictionary = _runtime.world_service.get_bounds()
|
|
var cells: Array[Vector3i] = [
|
|
Vector3i.ZERO,
|
|
Vector3i(0, -1, 0),
|
|
Vector3i(int(bounds[&"min_x"]), int(bounds[&"min_y"]), 0),
|
|
Vector3i(int(bounds[&"max_x"]), int(bounds[&"max_y"]), 0),
|
|
Vector3i(-3, 4, 0),
|
|
]
|
|
for layer: int in [WorldPreview.LayerMode.FRONT, WorldPreview.LayerMode.BACK]:
|
|
_preview.layer_mode = layer as WorldPreview.LayerMode
|
|
for zoom: float in [1.0, 2.0, 3.0]:
|
|
_preview.set_zoom(zoom)
|
|
for cell: Vector3i in cells:
|
|
cell.z = layer
|
|
_center_on(cell)
|
|
_preview.pan_offset += Vector2(31, -17)
|
|
var point := _preview.cell_to_canvas(cell)
|
|
_expect(_preview.canvas_to_cell(point) == cell,
|
|
"zoom %.1f round trip survives pan, bounds, and layer at %s" % [zoom, cell])
|
|
var rect := _preview.get_cell_rect(cell)
|
|
_expect(rect.has_point(point), "cell center remains inside its rendered rectangle")
|
|
_preview.reset_view()
|
|
var overview := _preview.get_map_rect()
|
|
_expect(_preview.canvas_to_cell(overview.position - Vector2.ONE * 2.0) == null,
|
|
"outside-world pixels cannot become buildable cells after overview reset")
|
|
|
|
|
|
func _test_grid_preserves_hit_testing() -> void:
|
|
_preview.layer_mode = WorldPreview.LayerMode.FRONT
|
|
var cell := Vector3i(-5, 1, 0)
|
|
_center_on(cell)
|
|
var point := _preview.cell_to_canvas(cell)
|
|
var expected := _preview.facility_at_canvas(point)
|
|
_expect(not expected.is_empty(), "grid fixture points at a real reception cell")
|
|
for show: bool in [false, true, false]:
|
|
_preview.show_grid = show
|
|
_click(point)
|
|
_expect(_last_facility == expected and _preview.canvas_to_cell(point) == cell,
|
|
"grid visibility never changes facility or floor hit testing")
|
|
|
|
|
|
func _test_animation_pause_and_simulation_isolation() -> void:
|
|
var before_digest := SimulationDigest.compute(_runtime.create_snapshot())
|
|
var before_minute: int = _clock.absolute_minute
|
|
var stopped_at := float(_preview.get("_animation_time"))
|
|
_preview.call("_process", 0.5)
|
|
_expect(is_equal_approx(float(_preview.get("_animation_time")), stopped_at),
|
|
"paused simulation freezes actor animation even when rendering receives a frame")
|
|
_clock.set_paused(false)
|
|
_preview.call("_process", 0.25)
|
|
var animated_at := float(_preview.get("_animation_time"))
|
|
_expect(animated_at > stopped_at, "unpausing resumes the pixel actor animation clock")
|
|
_clock.set_paused(true)
|
|
_preview.call("_process", 0.5)
|
|
_expect(is_equal_approx(float(_preview.get("_animation_time")), animated_at),
|
|
"pausing again freezes the exact resumed animation position")
|
|
|
|
var cell := Vector3i(-5, 1, 0)
|
|
_center_on(cell)
|
|
var anchor := _preview.cell_to_canvas(cell)
|
|
var wheel := InputEventMouseButton.new()
|
|
wheel.button_index = MOUSE_BUTTON_WHEEL_UP
|
|
wheel.pressed = true
|
|
wheel.position = anchor
|
|
_preview.call("_gui_input", wheel)
|
|
_expect(_preview.canvas_to_cell(anchor) == cell,
|
|
"wheel input preserves the room under the cursor while paused")
|
|
var press := InputEventMouseButton.new()
|
|
press.button_index = MOUSE_BUTTON_MIDDLE
|
|
press.pressed = true
|
|
_preview.call("_gui_input", press)
|
|
var drag := InputEventMouseMotion.new()
|
|
drag.relative = Vector2(43, 27)
|
|
drag.button_mask = MOUSE_BUTTON_MASK_MIDDLE
|
|
_preview.call("_gui_input", drag)
|
|
press.pressed = false
|
|
_preview.call("_gui_input", press)
|
|
var moved_point := _preview.cell_to_canvas(cell)
|
|
_expect(moved_point.distance_to(anchor + drag.relative) <= 2.0,
|
|
"middle-button drag translates the visible room by the pointer movement")
|
|
_click(moved_point)
|
|
_expect(not _last_facility.is_empty(), "a room remains selectable immediately after dragging")
|
|
_preview.set_pan_mode(true)
|
|
_click(moved_point)
|
|
_expect(_last_facility.is_empty() and _last_cell == null,
|
|
"left drag in pan mode does not select or issue a placement click")
|
|
drag.button_mask = MOUSE_BUTTON_MASK_LEFT
|
|
_preview.call("_gui_input", drag)
|
|
_expect(_preview.cell_to_canvas(cell).distance_to(moved_point + drag.relative) <= 2.0,
|
|
"explicit pan mode moves the room with the left mouse button")
|
|
var pan_before := _preview.pan_offset
|
|
drag.button_mask = 0
|
|
_preview.call("_gui_input", drag)
|
|
_expect(_preview.pan_offset == pan_before and not bool(_preview.get("_dragging")),
|
|
"returning after releasing outside the viewport does not leave a stuck drag")
|
|
_click(_preview.cell_to_canvas(cell))
|
|
_preview.notification(Control.NOTIFICATION_APPLICATION_FOCUS_OUT)
|
|
_expect(not bool(_preview.get("_dragging")), "application focus loss cancels the camera drag")
|
|
_preview.set_pan_mode(false)
|
|
_click(_preview.cell_to_canvas(cell))
|
|
_expect(not _last_facility.is_empty(), "leaving pan mode restores normal facility selection")
|
|
_preview.reset_view()
|
|
_expect(int(_clock.absolute_minute) == before_minute,
|
|
"animation frames and camera input do not advance simulation minutes")
|
|
_expect(SimulationDigest.compute(_runtime.create_snapshot()) == before_digest,
|
|
"animation, zoom, pan, and visual selection preserve the authoritative simulation digest")
|
|
|
|
|
|
func _center_on(cell: Vector3i) -> void:
|
|
_preview.pan_offset += _preview.size * 0.5 - _preview.cell_to_canvas(cell)
|
|
|
|
|
|
func _click(position: Vector2) -> void:
|
|
_last_facility = &""
|
|
_last_construction = &""
|
|
_last_cell = null
|
|
var event := InputEventMouseButton.new()
|
|
event.button_index = MOUSE_BUTTON_LEFT
|
|
event.pressed = true
|
|
event.position = position
|
|
event.global_position = _preview.global_position + position
|
|
_preview.call("_gui_input", event)
|
|
|
|
|
|
func _on_facility_selected(instance_id: StringName) -> void:
|
|
_last_facility = instance_id
|
|
|
|
|
|
func _on_construction_selected(job_id: StringName) -> void:
|
|
_last_construction = job_id
|
|
|
|
|
|
func _on_cell_clicked(cell: Vector3i) -> void:
|
|
_last_cell = cell
|
|
|
|
|
|
func _expect(condition: bool, message: String) -> void:
|
|
_checks += 1
|
|
if not condition:
|
|
_failures += 1
|
|
push_error(message)
|
|
|
|
|
|
func _test_vertical_scroll_and_connection() -> void:
|
|
var previous_mouse_filter := _preview.mouse_filter
|
|
_preview.mouse_filter = Control.MOUSE_FILTER_IGNORE
|
|
var evidence := OS.get_environment("THE_TREE_P05_FIXTURE_OUTPUT")
|
|
var before := var_to_bytes(_runtime.create_snapshot())
|
|
_preview.reset_view()
|
|
_preview.set_pan_mode(true)
|
|
var anchor_cell := Vector3i(-5,0,0)
|
|
var wheel := InputEventMouseButton.new()
|
|
wheel.button_index = MOUSE_BUTTON_WHEEL_UP
|
|
wheel.pressed = true
|
|
wheel.position = _preview.cell_to_canvas(anchor_cell)
|
|
wheel.factor = 1.0
|
|
var zoom_before := _preview.zoom_level
|
|
var point_before := _preview.cell_to_canvas(anchor_cell)
|
|
_preview._gui_input(wheel)
|
|
_expect(_preview.zoom_level == zoom_before and _preview.cell_to_canvas(anchor_cell).y > point_before.y,
|
|
"pan-mode wheel moves vertically without zooming")
|
|
wheel.button_index = MOUSE_BUTTON_WHEEL_DOWN
|
|
_preview._gui_input(wheel)
|
|
_expect(_preview.cell_to_canvas(anchor_cell) == point_before, "opposite wheel returns the same cell to the same point")
|
|
wheel.ctrl_pressed = true
|
|
wheel.button_index = MOUSE_BUTTON_WHEEL_UP
|
|
_preview._gui_input(wheel)
|
|
_expect(_preview.zoom_level > zoom_before, "Ctrl-wheel retains zoom while pan mode is active")
|
|
_preview.set_pan_mode(false)
|
|
wheel.ctrl_pressed = false
|
|
wheel.button_index = MOUSE_BUTTON_WHEEL_DOWN
|
|
_preview._gui_input(wheel)
|
|
_expect(_preview.zoom_level == zoom_before, "ordinary wheel retains established zoom outside pan mode")
|
|
_preview.set_pan_mode(true)
|
|
wheel.button_index = MOUSE_BUTTON_WHEEL_UP
|
|
for i in 200: _preview._gui_input(wheel)
|
|
var clamped := _preview.pan_offset
|
|
_preview._gui_input(wheel)
|
|
_expect(_preview.pan_offset == clamped, "repeated vertical scroll stays at the existing camera boundary")
|
|
_preview.reset_view()
|
|
_preview.set_pan_mode(false)
|
|
_expect(before == var_to_bytes(_runtime.create_snapshot()), "new camera input leaves whole authoritative Runtime bytes unchanged")
|
|
var camera_after := var_to_bytes(_runtime.create_snapshot())
|
|
if not evidence.is_empty():
|
|
var f := FileAccess.open(evidence.path_join("before-camera.var"),FileAccess.WRITE);f.store_buffer(before)
|
|
f = FileAccess.open(evidence.path_join("after-camera.var"),FileAccess.WRITE);f.store_buffer(var_to_bytes(_runtime.create_snapshot()))
|
|
var definition: FacilityDefinition = _runtime.definition_registry.get_facility(&"standard_room")
|
|
_preview.layer_mode = 0
|
|
_preview.set_build_definition(definition)
|
|
_preview.set("_hovered_cell",Vector3i(-6,2,0))
|
|
_preview.call("_update_build_preview")
|
|
var before_query := var_to_bytes(_runtime.create_snapshot())
|
|
var disconnected: Dictionary = _preview.get_build_preview_report(Vector3i(-6,2,0))[&"connection"]
|
|
_expect(disconnected[&"status"] == &"DISCONNECTED", "upper room warns before real stairs reach its access cells")
|
|
_expect(before_query == var_to_bytes(_runtime.create_snapshot()), "connection warning query preserves every Runtime byte")
|
|
var control := FacilityInstance.new()
|
|
control.origin = Vector3i(-6,2,0)
|
|
control.occupied_cells.assign(_runtime.world_service.cells_for_footprint(control.origin,definition.footprint))
|
|
_expect(not _runtime.call("_find_facility_access_path",_runtime.call("_operations_entrance_cell"),control)[&"reachable"],
|
|
"warning agrees with ordinary facility routing before stairs")
|
|
await _capture_connection("disconnected",evidence)
|
|
for cell: Vector3i in [Vector3i(-7,1,0),Vector3i(-7,2,0)]:
|
|
var result: CommandResult = _runtime.submit_command(&"build_facility",{&"definition_id":&"guest_stairs",&"origin":cell})
|
|
_expect(result.is_success(), "connect preview through real paid stair construction")
|
|
_clock.advance_minutes(_runtime.definition_registry.get_facility(&"guest_stairs").build_minutes)
|
|
_preview.set("_hovered_cell",Vector3i(-6,2,0))
|
|
_preview._process(0)
|
|
before_query = var_to_bytes(_runtime.create_snapshot())
|
|
var connected: Dictionary = _preview.get_build_preview_report(Vector3i(-6,2,0))[&"connection"]
|
|
_expect(connected[&"status"] == &"CONNECTED" and not connected[&"path"].is_empty(), "real stair completion changes warning into a connected path")
|
|
_expect(before_query == var_to_bytes(_runtime.create_snapshot()), "connected preview preserves the full authoritative state")
|
|
_expect(_runtime.call("_find_facility_access_path",_runtime.call("_operations_entrance_cell"),control)[&"reachable"],
|
|
"connected preview agrees with ordinary facility routing")
|
|
_expect(_preview.get("_last_preview_report")[&"connection"][&"status"] == &"CONNECTED", "topology changes refresh the visible report even while paused")
|
|
await _capture_connection("connected",evidence)
|
|
var route: Array = connected[&"path"]
|
|
for i in range(1,route.size()):
|
|
_expect(not _runtime.path_service.get_edge_report(route[i-1],route[i]).is_empty(), "drawn connection consists only of actually accessible edges")
|
|
var blocked: Array = connected[&"access_points"]
|
|
for cell: Vector3i in blocked: _runtime.path_service.set_cell_temporary_block(cell,true)
|
|
_preview._process(0)
|
|
var blocked_report: Dictionary = _preview.get_build_preview_report(Vector3i(-6,2,0))[&"connection"]
|
|
_expect(blocked_report[&"status"] == &"DISCONNECTED", "temporary access block invalidates the cached connected report")
|
|
for cell: Vector3i in blocked: _runtime.path_service.set_cell_temporary_block(cell,false)
|
|
_preview._process(0)
|
|
_expect(_preview.get_build_preview_report(Vector3i(-6,2,0))[&"connection"][&"status"] == &"CONNECTED", "removing the block restores the same connection without stale UI")
|
|
var connected_snapshot: Dictionary = _runtime.create_snapshot()
|
|
_runtime.path_service.set_cell_temporary_block(Vector3i(-6,0,0),true)
|
|
var branch_a: Dictionary = _runtime.create_snapshot()
|
|
var revisions_a: Array = _preview.call("_current_preview_topology")
|
|
_expect(_runtime.restore_snapshot(connected_snapshot), "restore real connected Runtime before second save branch")
|
|
_runtime.path_service.set_cell_temporary_block(Vector3i(-7,2,0),true)
|
|
var branch_b: Dictionary = _runtime.create_snapshot()
|
|
var revisions_b: Array = _preview.call("_current_preview_topology")
|
|
_expect(revisions_a == revisions_b, "different saved block topology deliberately has identical revision tuple")
|
|
_expect(_runtime.restore_snapshot(branch_a), "restore first equal-revision snapshot through actual Runtime")
|
|
var branch_a_report: Dictionary = _preview.get_build_preview_report(Vector3i(-6,2,0))[&"connection"]
|
|
_expect(_runtime.restore_snapshot(branch_b), "restore second equal-revision snapshot through actual Runtime")
|
|
var branch_b_report: Dictionary = _preview.get_build_preview_report(Vector3i(-6,2,0))[&"connection"]
|
|
_expect(branch_a_report[&"status"] == &"CONNECTED" and branch_b_report[&"status"] == &"DISCONNECTED", "snapshot restore replaces stale connection despite identical revision numbers")
|
|
_expect(branch_b_report[&"status"] == &"DISCONNECTED", "blocked access remains disconnected after equal-revision save restore")
|
|
_expect(_runtime.restore_snapshot(connected_snapshot), "restore connected branch after collision test")
|
|
_preview.set_runtime(_runtime)
|
|
_expect(_preview.get_build_preview_report(Vector3i(-6,2,0))[&"connection"][&"status"] == &"CONNECTED", "Runtime rebind clears prior connection cache")
|
|
if not evidence.is_empty():
|
|
var report := {"checks":_checks,"failures":_failures,"pid":OS.get_process_id(),"camera_before_after_equal":before==camera_after,"disconnected":disconnected,"connected":connected,"blocked":blocked_report,"equal_revision_a":revisions_a,"equal_revision_b":revisions_b,"branch_a":branch_a_report,"branch_b":branch_b_report,"fixture_only":true,"normal_OS_input":false,"unit_accepted":false}
|
|
var f := FileAccess.open(evidence.path_join("report.json"),FileAccess.WRITE);f.store_string(JSON.stringify(report,"\t"))
|
|
_preview.set_build_definition(null)
|
|
_preview.mouse_filter = previous_mouse_filter
|
|
|
|
|
|
func _capture_connection(label: String, evidence: String) -> void:
|
|
if evidence.is_empty() or DisplayServer.get_name() == "headless": return
|
|
_preview.set_zoom(2)
|
|
_center_on(Vector3i(-5,1,0))
|
|
_preview.set("_hovered_cell",Vector3i(-6,2,0))
|
|
_preview.call("_update_build_preview")
|
|
_preview.queue_redraw()
|
|
await process_frame
|
|
await RenderingServer.frame_post_draw
|
|
_expect(root.get_texture().get_image().save_png(evidence.path_join("connection-"+label+".png"))==OK,
|
|
"capture actual native connection line "+label)
|