From 5f01edea87319385a67547410c3ac17c32cf1561 Mon Sep 17 00:00:00 2001 From: Levi Neuwirth Date: Mon, 3 Aug 2026 11:16:08 -0400 Subject: [PATCH] test(panel): pin that the OMITTED default degrades on a pre-panel frontend MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Stage 3 step 5, criterion 5 — the one the framing named as most likely to be quietly wrong. `acc14` already proves capability fallback for an EXPLICIT `request.side` at the core level, and it is not this case. Stage 3 resolves the default into a PANEL REQUEST inside the adopter, so a pre-panel semantic frontend now has to degrade a request the caller never wrote. Nothing in `listview.open { name, rows }` says "panel", yet the request reaching the core does — which is exactly why this is invisible from the adopter's side and needs its own pin rather than an inference from acc14. Asserts the three things that must survive the degradation: no side window, no side parameters on the document window, and NO QUIT ACTION left behind. That last one is the subtle half — a quit action stranded on a document window would make a later `q` try to restore a presentation that never happened. Bite-verified rather than assumed: flipping the fixture's frontend to `panel_capable = true` fails it on "a pre-panel frontend gets no side window from the omitted default", so the test is measuring the capability and not merely the absence of a panel it never asked for. Co-Authored-By: Claude Opus 5 (1M context) --- tests/bottom_panel_stage1_acceptance.rs | 64 +++++++++++++++++++++++++ 1 file changed, 64 insertions(+) diff --git a/tests/bottom_panel_stage1_acceptance.rs b/tests/bottom_panel_stage1_acceptance.rs index 40f2b93..36efbe2 100644 --- a/tests/bottom_panel_stage1_acceptance.rs +++ b/tests/bottom_panel_stage1_acceptance.rs @@ -1660,6 +1660,70 @@ fn acc21_panel_visit_and_jump_back_returns_to_the_panel() { ); } +/// Bottom-panel Stage 3, criterion 5 — the OMITTED default degrades on a +/// frontend that cannot host a panel. +/// +/// `acc14` already proves capability fallback for an EXPLICIT +/// `request.side` at the core level. This is the Stage 3 case and it is +/// not the same one: the default is now resolved into a panel request +/// inside the adopter, so a pre-panel semantic frontend must degrade a +/// request the caller never wrote. The framing calls this the criterion +/// most likely to be quietly wrong, because the fallback is invisible +/// from the adopter's side — nothing in `listview.open` says "panel", +/// yet the request that reaches the core does. +/// +/// What must survive the degradation: no side window, no side +/// parameters, and NO QUIT ACTION left on the document window. A quit +/// action stranded on a document window would make a later `q` try to +/// restore a presentation that never existed. +#[test] +fn s3_2_the_omitted_default_degrades_on_a_pre_panel_frontend() { + let s = editor(); + let fid = FrontendId(31); + let document = attach_frontend(&s, fid, false); + s.core.borrow_mut().active_frontend = fid; + + // No `display` at all — the Stage 3 default resolves to a panel + // request, which this frontend cannot honour. + exec( + &s, + "pmacs.listview.open { name = \"*degraded*\", rows = { { text = \"row\" } } }", + ); + + assert!( + s.core.borrow().side_window_for(fid).is_none(), + "a pre-panel frontend gets no side window from the omitted default" + ); + { + let core = s.core.borrow(); + let window = &core.windows[&document]; + assert!( + window.params.side.is_none(), + "no side parameter is left on the document window" + ); + assert!( + !window.params.dedicated, + "the document window is not dedicated by a degraded request" + ); + assert!( + window.params.quit_action().is_none(), + "NO quit action is left behind — `q` must not try to restore a \ + presentation that never happened" + ); + assert_eq!( + core.registry + .borrow() + .get(window.buffer_id) + .expect("live buffer") + .name(), + "*degraded*", + "the buffer still reached the document target" + ); + } + + s.core.borrow_mut().active_frontend = FrontendId::LOCAL; +} + #[test] fn acc22_jump_histories_are_per_frontend_and_skip_stale_side_origins() { let s = editor();