refactor(panels, examples): cap the remaining runs

The panel migration tests (improvise-35e) keep their claim and lose their
history; tile_bar's scroll loop keeps its algorithm note. gen-grammar's
usage block is trimmed to the one line a reader runs.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Edward Langley
2026-09-20 09:51:38 -07:00
parent f7d377b010
commit e8e7a7f1fe
6 changed files with 19 additions and 43 deletions
+5 -18
View File
@@ -1,21 +1,8 @@
//! Generate a random valid example matching a rule from `improv.pest`. //! `cargo run --example gen-grammar -- <rule_name>` — one random valid example
//! //! of a rule from `improv.pest`, seeded from the current time + PID.
//! Usage:
//! cargo run --example gen-grammar -- <rule_name> // The generator constrains the grammar to produce realistic, round-trippable
//! // output rather than degenerate minima — `context/test-evidence/tui.md`.
//! Examples:
//! cargo run --example gen-grammar -- file
//! cargo run --example gen-grammar -- category_section
//! cargo run --example gen-grammar -- bare_name
//!
//! Each invocation generates one example seeded from the current time + PID.
//!
//! The generator adds constraints beyond what the grammar requires to produce
//! realistic, round-trippable output:
//! - bare names are drawn from a word pool instead of random letters
//! - pipe_inner is never empty
//! - rest_of_line always produces at least one character
//! - repetitions (`*`) produce 1–4 items, not 0
use pest_meta::ast::{Expr, RuleType}; use pest_meta::ast::{Expr, RuleType};
use pest_meta::parser; use pest_meta::parser;
+2 -5
View File
@@ -1,8 +1,5 @@
//! Parse a `.improv` file from stdin and print the formatted result to stdout. //! Parse a `.improv` file from stdin and print the formatted result to stdout:
//! //! `cargo run --example pretty-print < file.improv`.
//! Usage:
//! cargo run --example pretty-print < file.improv
//! cargo run --example gen-grammar -- file | cargo run --example pretty-print
use std::io::Read; use std::io::Read;
+2 -3
View File
@@ -102,9 +102,8 @@ mod tests {
app app
} }
/// The panel used to read `model.formulas()[i].raw` straight off the /// `FormulaCache::formulas` must carry what `model.formulas()[i].raw`
/// model (improvise-35e); it now reads `FormulaCache::formulas`. The /// carried (improvise-35e) — `context/test-evidence/tui.md`.
/// cache must carry the same strings in the same order.
#[test] #[test]
fn the_cache_carries_what_the_widget_used_to_read_off_the_model() { fn the_cache_carries_what_the_widget_used_to_read_off_the_model() {
let app = app_with_formulas(); let app = app_with_formulas();
+2 -3
View File
@@ -9,9 +9,8 @@ use crate::ui::app::{AppMode, Panel as PanelKind};
/// Trait for panel-specific content. Implement this to create a new side panel. /// Trait for panel-specific content. Implement this to create a new side panel.
pub trait PanelContent { pub trait PanelContent {
/// Which panel this content renders. The widget compares it against /// Which panel this content renders. Compared against `AppMode::panel()`,
/// `AppMode::panel()` to decide whether to draw the panel as active, so /// so no impl restates the mode match.
/// each impl declares its identity instead of restating the mode match.
fn panel(&self) -> PanelKind; fn panel(&self) -> PanelKind;
/// Color used for the active border AND the selection highlight background. /// Color used for the active border AND the selection highlight background.
fn active_color(&self) -> Color; fn active_color(&self) -> Color;
+4 -7
View File
@@ -64,9 +64,8 @@ impl<'a> Widget for TileBar<'a> {
// Available space for tiles (after prefix) // Available space for tiles (after prefix)
let avail = area.width.saturating_sub(prefix_w); let avail = area.width.saturating_sub(prefix_w);
// Find the minimal starting index so the selected tile is fully visible. // Scroll by whole tiles: the smallest start index at which the
// We scroll by whole tiles: find the first tile to draw such that the // selected tile still fits in `avail`.
// selected tile fits within the available width.
let sel = selected_cat_idx.unwrap_or(0); let sel = selected_cat_idx.unwrap_or(0);
let mut start = 0; let mut start = 0;
loop { loop {
@@ -181,10 +180,8 @@ mod tests {
.join("\n") .join("\n")
} }
/// The tile bar used to read `view.tileable_cats(&model.category_names())` /// The cache must carry exactly the pairs the widget used to read off the
/// and `view.axis_of(cat)` off the model directly (improvise-35e). It now /// model (improvise-35e) — `context/test-evidence/tui.md`.
/// reads a `TileBarCache`, so the cache must carry exactly those pairs — a
/// divergence here is a rendering change nobody asked for.
#[test] #[test]
fn the_cache_carries_what_the_widget_used_to_read_off_the_model() { fn the_cache_carries_what_the_widget_used_to_read_off_the_model() {
let app = app_with_two_categories(); let app = app_with_two_categories();
+4 -7
View File
@@ -11,9 +11,8 @@ use crate::view::Axis;
pub struct ViewContent<'a> { pub struct ViewContent<'a> {
views: &'a ViewListCache, views: &'a ViewListCache,
/// Which view this client is on. Read off `ViewState`, not the workbook: /// Which view this client is on. Read off `ViewState`, not the workbook —
/// the active view is per-client and is deliberately absent from /// per-client, and deliberately absent from `ViewListCache` (improvise-8uz).
/// `ViewListCache` (improvise-8uz).
active_view: &'a str, active_view: &'a str,
} }
@@ -121,10 +120,8 @@ mod tests {
app app
} }
/// The axis summary used to be built from `workbook.views` plus /// `ViewSummary::axes` must reproduce what `View::categories_on` built
/// `View::categories_on` (improvise-35e); it is now built from /// (improvise-35e) — `context/test-evidence/tui.md`.
/// `ViewSummary::axes`. Same names, same order, same virtual-category
/// filtering — this asserts the two agree on a real workbook.
#[test] #[test]
fn the_cache_reproduces_the_summary_the_widget_used_to_build() { fn the_cache_reproduces_the_summary_the_widget_used_to_build() {
let app = app_with_two_views(); let app = app_with_two_views();