use super::input::{open, saved}; use super::*; const SETTLE: std::time::Duration = std::time::Duration::from_secs(10); /// The latest value of `uno` seen so far. fn state<'a>(seen: &'a Events, uno: &str) -> Option<&'a str> { seen.states .iter() .rev() .find(|(name, _)| name == uno) .map(|(_, value)| value.as_str()) } fn run(worker: &mut Worker, doc: &Doc, id: &str, values: &[&str]) { worker .run(doc, id, values) .unwrap_or_else(|error| panic!("{id}: {error}")); } /// Lets the kernel settle a selection, as a person does. fn pause(worker: &mut Worker, doc: &Doc) { poll_until( worker, doc, &Events::default(), std::time::Duration::from_millis(500), |_| false, ); } /// A solid PNG on disk, as a file URL. pub(super) fn png(dir: &std::path::Path, name: &str, rgba: [u8; 4]) -> String { let mut bytes = Vec::new(); image::RgbaImage::from_pixel(300, 200, image::Rgba(rgba)) .write_to( &mut std::io::Cursor::new(&mut bytes), image::ImageFormat::Png, ) .expect("the png encodes"); let path = dir.join(name); std::fs::write(&path, bytes).expect("the png writes"); crate::file_url(&path) } #[test] fn page_setup_lands_and_reports() { if install().is_none() { eprintln!("SKIP: no pinned LOK build"); return; } let (dir, mut worker, doc) = open(FODT); click(&mut worker, &doc, 150, 150); run(&mut worker, &doc, "page.margins_lr", &["1270", "2540"]); run(&mut worker, &doc, "page.margins_ul", &["2540", "1270"]); run(&mut worker, &doc, "page.columns", &["2"]); run(&mut worker, &doc, "page.size", &["21000", "29700"]); run( &mut worker, &doc, "page.orientation", &["29700", "21000", "true", "0", "4"], ); let want = [ (".uno:PageLRMargin", "1270,2540"), (".uno:PageULMargin", "2540,1270"), (".uno:PageColumnType", "2"), (".uno:AttributePage", "true,0,4"), (".uno:AttributePageSize", "29700 x 21001"), ]; let seen = poll_until(&mut worker, &doc, &Events::default(), SETTLE, |seen| { want.iter() .all(|(uno, value)| state(seen, uno) == Some(*value)) }); for (uno, value) in want { assert_eq!(state(&seen, uno), Some(value), "{uno}"); } let text = saved(&dir, &mut worker, &doc, "page.fodt"); for mark in [ "fo:page-width=\"11.6929in\" fo:page-height=\"8.2681in\"", "style:print-orientation=\"landscape\"", "fo:margin-top=\"1in\" fo:margin-bottom=\"0.5in\" fo:margin-left=\"0.5in\" fo:margin-right=\"1in\"", "fo:column-count=\"2\"", ] { assert!(text.contains(mark), "{mark} lands"); } } #[test] fn headers_footers_and_sections_land() { if install().is_none() { eprintln!("SKIP: no pinned LOK build"); return; } let (dir, mut worker, doc) = open(FODT); click(&mut worker, &doc, 150, 150); run(&mut worker, &doc, "header.on", &["true"]); run(&mut worker, &doc, "footer.on", &["true"]); run(&mut worker, &doc, "header.layout", &["3"]); run(&mut worker, &doc, "field.page", &[]); run(&mut worker, &doc, "field.pages", &[]); let want = [ (".uno:SwPageHeaderItem", "true"), (".uno:SwPageFooterItem", "true"), (".uno:SwPageHeaderLayout", "3"), ]; let seen = poll_until(&mut worker, &doc, &Events::default(), SETTLE, |seen| { want.iter() .all(|(uno, value)| state(seen, uno) == Some(*value)) }); for (uno, value) in want { assert_eq!(state(&seen, uno), Some(value), "{uno}"); } run(&mut worker, &doc, "page.section", &["3", "Landscape"]); let section = poll_until(&mut worker, &doc, &seen, SETTLE, |seen| { state(seen, ".uno:PageStyleName") == Some("Landscape") }); assert_eq!(state(§ion, ".uno:PageStyleName"), Some("Landscape")); run(&mut worker, &doc, "header.on", &["false"]); let text = saved(&dir, &mut worker, &doc, "header.fodt"); for mark in [ "", "", "", "", "style:master-page-name=\"Landscape\"", "").next()) .expect("the section's page style"); assert!( !landscape.contains(""), "the section's header is off" ); } #[test] fn tables_edit_and_land() { if install().is_none() { eprintln!("SKIP: no pinned LOK build"); return; } let (dir, mut worker, doc) = open(FODT); click(&mut worker, &doc, 150, 150); worker.post_key(&doc, 0, 1029).expect("end"); worker.post_key(&doc, 13, 1280).expect("enter"); run(&mut worker, &doc, "table.insert", &["3", "2"]); let inside = poll_until(&mut worker, &doc, &Events::default(), SETTLE, |seen| { state(seen, ".uno:DeleteTable") == Some("enabled") }); assert_eq!( state(&inside, ".uno:DeleteTable"), Some("enabled"), "in a table" ); run(&mut worker, &doc, "table.repeat_heading", &[]); for (id, values) in [ ("table.row_below", vec![]), ("table.row_above", vec![]), ("table.delete_rows", vec![]), ("table.column_right", vec![]), ("table.column_left", vec![]), ("table.delete_columns", vec![]), ("table.shading", vec!["16776960"]), ("table.row_split", vec!["false"]), ("table.split", vec!["2", "false"]), ("table.select", vec![]), ("table.borders_all", vec![]), ("table.even_columns", vec![]), ("table.optimal_height", vec![]), ("table.even_rows", vec![]), ] { run(&mut worker, &doc, id, &values); } let repeated = poll_until(&mut worker, &doc, &inside, SETTLE, |seen| { state(seen, ".uno:HeadingRowsRepeat") == Some("true") }); assert_eq!(state(&repeated, ".uno:HeadingRowsRepeat"), Some("true")); let text = saved(&dir, &mut worker, &doc, "table.fodt"); for mark in [ "", "fo:background-color=\"#ffff00\"", "fo:keep-together=\"always\"", "fo:border=\"0.5pt solid #000000\"", "table:number-columns-spanned=\"2\"", ] { assert!(text.contains(mark), "{mark} lands"); } run(&mut worker, &doc, "table.borders_none", &[]); run(&mut worker, &doc, "table.merge", &[]); run(&mut worker, &doc, "table.delete", &[]); let text = saved(&dir, &mut worker, &doc, "gone.fodt"); assert!(!text.contains(" = text.split("").next()) .expect("the section's master page"); assert!( section.contains(""), "its footer differs on even pages" ); let standard = text .split("