Files
improvise/tests/tui_launch_state.rs
Edward Langley ac6f17288c docs(tests): record how to know a launch default has stopped disarming tests
The question PR #60 left open was not which tests the launch default
disarmed, but HOW TO KNOW THE CLASS IS CLOSED. Grep cannot answer it: it
finds sites that NAME the flag, and the hazard is a test that merely
starts from a default-built state and asserts something downstream,
mentioning nothing. Finding the three disarmed tests by grep was luck.

Mutation answers it, because it does not care what a test mentions.
Recorded in context/test-evidence/clients.md: mutate every site that
writes, propagates or reads the value to the constant the default
supplies; sites where nothing fails are suspects; then RE-RUN EACH
SUSPECT WITH THE DEFAULT INVERTED. If it now fails, the test was
vacuous -- the default disarmed it, fix the fixture. If it still fails
nothing, it was simply unguarded -- pre-existing, file it.

That second step is the whole method. Without it the two species are
indistinguishable (both look like "nothing failed"), and it is what
established that the vacuity class is closed at TWO rather than three.

It found two further silent sites, neither caused by the ruling:

- App::cmd_context propagates the flag and nothing tests it. Stuck
  true, `C` on a CLOSED panel decides to close it -- the panel becomes
  unopenable by its own key -- with the workspace green. Invisible
  because the command test helper builds the value it then asserts on.
  Filed as improvise-qsmp; control run proves it predates the ruling.
- render.rs propagates it into RenderModel. Stuck true is improvise-wsaw
  reintroduced one layer up, and RUST SEES NOTHING -- only the Chromium
  harness catches it. A Rust-only run of the `test` job cannot see a
  reintroduced wsaw, which is the sharpest argument on file for the
  browser job being able to fail the build.

Also marks the_terminal_constructor_inherits_the_shared_default_rather_than_setting_it
PROSPECTIVE: with three panels its two siblings already cover every
Panel::ALL member, so it cannot fail alone today. It earns its place the
way gotcha 12 describes Panel::ALL -- a fourth panel reaches it from one
entry -- and saying so stops a green tick being read as present-tense
evidence.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FC2jVn8Au7E9JPkw6bwXXH
2026-09-20 14:24:08 -07:00

56 lines
1.9 KiB
Rust

//! The terminal app's first screen carries a decision (improvise-4ibz).
//! Why this is not a rendered-frame test: `context/test-evidence/tui.md`.
use improvise::ui::app::{App, Panel};
use improvise::workbook::Workbook;
fn launched() -> App {
App::new(Workbook::new("launch"), None)
}
/// The user's ruling, 2026-09-20: the category sidebar is visible at launch in
/// the TUI as well as the browser. `src/draw.rs` draws it off this flag.
#[test]
fn the_terminal_app_launches_with_the_category_panel_open() {
let app = launched();
assert!(
app.view_state.category_panel_open,
"improvise model.improv opens with the category sidebar showing"
);
}
/// The ruling names one panel. Without this, "open everything at launch" would
/// pass the test above, and the sidebar would be three panels tall.
#[test]
fn the_other_two_panels_are_shut_at_launch() {
let app = launched();
assert!(!app.view_state.formula_panel_open, "formulas stay shut");
assert!(!app.view_state.view_panel_open, "views stay shut");
}
/// `App::new` could override the shared default without the protocol test
/// noticing. PROSPECTIVE with three panels — see the evidence file.
#[test]
fn the_terminal_constructor_inherits_the_shared_default_rather_than_setting_it() {
let shared = improvise::ui::app::ViewState::default();
let app = launched();
for panel in Panel::ALL {
let (in_app, in_default) = (open(&app.view_state, panel), open(&shared, panel));
assert_eq!(
in_app,
in_default,
"{} differs between App::new and ViewState::default: a TUI-only \
launch default is the divergence improvise-wsaw closed",
panel.name()
);
}
}
fn open(view: &improvise::ui::app::ViewState, panel: Panel) -> bool {
match panel {
Panel::Formula => view.formula_panel_open,
Panel::Category => view.category_panel_open,
Panel::View => view.view_panel_open,
}
}