//! Row-level table property exceptions (`w:tblPrEx` in `w:tr`, ECMA-376 Part 1 ยง17.4.61). //! Fixtures are hand-written from the spec. use std::io::{Read, Write}; fn docx(body: &str) -> Vec { let root = r#""#; let doc = format!( r#"{body}"# ); let mut zw = zip::ZipWriter::new(std::io::Cursor::new(Vec::new())); for (name, bytes) in [("_rels/.rels", root.as_bytes()), ("word/document.xml", doc.as_bytes())] { zw.start_file(name, zip::write::SimpleFileOptions::default()).unwrap(); zw.write_all(bytes).unwrap(); } zw.finish().unwrap().into_inner() } fn document_xml(bytes: &[u8]) -> String { let mut z = zip::ZipArchive::new(std::io::Cursor::new(bytes)).unwrap(); let mut s = String::new(); z.by_name("word/document.xml").unwrap().read_to_string(&mut s).unwrap(); s } fn row(ex: &str, text: &str) -> String { format!( r#"{ex}{text}"# ) } #[test] fn row_property_exceptions_round_trip_before_the_row_properties() { let ex = r#""#; let body = format!(r#"{}{}"#, row(ex, "A"), row("", "B")); let d = wordcraft_docx::read(&docx(&body)).unwrap(); let out = wordcraft_docx::write(&d).unwrap(); let xml = document_xml(&out); assert_eq!(xml.matches("").count(), 1, "{xml}"); assert!(xml.contains(r#""#), "{xml}"); // Reading the output again gives the same exception on the first row only. let back = wordcraft_docx::read(&out).unwrap(); let t = back.body.iter().find_map(|b| b.as_table()).unwrap(); let x = t.rows[0].props.exceptions.as_ref().expect("first row keeps its exceptions"); assert_eq!(x.width, Some(150.0)); assert!(x.fixed); assert!(t.rows[1].props.exceptions.is_none()); } #[test] fn an_empty_row_exception_element_is_kept() { let body = format!(r#"{}"#, row("", "A")); let d = wordcraft_docx::read(&docx(&body)).unwrap(); let xml = document_xml(&wordcraft_docx::write(&d).unwrap()); assert!(xml.contains("") || xml.contains(""), "{xml}"); }