//! A dynamic XFA form whose button adds rows past fifty lays every row out and adds the pages //! they need (XFA 3.3, "The occur element", p. 786: `max="-1"` sets no upper boundary). use std::sync::Arc; use pdfcraft_engine::Session; /// A list whose `item` row (20pt, 36 to a page) repeats without bound, `data` rows in its /// datasets, and a button that adds `add` rows in one click. fn form(add: usize, data_rows: usize) -> Vec { let data: String = (1..=data_rows).map(|i| format!("row {i}")).collect(); let datasets = if data_rows == 0 { String::new() } else { format!( r#"
{data}
"# ) }; let xdp = format!( r#" {datasets} "# ); pdfcraft_xfa::fixtures::shell(&xdp) } fn rows(s: &Session, id: pdfcraft_engine::DocId) -> usize { s.get(id).map_or(0, |d| d.form.iter().filter(|f| f.name.starts_with("qty")).count()) } #[test] fn a_button_adding_rows_past_fifty_lays_them_all_out() { let mut s = Session::new(); let id = s.open("rows.pdf", None, Arc::new(form(59, 0)), None).expect("opens"); assert_eq!(rows(&s, id), 1); assert_eq!(s.get(id).map(|d| d.info.pages.len()), Some(1)); let o = s.run_javascript(id, "", Some("more")).expect("the click runs"); assert_eq!(o.error, None); // The button row plus 60 rows of 20pt: 61 rows at 36 a page is two pages. assert_eq!(rows(&s, id), 60); assert_eq!(s.get(id).map(|d| d.info.pages.len()), Some(2)); let out = s.take_js_output(id); assert!(!out.console.iter().any(|l| l.contains("only the first")), "no row is cut: {:?}", out.console); } /// A table (`layout="table"`) placed at its own position in a positioned subform, its `item` row /// repeating with `occur max` `max`, and five rows in its data (XFA 3.3, "Tables", p. 327). fn positioned_table(max: &str) -> Vec { let data: String = (1..=5).map(|i| format!("row {i}")).collect(); let xdp = format!( r#"
{data}
"# ); pdfcraft_xfa::fixtures::shell(&xdp) } #[test] fn a_table_in_a_positioned_subform_gets_a_row_per_data_row_up_to_its_max() { let mut s = Session::new(); for (max, want) in [("-1", 5), ("3", 3)] { let id = s.open("table.pdf", None, Arc::new(positioned_table(max)), None).expect("opens"); assert_eq!(rows(&s, id), want, "occur max {max}"); } }