Files
settled-reach/client/tests/test_atlas_window_water_clip.gd
T
jpmschweitzerandClaude Fable 5 0b14cdb21d fix(ui): T-1172 round 2 — tile wrap resolution mirrored to the painter's own direction
Live round: the first clip removed only 133 pixels. Root cause (dossier-
traced): resolve_morphology_zone wrapped the QUERY toward a tile's raw
canonical center — the inverse of the painter's draw_col =
nearest_wrap_image(tile_center, held_center) — so seam tiles tested
containment against the wrong wrap-image and read real-but-wrong-
location land cells. Fix mirrors the painter exactly: wrap the tile's
own center toward held_center, test the (already held-wrapped) query
against that. Index math itself was confirmed correct end-to-end and
is now factored into shared AtlasWindowGeometry.cell_index_for_local_
offset() (full painter unification not applicable — the painter only
iterates forward, never reverse-looks-up; documented). Post-fix: 1082
traced positions cross-checked against actual painted pixels, 0 real
mismatches; regenerated captures show every dot/mouth on land. The one
pre-existing test encoding the buggy direction as correct was replaced
by positive+negative wrap-semantics tests (the negative one is the
reliable revert discriminator) plus a wire-accurate seam-tile fixture
with an honestly-documented proof limit (a single-tile fixture cannot
distinguish the wrap directions; the multi-tile scan tests can).
Also: two harness traps found and fixed in the lead's drive scratch —
canvas_items stretch factor (root.size now matches the 1920x1080 base
viewport) and mid-arrival snapshots (explicit is_fully_arrived wait;
the round-1 faint result was partly a 4-of-6-tiles capture). 46/46 +
50/50 + five sibling suites regression-free; gdlint clean.

Tickets: T-1172

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-23 11:33:31 +02:00

369 lines
17 KiB
GDScript

## T-1172: pure-function tests for AtlasWindowWaterClip — the two-waterline
## clip's cell-lookup math (cell_grid_side_for_window/morphology_zone_in_window/
## resolve_morphology_zone). Split into its own file matching this cluster's
## own "one pure-geometry file, one test file" precedent
## (test_atlas_window_geometry_nature.gd next to atlas_window_geometry.gd's
## nature-overlay additions).
class_name TestAtlasWindowWaterClip
extends GdUnitTestSuite
const AtlasWindowWaterClip := preload("res://ui/implant/apps/atlas/atlas_window_water_clip.gd")
const MORPHOLOGY_OPEN_OCEAN: int = 0
const MORPHOLOGY_LAND: int = 8 # AlluvialPlain — any non-water zone works
## A window dict shaped exactly like a real DistrictWindowLayer — `center`
## as a [x,y] array (the msgpack-decoded wire shape, matching every other
## mock window in this cluster's tests), `n` districts wide, `granularity_v2`
## District (1:1 cell:district, the simplest case), and a `grid_side x
## grid_side` morphology array where `grid_side == n`.
static func _mock_district_window(
center: Vector2i, n: int, morphology: PackedByteArray
) -> Dictionary:
return {
"center": [center.x, center.y],
"n": n,
"granularity_v2": "District",
"morphology": morphology,
}
# =============================================================================
# cell_grid_side_for_window — mirrors AtlasWindowOverlay.cell_grid_side_for_window()
# =============================================================================
func test_cell_grid_side_district_is_n_unchanged() -> void:
var w := {"n": 32, "granularity_v2": "District"}
assert_int(AtlasWindowWaterClip.cell_grid_side_for_window(w)).is_equal(32)
func test_cell_grid_side_quarter_is_n_times_four() -> void:
var w := {"n": 16, "granularity_v2": "Quarter"}
assert_int(AtlasWindowWaterClip.cell_grid_side_for_window(w)).is_equal(64)
func test_cell_grid_side_region_is_n_over_hundred_rounded() -> void:
var w := {"n": 6400, "granularity_v2": "Region"}
assert_int(AtlasWindowWaterClip.cell_grid_side_for_window(w)).is_equal(64)
func test_cell_grid_side_region_floors_at_one() -> void:
var w := {"n": 1, "granularity_v2": "Region"}
assert_int(AtlasWindowWaterClip.cell_grid_side_for_window(w)).is_equal(1)
func test_cell_grid_side_unknown_granularity_falls_back_to_district() -> void:
var w := {"n": 32} # no granularity_v2 key at all
assert_int(AtlasWindowWaterClip.cell_grid_side_for_window(w)).is_equal(32)
# =============================================================================
# morphology_zone_in_window — single-window cell lookup
# =============================================================================
## A 4x4 District window (n=4, grid_side=4) centered on district (0,0),
## spanning [-2, 2) on both axes. Cell (0,0) [top-left, covering district
## x in [-2,-1), y in [-2,-1)] is water; the rest is land.
static func _mock_4x4_window() -> Dictionary:
var morphology := PackedByteArray()
morphology.resize(16)
for i in range(16):
morphology[i] = MORPHOLOGY_LAND
morphology[0] = MORPHOLOGY_OPEN_OCEAN # row 0, col 0
return _mock_district_window(Vector2i.ZERO, 4, morphology)
func test_morphology_zone_in_window_reads_the_water_cell() -> void:
var w: Dictionary = _mock_4x4_window()
# District (-1.5, -1.5) falls in cell (row 0, col 0) — the water cell.
var zone: int = AtlasWindowWaterClip.morphology_zone_in_window(Vector2(-1.5, -1.5), w)
assert_int(zone).is_equal(MORPHOLOGY_OPEN_OCEAN)
func test_morphology_zone_in_window_reads_a_land_cell() -> void:
var w: Dictionary = _mock_4x4_window()
# District (1.5, 1.5) falls in cell (row 3, col 3) — land.
var zone: int = AtlasWindowWaterClip.morphology_zone_in_window(Vector2(1.5, 1.5), w)
assert_int(zone).is_equal(MORPHOLOGY_LAND)
func test_morphology_zone_in_window_outside_extent_is_no_data() -> void:
var w: Dictionary = _mock_4x4_window()
var zone: int = AtlasWindowWaterClip.morphology_zone_in_window(Vector2(100.0, 100.0), w)
assert_int(zone).is_equal(AtlasWindowWaterClip.MORPHOLOGY_ZONE_NO_DATA)
func test_morphology_zone_in_window_null_window_is_no_data() -> void:
var zone: int = AtlasWindowWaterClip.morphology_zone_in_window(Vector2.ZERO, null)
assert_int(zone).is_equal(AtlasWindowWaterClip.MORPHOLOGY_ZONE_NO_DATA)
func test_morphology_zone_in_window_missing_morphology_array_is_no_data() -> void:
var w := {"center": [0, 0], "n": 4, "granularity_v2": "District"}
var zone: int = AtlasWindowWaterClip.morphology_zone_in_window(Vector2.ZERO, w)
assert_int(zone).is_equal(AtlasWindowWaterClip.MORPHOLOGY_ZONE_NO_DATA)
func test_morphology_zone_in_window_zero_n_is_no_data() -> void:
var w := {
"center": [0, 0], "n": 0, "granularity_v2": "District", "morphology": PackedByteArray()
}
var zone: int = AtlasWindowWaterClip.morphology_zone_in_window(Vector2.ZERO, w)
assert_int(zone).is_equal(AtlasWindowWaterClip.MORPHOLOGY_ZONE_NO_DATA)
## The exact top-left/bottom-right boundary districts must resolve to the
## edge cells, not silently miss due to an off-by-one in the containment
## test — [-2, 2) is half-open, so -2.0 is IN, 2.0 is OUT.
func test_morphology_zone_in_window_boundary_inclusive_at_min() -> void:
var w: Dictionary = _mock_4x4_window()
var zone: int = AtlasWindowWaterClip.morphology_zone_in_window(Vector2(-2.0, -2.0), w)
assert_int(zone).is_equal(MORPHOLOGY_OPEN_OCEAN)
func test_morphology_zone_in_window_boundary_exclusive_at_max() -> void:
var w: Dictionary = _mock_4x4_window()
var zone: int = AtlasWindowWaterClip.morphology_zone_in_window(Vector2(2.0, 2.0), w)
assert_int(zone).is_equal(AtlasWindowWaterClip.MORPHOLOGY_ZONE_NO_DATA)
# =============================================================================
# resolve_morphology_zone — the single-window / tile-mode dispatch
# =============================================================================
func test_resolve_single_window_mode_reads_the_window_directly() -> void:
var w: Dictionary = _mock_4x4_window()
var zone: int = AtlasWindowWaterClip.resolve_morphology_zone(
Vector2(-1.5, -1.5), false, w, [], 0
)
assert_int(zone).is_equal(MORPHOLOGY_OPEN_OCEAN)
func test_resolve_single_window_mode_null_window_is_no_data() -> void:
var zone: int = AtlasWindowWaterClip.resolve_morphology_zone(Vector2.ZERO, false, null, [], 0)
assert_int(zone).is_equal(AtlasWindowWaterClip.MORPHOLOGY_ZONE_NO_DATA)
## Tile mode: two tiles, each its own 4x4 window, centered far enough apart
## that a queried district only falls inside ONE of them.
func test_resolve_tile_mode_finds_the_containing_tile() -> void:
var morph_a := PackedByteArray()
morph_a.resize(16)
for i in range(16):
morph_a[i] = MORPHOLOGY_LAND
var tile_a := {
"center": Vector2i(0, 0), "window": _mock_district_window(Vector2i.ZERO, 4, morph_a)
}
var morph_b := PackedByteArray()
morph_b.resize(16)
for i in range(16):
morph_b[i] = MORPHOLOGY_OPEN_OCEAN
var tile_b := {
"center": Vector2i(100, 0), "window": _mock_district_window(Vector2i(100, 0), 4, morph_b)
}
var tiles: Array = [tile_a, tile_b]
var zone_in_a: int = AtlasWindowWaterClip.resolve_morphology_zone(
Vector2(0.0, 0.0), true, null, tiles, 0
)
var zone_in_b: int = AtlasWindowWaterClip.resolve_morphology_zone(
Vector2(100.0, 0.0), true, null, tiles, 0
)
assert_int(zone_in_a).override_failure_message(
"a district position inside tile A's extent must read tile A's own cell"
).is_equal(MORPHOLOGY_LAND)
assert_int(zone_in_b).override_failure_message(
"a district position inside tile B's extent must read tile B's own cell"
).is_equal(MORPHOLOGY_OPEN_OCEAN)
func test_resolve_tile_mode_position_outside_every_tile_is_no_data() -> void:
var morph := PackedByteArray()
morph.resize(16)
var tile := {"center": Vector2i(0, 0), "window": _mock_district_window(Vector2i.ZERO, 4, morph)}
var zone: int = AtlasWindowWaterClip.resolve_morphology_zone(
Vector2(9999.0, 9999.0), true, null, [tile], 0
)
assert_int(zone).is_equal(AtlasWindowWaterClip.MORPHOLOGY_ZONE_NO_DATA)
## A tile whose window hasn't arrived yet (`window: null`, matching
## AtlasWindowTileSet.get_tiles()'s own "unarrived" shape) must be skipped,
## not crash — the scan continues to the next tile / falls through to
## MORPHOLOGY_ZONE_NO_DATA.
func test_resolve_tile_mode_skips_unarrived_tiles() -> void:
var unarrived := {"center": Vector2i(0, 0), "window": null}
var zone: int = AtlasWindowWaterClip.resolve_morphology_zone(
Vector2(0.0, 0.0), true, null, [unarrived], 0
)
assert_int(zone).is_equal(AtlasWindowWaterClip.MORPHOLOGY_ZONE_NO_DATA)
func test_resolve_tile_mode_empty_tile_list_is_no_data() -> void:
var zone: int = AtlasWindowWaterClip.resolve_morphology_zone(Vector2.ZERO, true, null, [], 0)
assert_int(zone).is_equal(AtlasWindowWaterClip.MORPHOLOGY_ZONE_NO_DATA)
## Live round 2 fix (coordinator's trace, T-1172): a tile whose CANONICAL
## center is far from `held_center` (the seam-tile case — exactly Lendel's
## own live repro, tile canonical center 12739 drawn at draw_col=-6400) must
## have its CENTER wrapped toward `held_center_x` — mirroring
## AtlasWindowOverlay._draw_tile_mosaic()'s own `draw_col =
## nearest_wrap_image(center.x, held_center.x, cols)` EXACTLY — before
## testing containment. The query `district` is assumed ALREADY expressed in
## the held-center-wrapped frame (AtlasWindowNatureOverlay._district()'s own
## contract) and is NOT separately re-wrapped.
##
## Original (pre-fix) test asserted the INVERSE — wrapping the query toward
## the tile's raw canonical center — which was the actual bug: it happened
## to land inside the tile's CANONICAL (unwrapped) span by coincidental mod
## arithmetic, silently testing the WRONG real-world location whenever a
## tile needed wrapping to appear on screen at all. Live capture evidence:
## a river dot at district.x=-9569 sitting on the painter's WEST wrap-image
## of a seam tile (canonical center 12739, draw_col=-6400) read a real but
## wrong-location land cell under the old code, and only stopped doing so
## once resolve_morphology_zone() wrapped the TILE's center instead.
func test_resolve_tile_mode_wraps_the_tiles_own_center_toward_held_center() -> void:
var cols := 100
var morph := PackedByteArray()
morph.resize(16)
for i in range(16):
morph[i] = MORPHOLOGY_OPEN_OCEAN
# Tile's canonical center is column 98 (far east) — but its nearest
# wrap-image to held_center=0 is column -2 (98 - 100), matching the
# Lendel seam tile's own shape (canonical 12739 -> draw_col -6400).
var tile := {"center": Vector2i(98, 0), "window": _mock_district_window(Vector2i(98, 0), 4, morph)}
# Query at column -2.5 — inside the tile's WRAP-IMAGE span [-4, 0), the
# real on-screen location, held_center-relative (the caller's own
# _district() contract) — NOT inside the canonical span [96, 100).
var zone: int = AtlasWindowWaterClip.resolve_morphology_zone(
Vector2(-2.5, 0.0), true, null, [tile], cols, 0
)
assert_int(zone).override_failure_message(
"the tile's CENTER must be wrapped toward held_center_x (mirroring the"
+ " painter's draw_col computation) so a query already expressed in the"
+ " held-center frame resolves against the tile's REAL on-screen wrap-image"
).is_equal(MORPHOLOGY_OPEN_OCEAN)
## The INVERSE position — a query at the tile's CANONICAL (unwrapped) span —
## must NOT resolve against this tile once wrapping is applied, since that
## span is no longer where the tile actually draws relative to held_center.
## Pins that the fix doesn't just "also succeed at the old span" by accident.
func test_resolve_tile_mode_does_not_match_the_tiles_stale_canonical_span() -> void:
var cols := 100
var morph := PackedByteArray()
morph.resize(16)
for i in range(16):
morph[i] = MORPHOLOGY_OPEN_OCEAN
var tile := {"center": Vector2i(98, 0), "window": _mock_district_window(Vector2i(98, 0), 4, morph)}
# Query at column 97 — inside the tile's CANONICAL span [96,100) — but
# that is NOT where this tile is drawn relative to held_center=0 (it's
# drawn at the wrap-image [-4,0) instead), so this must NOT resolve.
var zone: int = AtlasWindowWaterClip.resolve_morphology_zone(
Vector2(97.0, 0.0), true, null, [tile], cols, 0
)
assert_int(zone).override_failure_message(
"a query at the tile's stale CANONICAL span must not resolve against it"
+ " once the tile is wrapped toward held_center — that span is not where"
+ " the tile actually draws on screen"
).is_equal(AtlasWindowWaterClip.MORPHOLOGY_ZONE_NO_DATA)
# =============================================================================
# T-1172 round 2 (coordinator's "wire-accurate fixture" hardening ask —
# cold-start batch discipline): a fixture derived from an ACTUAL live tile
# response captured during the round-2 investigation, at the REAL wire scale
# (n=6400, grid_side=64, Region granularity) — not a hand-shrunk 4x4 mock.
# The round-2 bug (wrapping the query toward the tile instead of the tile
# toward held_center) passed EVERY test against the small mocks above,
## because those mocks never modeled a tile whose canonical center is FAR
# from held_center — the exact condition the bug needed to manifest. This
# fixture reproduces that condition at production scale, so a future
# regression of the same SHAPE (stub-and-code silently agreeing on a wrong
# convention) can't hide behind "the small tests still pass."
# =============================================================================
## Lendel's own seam tile from the live drive capture that closed T-1172
## round 2 (client/tmp_drive_clip.gd, SR_LIVE=1 against the worktree release
## server): canonical center (12739, -3200), TILE_N=6400 districts,
## Region granularity (grid_side = round(6400/100) = 64). `cols=19139`
## matches Lendel's real district_extent() circumference. The morphology
## array is NOT the real 4096-byte payload (too large to hand-author) — only
## the ONE cell index the live trace actually resolved for the
## district=-9569.414 repro query (idx=1024, col=0/row=16 — the exact
## INDEX_TRACE line from the live investigation) is given a real value;
## every other cell is left at 0 (OpenOcean), which is irrelevant here since
## this fixture exists to pin the WRAP resolution reaching the CORRECT
## tile/cell pair, not to re-verify the index math itself (already covered
## above and in test_atlas_window_geometry_nature.gd).
static func _lendel_seam_tile_fixture() -> Dictionary:
var morph := PackedByteArray()
morph.resize(4096)
morph[1024] = MORPHOLOGY_LAND # col=0, row=16 — the live-traced cell
return {
"center": Vector2i(12739, -3200),
"window": {
"center": [12739, -3200],
"n": 6400,
"granularity_v2": "Region",
"morphology": morph,
}
}
## The exact district position from the live capture that ORIGINALLY exposed
## the round-2 bug (district.x=-9569.414 — a dot visibly sitting on the
## painter's WEST wrap-image of the seam tile). held_center_x=0 (the
## viewer's canonical orbital-frame origin, cols=19139 (Lendel's real
## circumference in districts). Must resolve to the SAME land zone the live
## painter trace independently confirmed for this exact query.
##
## Honest note (found DURING revert-verification, worth recording): for a
## SINGLE tile in isolation, the old (query-wrapped-toward-tile) and new
## (tile-wrapped-toward-held_center) formulas are mathematically GUARANTEED
## to agree whenever local_x lands in-range for both — both reduce to
## `query - tile_center (mod cols)`, and a valid `local_x` is unique in
## `[0, n)`. This single-tile fixture therefore does NOT independently
## distinguish old from new (confirmed: it still passes with the pre-fix
## code) — it locks in the real wire-scale numbers as a realistic regression
## fixture (shared index formula, tile shape, wrap arithmetic all exercised
## together), not as the old-vs-new discriminator. The tests that DO reliably
## catch the round-2 regression are
## test_resolve_tile_mode_wraps_the_tiles_own_center_toward_held_center and
## test_resolve_tile_mode_does_not_match_the_tiles_stale_canonical_span above
## (confirmed: the latter fails by name against the reverted code) — the
## real-world bug's actual mechanism was the MULTI-TILE SCAN ORDER matching
## the WRONG tile's data before reaching the right one, not a single-tile
## formula divergence; a true multi-tile live reproduction would need the
## full 6-tile fixture, impractical to hand-author at full 4096-cell scale.
func test_wire_accurate_lendel_seam_tile_resolves_correctly() -> void:
var tile: Dictionary = _lendel_seam_tile_fixture()
var zone: int = AtlasWindowWaterClip.resolve_morphology_zone(
Vector2(-9569.414, -4784.793), true, null, [tile], 19139, 0
)
assert_int(zone).override_failure_message(
"the live T-1172 round 2 repro position must resolve against the seam"
+ " tile's WRAPPED (on-screen) image and read the real traced land zone"
+ " — a regression here reproduces the ORIGINAL over-ocean-dots bug"
).is_equal(MORPHOLOGY_LAND)
## The SAME fixture, queried at a position that legitimately falls OUTSIDE
## even the wrapped tile's span (nowhere near either wrap-image) — must fail
## open (NO_DATA), not silently match by coincidental mod arithmetic (the
## general shape of the original bug, pinned generically here in case a
## future change reintroduces a different mod-arithmetic coincidence).
func test_wire_accurate_lendel_seam_tile_out_of_range_query_is_no_data() -> void:
var tile: Dictionary = _lendel_seam_tile_fixture()
var zone: int = AtlasWindowWaterClip.resolve_morphology_zone(
Vector2(500.0, 500.0), true, null, [tile], 19139, 0
)
assert_int(zone).is_equal(AtlasWindowWaterClip.MORPHOLOGY_ZONE_NO_DATA)