gridcraft/crates/ui-egui/tests/committed_text_fields.rs

82 lines
3.3 KiB
Rust

//! Text fields over workbook values (chart titles, table name) keep what the user types until they commit it.
use egui::{Event, Key, Modifiers, accesskit::Role, vec2};
use egui_kittest::kittest::Queryable as _;
use gridcraft_engine::Session;
use gridcraft_ui_egui::SheetApp;
use serde_json::json;
type Harness = egui_kittest::Harness<'static, SheetApp>;
fn harness(session: Session) -> Harness {
let mut h = egui_kittest::Harness::builder().with_size(vec2(1200.0, 800.0)).build_ui_state(
|ui, app: &mut SheetApp| {
let ctx = ui.ctx().clone();
app.logic(&ctx);
app.ui(ui);
},
SheetApp::new(session, Default::default()),
);
h.run_steps(4);
h
}
fn session() -> Session {
let mut session = Session::new();
session.new_workbook();
session.execute("range.setValues", json!({"range": "A1", "values": [["Name", "Qty"], ["a", 1], ["b", 2]]})).unwrap();
session
}
/// Clicks the field, replaces its text with `text` and presses Enter.
fn retype(h: &mut Harness, field: egui::Rect, text: &str) {
h.input_mut().events.push(Event::PointerMoved(field.center()));
h.run_steps(1);
h.get_all_by_role(Role::TextInput).find(|n| n.rect() == field).unwrap().click();
h.run_steps(2);
h.key_press_modifiers(Modifiers::COMMAND, Key::A);
h.run_steps(1);
// One keystroke per frame, as a person types: each must survive the next frame.
for c in text.chars() {
h.input_mut().events.push(Event::Text(c.to_string()));
h.run_steps(2);
}
h.key_press(Key::Enter);
h.run_steps(2);
}
#[test]
fn typing_a_chart_title_in_format_chart_area_sets_it() {
let mut session = session();
session.execute("selection.set", json!({"range": "A1:B3"})).unwrap();
let chart = session.execute("insert.chart", json!({"type": "column", "at": "D3"})).unwrap();
let id = chart["chart"].as_u64().unwrap() as u32;
let mut h = harness(session);
h.state_mut().selected_chart = Some(id);
h.state_mut().grid.pane = Some("formatChart".into());
h.run_steps(2);
h.get_by_role_and_label(Role::Button, "Chart Title").click();
h.run_steps(2);
// The pane sits on the right; the formula bar and name box are further left.
let field = h.get_all_by_role(Role::TextInput).map(|n| n.rect()).find(|r| r.left() > 850.0).unwrap();
retype(&mut h, field, "Sales");
let title = h.state().session.active().unwrap().wb.active().unwrap().charts.iter().find(|c| c.id == id).unwrap().title.clone();
assert_eq!(title.as_deref(), Some("Sales"));
}
#[test]
fn typing_a_table_name_on_the_table_design_tab_renames_the_table() {
let mut session = session();
session.execute("insert.table", json!({"range": "A1:B3", "header": true})).unwrap();
session.execute("selection.set", json!({"range": "A2"})).unwrap();
let mut h = harness(session);
h.state_mut().ui.ribbon_tab = "Table Design".into();
h.run_steps(2);
let label = h.get_by_label("Table Name:").rect();
let below_label = |r: &egui::Rect| r.top() >= label.bottom() - 2.0 && (r.left() - label.left()).abs() < 20.0;
let field = h.get_all_by_role(Role::TextInput).map(|n| n.rect()).find(below_label).unwrap();
retype(&mut h, field, "Sales");
let name = h.state().session.active().unwrap().wb.active().unwrap().tables[0].name.clone();
assert_eq!(name, "Sales");
}