test(command,wasm): column width, row-header width and column group labels follow displays (improvise-cq1q.12)

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VdfEGXA7aJ6ftMsCc9PJze
This commit is contained in:
Claude (adr007-display)
2026-10-08 22:38:16 -07:00
committed by Edward Langley
parent d20c5471bd
commit 09fa78e7cd
4 changed files with 100 additions and 0 deletions
+7
View File
@@ -1796,6 +1796,13 @@ messages and the view title say (improvise-cq1q.13). A display change alone does
not move `layout_fingerprint`, so it resets no cursor; no production path changes
one yet.
`AxisFrame::cat_displays` is projected and validated, but nothing paints it yet
(the corner label has no consumer); that is a gap to close when one does, not a
bug. The new wire fields carry no `serde(default)`, so a payload from before this
change is refused: deliberate, since zero is a claim and not an absence (the same
reason as `AxisFrame::first`), and bundles are stamped so a client and host
cannot differ.
**`.improv` neither writes nor reads a display in this step.** A saved file still
carries keys only, so a display set in memory is lost on save; display persists
only with the new version literal (improvise-cq1q.5).
+21
View File
@@ -2122,3 +2122,24 @@ From Copilot's finding on #336: `item_displays` is a parallel list on a wire typ
that derives `Deserialize`. The control parses a well-formed axis first; then a
shorter list and an absent one beside `items: Some(..)` are each refused with the
"item displays" message. Without the `try_from` the same JSON parses.
### ui::viewport::tests::a_column_is_as_wide_as_the_display_its_header_draws
From the Opus review of #336: `header_level_seed` could measure keys and the
suite stayed green. The fixture's column display ("Januaryyyyy", 11) is far longer
than its key ("Jan") and the cell, so the 5-column minimum cannot hide it. Rival:
the seed reads `tuple` instead of `display`; the width is 5, not 12, and this test
fails.
### ui::viewport::tests::the_row_header_is_as_wide_as_the_display_its_rows_draw
Rival: `compute_row_header_width` reads `tuple`. That width drives `visible_cols`
on the keypress path (the improvise-gtn7.1 shape: a scroll measured elsewhere than
it is drawn), so a key measurement lets the cursor scroll to an undrawn column.
The display "Eastern Seaboard" against the key "E" gives 17, not the 4 minimum.
### render::tests::a_column_group_header_is_painted_by_its_display
Rival: `col_groups` labels a run with `g.name`. The browser test for group displays
covered row groups only; this one folds a column frame whose group "Q1" is shown as
"First quarter" and fails on the key.
@@ -253,6 +253,51 @@ mod tests {
use crate::view::Axis;
use crate::workbook::Workbook;
/// One row and one column, each item shown under a display far longer than its
/// key and than the cell, so the 5-column minimum cannot hide a key measurement.
fn long_displays() -> Workbook {
let mut wb = Workbook::new("T");
wb.add_category("Type").unwrap();
wb.add_category("Month").unwrap();
wb.add_item("Type", "E").unwrap();
wb.add_item("Month", "Jan").unwrap();
wb.model.set_cell(
CellKey::new(vec![
("Type".into(), "E".into()),
("Month".into(), "Jan".into()),
]),
CellValue::Number(1.0),
);
wb.model
.category_mut("Type")
.unwrap()
.set_item_display("E", "Eastern Seaboard");
wb.model
.category_mut("Month")
.unwrap()
.set_item_display("Jan", "Januaryyyyy");
wb
}
#[test]
fn a_column_is_as_wide_as_the_display_its_header_draws() {
let wb = long_displays();
let layout = GridLayout::new(&wb.model, wb.active_view());
let plan = FormatPlan::of(&wb.model, wb.active_view());
let widths = compute_col_widths(&wb.model, &layout, &plan);
assert_eq!(widths, vec!["Januaryyyyy".len() as u16 + 1]);
}
#[test]
fn the_row_header_is_as_wide_as_the_display_its_rows_draw() {
let wb = long_displays();
let layout = GridLayout::new(&wb.model, wb.active_view());
assert_eq!(
compute_row_header_width(&layout),
"Eastern Seaboard".len() as u16 + 1
);
}
/// Q1 = {Jan, Feb} collapsed, Q2 = {Apr}; F0 = Revenue and F(i) = F(i-1) twice.
fn folded_chain() -> Workbook {
let mut wb = Workbook::new("T");
@@ -959,6 +959,33 @@ mod tests {
assert_eq!(model.categories[1].label, "Eastern Seaboard");
}
#[test]
fn a_column_group_header_is_painted_by_its_display() {
use improvise_protocol::{AxisFrame, FrameGroup};
let mut client = init();
let state = client.state_mut();
state.fold(&Command::Project(Projection::Grid(GridUpdate::ColFrame(
AxisFrame {
cats: vec!["Month".into()],
cat_displays: vec!["Period".into()],
first: 0,
entries: vec![
FrameEntry::Group(FrameGroup {
level: 0,
depth: 0,
name: "Q1".into(),
display: "First quarter".into(),
collapsed: false,
}),
item("Jan"),
],
},
))));
let groups = client.model().col_groups;
assert_eq!(groups.len(), 1);
assert_eq!(groups[0].label.as_deref(), Some("First quarter"));
}
fn client_with_panels() -> Client {
let mut client = init();
client