test(protocol,wasm,io): displays drawn, keys composed, in the grid, page bar, panels and CSV (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:
committed by
Edward Langley
parent
7a4dc07642
commit
ba053fdaa5
@@ -106,6 +106,34 @@ mod tests {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn export_csv_writes_displays_in_every_header_and_label() {
|
||||
let mut m = Workbook::new("T");
|
||||
for cat in ["Type", "Month", "Payer"] {
|
||||
m.add_category(cat).unwrap();
|
||||
}
|
||||
m.add_item("Type", "Food").unwrap();
|
||||
m.add_item("Month", "Jan").unwrap();
|
||||
m.add_item("Payer", "Alice").unwrap();
|
||||
m.model.set_cell(
|
||||
coord(&[("Type", "Food"), ("Month", "Jan"), ("Payer", "Alice")]),
|
||||
CellValue::Number(1.0),
|
||||
);
|
||||
let ty = m.model.category_mut("Type").unwrap();
|
||||
ty.set_display("Kind");
|
||||
ty.set_item_display("Food", "Groceries");
|
||||
m.model
|
||||
.category_mut("Month")
|
||||
.unwrap()
|
||||
.set_item_display("Jan", "January");
|
||||
let payer = m.model.category_mut("Payer").unwrap();
|
||||
payer.set_display("Who");
|
||||
payer.set_item_display("Alice", "Alicia");
|
||||
let bytes = super::render_csv(&m, "Default").unwrap();
|
||||
let text = String::from_utf8(bytes).unwrap();
|
||||
assert_eq!(text, "Kind (Who=Alicia),January\nGroceries,1.00\n");
|
||||
}
|
||||
|
||||
/// Bug improvise-1cz: bare-comma joining and an ignored number format
|
||||
/// corrupted every row. Evidence: `context/test-evidence/formula-and-io.md`.
|
||||
#[test]
|
||||
|
||||
@@ -4071,6 +4071,48 @@ mod tests {
|
||||
);
|
||||
}
|
||||
|
||||
/// ADR 007: the bar shows displays and a pick composes the KEY at that index.
|
||||
#[test]
|
||||
fn picking_a_displayed_page_item_still_names_its_key() {
|
||||
let mut state = paged();
|
||||
state.grid.page_coords[1].cat_display = "Period".into();
|
||||
state.grid.page_coords[1].item_displays =
|
||||
Some(["First", "Second", "Third", "Fourth"].map(String::from).to_vec());
|
||||
let commands = click(&state, Click::PageItem { axis: 1, item: 1 });
|
||||
let [Command::Model { cmd: ModelCommand::SetPageSelection { category, item, .. }, .. }] =
|
||||
commands.as_slice()
|
||||
else {
|
||||
panic!("expected one page selection, got {commands:?}");
|
||||
};
|
||||
assert_eq!((category.as_str(), item.as_str()), ("Quarter", "Q2"));
|
||||
}
|
||||
|
||||
/// The frame shows an item under its display; hiding it names the key.
|
||||
#[test]
|
||||
fn hiding_a_displayed_row_item_names_its_key() {
|
||||
let mut state = in_mode(AppMode::Normal);
|
||||
crate::WidgetCache::apply(&mut state.basis, &published());
|
||||
state.grid.row_frame = crate::AxisFrame {
|
||||
cats: vec!["Region".into()],
|
||||
cat_displays: vec!["Sales Area".into()],
|
||||
first: 0,
|
||||
entries: vec![crate::FrameEntry::Item {
|
||||
tuple: vec!["East".into()],
|
||||
display: vec!["Eastern Seaboard".into()],
|
||||
collapsed: false,
|
||||
}],
|
||||
};
|
||||
let KeyOutcome::Local(commands) = resolve(&state, ev(KeyCode::Char('H'))) else {
|
||||
panic!("hiding resolves here");
|
||||
};
|
||||
let [Command::Model { cmd: ModelCommand::HideItem { category, item, .. }, .. }] =
|
||||
commands.as_slice()
|
||||
else {
|
||||
panic!("expected one hide, got {commands:?}");
|
||||
};
|
||||
assert_eq!((category.as_str(), item.as_str()), ("Region", "East"));
|
||||
}
|
||||
|
||||
/// A Filter axis is on the bar and offers nothing to pick (gotcha 27).
|
||||
/// Offering a menu that cannot act is worse than offering none.
|
||||
#[test]
|
||||
|
||||
@@ -883,6 +883,79 @@ mod tests {
|
||||
assert!(views[0].active, "the active view is still found by its key");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn the_grid_page_bar_and_item_rows_paint_displays() {
|
||||
use improvise_protocol::{AxisFrame, CategoryItem, FrameGroup};
|
||||
let mut client = init();
|
||||
let state = client.state_mut();
|
||||
let shown = |key: &str, display: &str| FrameEntry::Item {
|
||||
tuple: vec![key.into()],
|
||||
display: vec![display.into()],
|
||||
collapsed: false,
|
||||
};
|
||||
state.fold(&Command::Project(Projection::Grid(GridUpdate::RowFrame(
|
||||
AxisFrame {
|
||||
cats: vec!["Region".into()],
|
||||
cat_displays: vec!["Sales Area".into()],
|
||||
first: 0,
|
||||
entries: vec![
|
||||
FrameEntry::Group(FrameGroup {
|
||||
level: 0,
|
||||
depth: 0,
|
||||
name: "Coastal".into(),
|
||||
display: "Shoreline".into(),
|
||||
collapsed: false,
|
||||
}),
|
||||
shown("East", "Eastern Seaboard"),
|
||||
],
|
||||
},
|
||||
))));
|
||||
state.fold(&Command::Project(Projection::Grid(GridUpdate::ColFrame(
|
||||
AxisFrame {
|
||||
cats: vec!["_Measure".into()],
|
||||
cat_displays: vec!["_Measure".into()],
|
||||
first: 0,
|
||||
entries: vec![shown("Revenue", "Sales")],
|
||||
},
|
||||
))));
|
||||
state.fold(&Command::Project(Projection::Grid(GridUpdate::PageCoords(
|
||||
vec![PageAxis {
|
||||
cat: "Quarter".into(),
|
||||
cat_display: "Period".into(),
|
||||
selected: "Q1".into(),
|
||||
selected_display: "First".into(),
|
||||
items: Some(vec!["Q1".into(), "Q2".into()]),
|
||||
item_displays: Some(vec!["First".into(), "Second".into()]),
|
||||
}],
|
||||
))));
|
||||
state.fold(&Command::Project(Projection::CategoryTree(
|
||||
CategoryTreeUpdate::Categories(vec![CategoryRow {
|
||||
name: "Region".into(),
|
||||
display: "Sales Area".into(),
|
||||
items: vec![CategoryItem {
|
||||
name: "East".into(),
|
||||
display: "Eastern Seaboard".into(),
|
||||
}],
|
||||
axis: Axis::Row,
|
||||
}]),
|
||||
)));
|
||||
state.view.expanded_cats.insert("Region".into());
|
||||
let model = client.model();
|
||||
assert!(matches!(
|
||||
&model.rows[0],
|
||||
RenderRow::Group { label, .. } if label == "Shoreline"
|
||||
));
|
||||
assert!(matches!(
|
||||
&model.rows[1],
|
||||
RenderRow::Data { labels, .. } if labels == &vec!["Eastern Seaboard".to_string()]
|
||||
));
|
||||
assert_eq!(model.col_levels, vec![vec!["Sales".to_string()]]);
|
||||
let bar = &model.page_coords[0];
|
||||
assert_eq!((bar.cat.as_str(), bar.selected.as_str()), ("Period", "First"));
|
||||
assert_eq!(bar.cycle.as_ref().unwrap().items, vec!["First", "Second"]);
|
||||
assert_eq!(model.categories[1].label, "Eastern Seaboard");
|
||||
}
|
||||
|
||||
fn client_with_panels() -> Client {
|
||||
let mut client = init();
|
||||
client
|
||||
|
||||
@@ -884,6 +884,27 @@ mod tests {
|
||||
assert_eq!(text, GROUPED_FRAME, "\n--- got ---\n{text}\n--- end ---");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn the_frame_and_page_bar_draw_displays_not_keys() {
|
||||
let mut m = grouped_model();
|
||||
let region = m.model.category_mut("Region").unwrap();
|
||||
region.set_item_display("East", "Eastward");
|
||||
region.set_group_display("Coastal", "Bay");
|
||||
let month = m.model.category_mut("Month").unwrap();
|
||||
month.set_item_display("Jan", "Janv");
|
||||
month.set_group_display("Q1", "Qa");
|
||||
let payer = m.model.category_mut("Payer").unwrap();
|
||||
payer.set_display("Who");
|
||||
payer.set_item_display("Alice", "Alicia");
|
||||
let text = buf_text(&render(&mut m, 60, 16));
|
||||
for shown in ["Who = Alicia", "Eastward", "▼ Bay", "Janv", "▼ Qa"] {
|
||||
assert!(text.contains(shown), "{shown:?} missing:\n{text}");
|
||||
}
|
||||
for key in ["Payer", "Alice]", "East ", "Coastal", "Jan ", "Q1"] {
|
||||
assert!(!text.contains(key), "the key {key:?} was drawn:\n{text}");
|
||||
}
|
||||
}
|
||||
|
||||
/// Re-pinned for improvise-0o6x: the leading `▼ Co…` is the ONE line that
|
||||
/// moved, and its absence was the bug. context/test-evidence/tui.md.
|
||||
const GROUPED_FRAME: &str = concat!(
|
||||
|
||||
Reference in New Issue
Block a user