# lib-core.panel-test Test-module for `lib-core.panel`. v0.4.0 expands to 128 assertions: - v0.1.x: registry lifecycle, theme validation, error handling, pause-gate, context-menu dispatch. - v0.2.0 (W.0): multi-active model, 11 layout-slots, custom-fn layout, hit-test reverse-open-order, bw-compat shim. - v0.3.0 (W.2): z-tiers (hud/normal/top), persistent windows, input_block routing (none/self/all), default-input_block per tier, panel.point_in_any_panel public API, chromeless guards, top-tier modal swallow. - v0.4.0 (W.3): focus API (focus/raise/lower/get_focused), click-to-focus auto-routing, drag-by-title-bar with 32px screen-clamp, resize-by-SE-corner with min/max_size clamps, bounds_override pattern persistence, chromeless drag guard. **Version:** 0.4.0 **Lib-ID:** lib-core.panel-test **Requires:** lib-core.panel v0.4.0 **Tags:** test, panel, ui, window-manager, focus, drag, resize ## Running ```bash export PATH="/c/msys64/mingw64/bin:$PATH" cd ~/Projects/Sporel/sporel-engine SPOREL_LIBS_DIR=~/Projects/Sporel/sporel-libs SPOREL_CI=1 SPOREL_LOG_STDERR=1 \ ./build/Sporel.exe --test-libs=lib-core.panel-test 2>&1 | tail -15 ``` Expected: `pass=128 fail=0`. ## Assertion Summary (v0.4.0) **v0.1.x baseline (10 assertions):** 1. register + open / close round-trip 2. close after open works 3. toggle twice opens then closes 4. open with unknown widget_id raises an error 5. set_theme with valid override is visible via get_theme 6. set_theme with unknown key raises an error 7. register without render function raises an error 8. pause_on_open=true widget makes is_pausing() true; close makes it false 9. context-menu action callback invoked on click inside its row 10. non-pause widget: is_pausing() is false **v0.2.0 W.0 multi-active + layout-slots (~44 assertions):** bw-compat shim, multi-active open(A)+open(B), per-id close, focused-close, layout-slot resolution (left-half, right-half, center, custom fn), loud-error on unknown slot, hit-test reverse-open-order, is_pausing across all open windows. **v0.3.0 W.2 z-tiers + persistent + input-block (28 assertions):** - persistent flag auto-opens at register-time + is in open_order - z_tier render-order is hud → normal → top - within z_tier, open-order preserved - input_block="none" passes through (no handler call) - input_block="self" hit-tests within bounds (inside vs outside) - input_block="all" swallows outside-clicks (modal block) - persistent + close() no-op when focused is persistent - close(id) explicit DOES close persistent (modder-controlled) - Loud-Error on unknown z_tier - Loud-Error on unknown input_block - default input_block per tier (hud=none, normal=self, top=all) - point_in_any_panel public API (inside / outside / none open) - chromeless suppresses phantom close-button hit-test - top-tier modal swallows outside-clicks before lower tiers can claim **v0.4.0 W.3 focus + drag + resize (46 assertions):** - focus(id) reorders within open_order; focus(hud) is no-op - raise alias = focus - lower(id) moves to bottom of open_order - get_focused() prioritizes top-tier over normal; nil when nothing open - click on window auto-focuses (non-hud only) - drag updates bounds_override (simulate-backdoor) - drag screen-clamp keeps 32px of title-bar visible on all edges - resize updates bounds_override (SE-corner; simulate-backdoor) - resize min_size + max_size constraints clamp correctly - dispatch-time drag-start fires on real title-bar click - dispatch-time resize-start fires on real SE-corner click - chromeless widget does NOT drag-start on top-area click - bounds_override survives drag-end (persists in window record) - point_in_any_panel respects bounds_override