//! Copy/cut route rich tables to the host without a later egui text write replacing them.
use std::cell::RefCell;
use std::rc::Rc;
use egui::{Event, OutputCommand};
use gridcraft_engine::Session;
use gridcraft_ui_egui::{Services, SheetApp};
use serde_json::json;
fn harness(services: Services) -> egui_kittest::Harness<'static, SheetApp> {
let mut session = Session::new();
session.new_workbook();
session.execute("range.setValues", json!({"range": "A1", "values": [["Name", "Score"], ["Ada", 42]]})).unwrap();
session.execute("selection.set", json!({"range": "A1:B2"})).unwrap();
let mut h = egui_kittest::Harness::builder().with_size(egui::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, services),
);
h.run_steps(4);
h
}
#[test]
fn copy_and_cut_publish_html_and_text_without_overwriting_rich_clipboard() {
for event in [Event::Copy, Event::Cut] {
let calls = Rc::new(RefCell::new(Vec::new()));
let received = calls.clone();
let mut h = harness(Services {
copy_html: Some(Box::new(move |html, text| {
received.borrow_mut().push((html.to_string(), text.to_string()));
Ok(())
})),
..Default::default()
});
h.input_mut().events.push(event.clone());
h.step();
let calls = calls.borrow();
assert_eq!(calls.len(), 1);
assert!(calls[0].0.contains("
"#.to_string()))),
..Default::default()
});
h.state_mut().run("selection.set", json!({"cell": "D5"})).unwrap();
h.input_mut().events.push(Event::Paste("Rp10,000.00".into()));
h.run_steps(2);
let value = h.state().session.active().and_then(|d| d.wb.active().map(|s| s.value(gridcraft_engine::core::CellRef::new(4, 3))));
assert_eq!(value, Some(gridcraft_engine::core::Value::number(10000.0)));
}
#[test]
fn copying_multiple_areas_copies_lined_up_areas_and_explains_the_rest() {
// Issue #348: lined-up areas copy as one block; others get Excel's message instead of nothing.
let mut h = harness(Services::default());
h.state_mut().session.execute("selection.set", json!({"range": "B1:B2,A1:A2"})).unwrap();
h.input_mut().events.push(Event::Copy);
h.step();
assert!(h.output().platform_output.commands.iter().any(|c| matches!(c, OutputCommand::CopyText(text) if text == "Name\tScore\nAda\t42\n")));
assert!(h.state().message.is_none());
assert_eq!(h.state().session.clipboard.as_ref().map(|c| c.areas.len()), Some(2));
h.state_mut().session.execute("selection.set", json!({"range": "A1,B2"})).unwrap();
h.input_mut().events.push(Event::Copy);
h.step();
assert!(!h.output().platform_output.commands.iter().any(|c| matches!(c, OutputCommand::CopyText(_))));
assert_eq!(h.state().message.as_ref().map(|(_, text)| text.as_str()), Some("This action won't work on multiple selections."));
assert_eq!(h.state().session.clipboard.as_ref().map(|c| c.areas.len()), Some(2), "the earlier copy stays");
}