#![cfg(feature = "docx")]
use std::io::{Read, Write};
use rwml::{
Block, DocGridType, Document, FieldEvaluationReason, FieldEvaluationReasonCount, FieldKind,
FieldKindCount, FieldRole, FieldUnsupportedReason, PageNumberFormat, TextDirection,
};
fn docx_fixture(parts: &[(&str, &str)]) -> Vec<u8> {
let mut out = Vec::new();
{
let cursor = std::io::Cursor::new(&mut out);
let mut zip = zip::ZipWriter::new(cursor);
let opt = zip::write::SimpleFileOptions::default();
for (name, body) in parts {
zip.start_file(*name, opt).unwrap();
zip.write_all(body.as_bytes()).unwrap();
}
zip.finish().unwrap();
}
out
}
fn unzip_parts(bytes: &[u8]) -> std::collections::BTreeMap<String, Vec<u8>> {
let mut zip = zip::ZipArchive::new(std::io::Cursor::new(bytes.to_vec())).unwrap();
let mut parts = std::collections::BTreeMap::new();
for i in 0..zip.len() {
let mut file = zip.by_index(i).unwrap();
let mut buf = Vec::new();
file.read_to_end(&mut buf).unwrap();
parts.insert(file.name().to_string(), buf);
}
parts
}
fn model_simple_field_reason_hints(
doc: &Document,
instruction_filter: impl Fn(&str) -> bool,
) -> Vec<(String, Option<FieldUnsupportedReason>)> {
doc.model()
.blocks
.iter()
.filter_map(|block| match block {
Block::Paragraph(paragraph) => Some(paragraph),
_ => None,
})
.flat_map(|paragraph| paragraph.runs.iter())
.filter_map(|run| match &run.field {
FieldRole::Simple { instruction } if instruction_filter(instruction) => {
Some((instruction.clone(), run.field_unsupported_reason))
}
_ => None,
})
.collect()
}
fn field_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:fldSimple w:instr=" PAGE "><w:r><w:t>1</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" TOC \o "1-3" "><w:r><w:t>Contents</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" REF Figure1 "><w:r><w:t>Figure 1</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" HYPERLINK "https://example.com" "><w:r><w:t>Example</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" CUSTOM value "><w:r><w:t>custom</w:t></w:r></w:fldSimple></w:p><w:p><w:r><w:fldChar w:fldCharType=" begin "/></w:r><w:r><w:instrText> FILENAME \p </w:instrText></w:r><w:r><w:fldChar w:fldCharType=" separate "/></w:r><w:r><w:t>report.docx</w:t></w:r><w:r><w:fldChar w:fldCharType=" end "/></w:r></w:p></w:body></w:document>"#,
),
])
}
#[cfg(feature = "render")]
fn hyperlink_gap_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:fldSimple w:instr=" HYPERLINK "https://example.com" \o "tip" "><w:r><w:t>Example</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" HYPERLINK "https://example.com "><w:r><w:t>Cached link</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" HYPERLINK \o "tip" "><w:r><w:t>Cached tooltip-only link</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" HYPERLINK "https://example.com" extra "><w:r><w:t>Cached trailing link</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn revision_wrapped_field_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:fldSimple w:instr=" MERGEFIELD DirectName "><w:r><w:t>direct name</w:t></w:r></w:fldSimple></w:p><w:ins w:id="20" w:author="Editor"><w:p><w:fldSimple w:instr=" MERGEFIELD InsertedName "><w:r><w:t>inserted name</w:t></w:r></w:fldSimple></w:p></w:ins><w:moveTo w:id="21" w:author="Editor"><w:p><w:fldSimple w:instr=" MERGEFIELD MovedToName "><w:r><w:t>moved-to name</w:t></w:r></w:fldSimple></w:p></w:moveTo><w:del w:id="22" w:author="Editor"><w:p><w:fldSimple w:instr=" CUSTOM DeletedField "><w:r><w:delText>deleted field</w:delText></w:r></w:fldSimple></w:p></w:del><w:moveFrom w:id="23" w:author="Editor"><w:p><w:fldSimple w:instr=" CUSTOM MovedFromField "><w:r><w:delText>moved-from field</w:delText></w:r></w:fldSimple></w:p></w:moveFrom></w:body></w:document>"#,
),
])
}
fn alternate_content_field_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"><w:body><w:p><w:r><mc:AlternateContent><mc:Choice Requires="wps"><w:fldSimple w:instr=" MERGEFIELD AltClient "><w:r><w:t>Choice Client</w:t></w:r></w:fldSimple></mc:Choice><mc:Fallback><w:fldSimple w:instr=" MERGEFIELD AltClient "><w:r><w:t>Fallback Client</w:t></w:r></w:fldSimple></mc:Fallback></mc:AlternateContent></w:r></w:p></w:body></w:document>"#,
),
])
}
fn page_field_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:pPr><w:sectPr><w:type w:val="nextPage"/><w:pgNumType w:start="4" w:fmt="decimalZero"/></w:sectPr></w:pPr></w:p><w:p><w:fldSimple w:instr=" PAGE "><w:r><w:t>stale restart decimal zero</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" PAGE \* Arabic "><w:r><w:t>stale restart arabic</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" PAGE \* CardText \* Upper "><w:r><w:t>stale restart card upper</w:t></w:r></w:fldSimple></w:p><w:p><w:r><w:t>Visible before ambiguous break.</w:t><w:br w:type="page"/></w:r></w:p><w:p><w:fldSimple w:instr=" PAGE "><w:r><w:t>cached ambiguous page</w:t></w:r></w:fldSimple></w:p><w:p><w:r><w:lastRenderedPageBreak/><w:t>Rendered page lead.</w:t></w:r></w:p><w:p><w:r><w:fldChar w:fldCharType="begin"/></w:r><w:r><w:instrText> PAGE \* roman </w:instrText></w:r><w:r><w:fldChar w:fldCharType="separate"/></w:r><w:r><w:t>stale rendered roman page</w:t></w:r><w:r><w:fldChar w:fldCharType="end"/></w:r></w:p></w:body></w:document>"#,
),
])
}
#[cfg(feature = "render")]
fn page_unsupported_switch_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:fldSimple w:instr=" PAGE \* Unknown "><w:r><w:t>cached bad page</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn page_field_visible_intro_section_page_number_restart_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:r><w:t>Cover text can auto-paginate before the section break.</w:t></w:r></w:p><w:p><w:pPr><w:sectPr><w:type w:val="nextPage"/><w:pgNumType w:start="7"/></w:sectPr></w:pPr></w:p><w:p><w:fldSimple w:instr=" PAGE "><w:r><w:t>stale restarted current page</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn page_field_continuous_section_restart_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:pPr><w:sectPr><w:type w:val="continuous"/><w:pgNumType w:start="5"/></w:sectPr></w:pPr></w:p><w:p><w:fldSimple w:instr=" PAGE "><w:r><w:t>stale continuous restart</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn page_ref_relative_untrusted_field_trusted_target_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:r><w:t>Visible intro can auto-paginate.</w:t><w:br w:type="page"/></w:r></w:p><w:p><w:fldSimple w:instr=" PAGEREF Later \p "><w:r><w:t>stale relative ref</w:t></w:r></w:fldSimple></w:p><w:p><w:r><w:lastRenderedPageBreak/><w:t>Later page content.</w:t></w:r></w:p><w:p><w:bookmarkStart w:id="1" w:name="Later"/><w:r><w:t>Target heading</w:t></w:r><w:bookmarkEnd w:id="1"/></w:p></w:body></w:document>"#,
),
])
}
fn page_field_page_break_before_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:r><w:t>Intro text before the break-before paragraph.</w:t></w:r></w:p><w:p><w:pPr><w:pageBreakBefore/></w:pPr><w:fldSimple w:instr=" PAGE \* Arabic "><w:r><w:t>stale break-before page</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn empty_section_type_page_accounting_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:pPr><w:sectPr><w:type/></w:sectPr></w:pPr></w:p><w:p><w:bookmarkStart w:id="7" w:name="DefaultTyped"/><w:r><w:t>Default typed target</w:t></w:r><w:bookmarkEnd w:id="7"/></w:p><w:p><w:fldSimple w:instr=" PAGE "><w:r><w:t>stale page</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" PAGEREF DefaultTyped \h "><w:r><w:t>stale ref</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn disabled_page_break_before_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:pPr><w:pageBreakBefore w:val="0"/></w:pPr><w:r><w:t>No forced break.</w:t></w:r></w:p></w:body></w:document>"#,
),
])
}
fn wrapped_page_field_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"><w:body><w:p><w:r><w:t>Page one text.</w:t></w:r></w:p><w:ins><w:p><w:r><w:lastRenderedPageBreak/><w:t>Inserted page two.</w:t></w:r></w:p></w:ins><w:ins><w:p><w:r><w:fldChar w:fldCharType="begin"/></w:r><w:r><w:instrText> PAGE \* Arabic </w:instrText></w:r><w:r><w:fldChar w:fldCharType="separate"/></w:r><w:r><w:t>stale inserted page</w:t></w:r><w:r><w:fldChar w:fldCharType="end"/></w:r></w:p></w:ins><w:p><w:r><mc:AlternateContent><mc:Choice Requires="wps"><w:lastRenderedPageBreak/></mc:Choice><mc:Fallback><w:lastRenderedPageBreak/></mc:Fallback></mc:AlternateContent></w:r><w:r><w:t>Alternate page three.</w:t></w:r></w:p><w:p><w:fldSimple w:instr=" PAGE \* Ordinal "><w:r><w:t>stale alternate page</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn merge_field_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:fldSimple w:instr=" MERGEFIELD client-name \* MERGEFORMAT "><w:r><w:t>Acme</w:t></w:r></w:fldSimple></w:p><w:p><w:r><w:fldChar w:fldCharType="begin"/></w:r><w:r><w:instrText> MERGEFIELD "project-name" \* MERGEFORMAT </w:instrText></w:r><w:r><w:fldChar w:fldCharType="separate"/></w:r><w:r><w:t>Roadmap</w:t></w:r><w:r><w:fldChar w:fldCharType="end"/></w:r></w:p></w:body></w:document>"#,
),
])
}
fn sequence_field_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:fldSimple w:instr=" SEQ Figure "><w:r><w:t>stale figure one</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" SEQ Figure "><w:r><w:t>stale figure two</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" SEQ Figure \r 7 "><w:r><w:t>stale figure reset</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" SEQ Figure \c "><w:r><w:t>stale figure current</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" SEQ Figure \h "><w:r><w:t>stale hidden figure</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" SEQ Figure "><w:r><w:t>stale figure after hidden</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" SEQ Figure \r -1 "><w:r><w:t>cached invalid reset</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" SEQ Figure "><w:r><w:t>stale figure after invalid reset</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" SEQ Appendix \* roman "><w:r><w:t>stale appendix roman</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" SEQ Appendix \r 31 \* Hex "><w:r><w:t>stale appendix hex</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn sequence_heading_reset_field_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/><Override PartName="/word/styles.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/_rels/document.xml.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rIdStyles" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles" Target="styles.xml"/></Relationships>"#,
),
(
"word/styles.xml",
r#"<w:styles xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:style w:type="paragraph" w:styleId="Heading1"><w:name w:val="heading 1"/></w:style></w:styles>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:pPr><w:pStyle w:val="Heading1"/></w:pPr><w:r><w:t>Chapter One</w:t></w:r></w:p><w:p><w:fldSimple w:instr=" SEQ Figure \s 1 "><w:r><w:t>stale chapter one figure</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" SEQ Figure "><w:r><w:t>stale chapter one followup</w:t></w:r></w:fldSimple></w:p><w:p><w:pPr><w:pStyle w:val="Heading1"/></w:pPr><w:r><w:t>Chapter Two</w:t></w:r></w:p><w:p><w:fldSimple w:instr=" SEQ Figure \s 1 "><w:r><w:t>stale chapter two figure</w:t></w:r></w:fldSimple></w:p><w:p><w:r><w:fldChar w:fldCharType="begin"/></w:r><w:r><w:instrText> SEQ Figure \s1 \* roman </w:instrText></w:r><w:r><w:fldChar w:fldCharType="separate"/></w:r><w:r><w:t>stale chapter two roman</w:t></w:r><w:r><w:fldChar w:fldCharType="end"/></w:r></w:p></w:body></w:document>"#,
),
])
}
fn sequence_heading_paragraph_reset_field_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/><Override PartName="/word/styles.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/_rels/document.xml.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rIdStyles" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles" Target="styles.xml"/></Relationships>"#,
),
(
"word/styles.xml",
r#"<w:styles xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:style w:type="paragraph" w:styleId="Heading1"><w:name w:val="heading 1"/></w:style></w:styles>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:pPr><w:pStyle w:val="Heading1"/></w:pPr><w:r><w:t>Chapter One Figure </w:t></w:r><w:fldSimple w:instr=" SEQ Figure \s 1 "><w:r><w:t>stale heading one figure</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" SEQ Figure \s 1 "><w:r><w:t>stale chapter one followup</w:t></w:r></w:fldSimple></w:p><w:p><w:pPr><w:pStyle w:val="Heading1"/></w:pPr><w:r><w:t>Chapter Two Figure </w:t></w:r><w:fldSimple w:instr=" SEQ Figure \s 1 "><w:r><w:t>stale heading two figure</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn sequence_heading_property_revision_reset_field_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/><Override PartName="/word/styles.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/_rels/document.xml.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rIdStyles" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles" Target="styles.xml"/></Relationships>"#,
),
(
"word/styles.xml",
r#"<w:styles xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:style w:type="paragraph" w:styleId="Heading1"><w:name w:val="heading 1"/></w:style></w:styles>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:fldSimple w:instr=" SEQ Figure \s 1 "><w:r><w:t>stale before old heading</w:t></w:r></w:fldSimple></w:p><w:p><w:pPr><w:pPrChange w:id="9" w:author="Reviewer"><w:pPr><w:pStyle w:val="Heading1"/></w:pPr></w:pPrChange></w:pPr><w:r><w:t>Former heading only</w:t></w:r></w:p><w:p><w:fldSimple w:instr=" SEQ Figure \s 1 "><w:r><w:t>stale after old heading</w:t></w:r></w:fldSimple></w:p><w:p><w:pPr><w:pStyle w:val="Heading1"/></w:pPr><w:r><w:t>Current Heading</w:t></w:r></w:p><w:p><w:fldSimple w:instr=" SEQ Figure \s 1 "><w:r><w:t>stale after current heading</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn document_info_field_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:fldSimple w:instr=" DATE \@ "yyyy-MM-dd" "><w:r><w:t>2026-06-24</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" TIME \@ "HH:mm" "><w:r><w:t>14:35</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" AUTHOR \* MERGEFORMAT "><w:r><w:t>Hyunjo Jung</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" DOCPROPERTY "Company" "><w:r><w:t>Example Co.</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" NUMPAGES "><w:r><w:t>12</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" EDITTIME "><w:r><w:t>42</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" DOCPROPERTY "Broken Name "><w:r><w:t>cached broken property</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn file_size_switch_field_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:fldSimple w:instr=" FILESIZE "><w:r><w:t>stale bytes</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" FILESIZE \k "><w:r><w:t>stale kilobytes</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" FILESIZE \m "><w:r><w:t>stale megabytes</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn user_info_field_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:fldSimple w:instr=" USERNAME "><w:r><w:t>cached user name</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" USERINITIALS "><w:r><w:t>cached initials</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" USERADDRESS "><w:r><w:t>cached address</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" USERNAME "Casey Reviewer" \* Upper "><w:r><w:t>stale override name</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" USERINITIALS "cr" \* Upper "><w:r><w:t>stale override initials</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" USERADDRESS "Review desk, Seoul" \* Upper "><w:r><w:t>stale override address</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" USERNAME Casey Reviewer \* Upper "><w:r><w:t>stale unquoted name</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" USERINITIALS casey reviewer \* Upper "><w:r><w:t>stale unquoted initials</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" USERADDRESS Review desk Seoul \* Upper "><w:r><w:t>stale unquoted address</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn user_info_compact_format_field_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:fldSimple w:instr=" USERNAME "Casey Reviewer" \*Upper "><w:r><w:t>stale compact user</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn document_info_package_properties_field_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/><Override PartName="/word/settings.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.settings+xml"/><Override PartName="/docProps/core.xml" ContentType="application/vnd.openxmlformats-package.core-properties+xml"/><Override PartName="/docProps/custom.xml" ContentType="application/vnd.openxmlformats-officedocument.custom-properties+xml"/><Override PartName="/docProps/app.xml" ContentType="application/vnd.openxmlformats-officedocument.extended-properties+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/><Relationship Id="rIdCore" Type="http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties" Target="docProps/core.xml"/><Relationship Id="rIdCustom" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/custom-properties" Target="docProps/custom.xml"/><Relationship Id="rIdApp" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties" Target="docProps/app.xml"/></Relationships>"#,
),
(
"docProps/core.xml",
r#"<cp:coreProperties xmlns:cp="http://schemas.openxmlformats.org/package/2006/metadata/core-properties" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dcterms="http://purl.org/dc/terms/"><dc:title>Quarter Plan</dc:title><dc:subject>Launch</dc:subject><dc:creator>Hyunjo Jung</dc:creator><dc:description>Field coverage</dc:description><cp:keywords>rwml,fields</cp:keywords><cp:category>Operations</cp:category><cp:contentStatus>Draft</cp:contentStatus><cp:lastModifiedBy>Reviewer</cp:lastModifiedBy><dcterms:created>2026-06-01T02:03:04Z</dcterms:created><dcterms:modified>2026-06-02T03:04:05Z</dcterms:modified><cp:lastPrinted>2026-06-03T04:05:06Z</cp:lastPrinted><cp:version>1.2</cp:version></cp:coreProperties>"#,
),
(
"docProps/custom.xml",
r#"<Properties xmlns="http://schemas.openxmlformats.org/officeDocument/2006/custom-properties" xmlns:vt="http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes"><property fmtid="{D5CDD505-2E9C-101B-9397-08002B2CF9AE}" pid="2" name=" Client Name "><vt:lpwstr>acme launch</vt:lpwstr></property><property fmtid="{D5CDD505-2E9C-101B-9397-08002B2CF9AE}" pid="3" name="RiskScore"><vt:i4>7</vt:i4></property><property fmtid="{D5CDD505-2E9C-101B-9397-08002B2CF9AE}" pid="4" name="Review Date"><vt:filetime>2026-06-15T09:10:11Z</vt:filetime></property></Properties>"#,
),
(
"docProps/app.xml",
r#"<Properties xmlns="http://schemas.openxmlformats.org/officeDocument/2006/extended-properties"><Application>rwml field engine</Application><AppVersion>16.0000</AppVersion><Template>Normal.dotm</Template><TotalTime>42</TotalTime><Pages>12</Pages><Words>321</Words><Characters>2048</Characters><CharactersWithSpaces>2500</CharactersWithSpaces><Company>Example Co</Company><Manager>Document Lead</Manager><HyperlinkBase>https://docs.example/base/</HyperlinkBase><DocSecurity>4</DocSecurity><LinksUpToDate>true</LinksUpToDate></Properties>"#,
),
(
"word/settings.xml",
r#"<w:settings xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:docVars><w:docVar w:name=" ClientCode " w:val="alpha-42"/></w:docVars></w:settings>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:fldSimple w:instr=" TITLE "><w:r><w:t>stale title</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" AUTHOR "><w:r><w:t>stale author</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" INFO "Title" \* Upper "><w:r><w:t>stale info title</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" DOCPROPERTY "Subject" \* Upper "><w:r><w:t>stale subject</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" DOCPROPERTY "Comments" \* FirstCap "><w:r><w:t>stale comments</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" DOCPROPERTY Keywords "><w:r><w:t>stale keywords</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" DOCPROPERTY Category "><w:r><w:t>stale category</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" INFO "ContentStatus" "><w:r><w:t>stale content status</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" DOCPROPERTY Version "><w:r><w:t>stale version</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" DOCPROPERTY "Client Name" \* Caps "><w:r><w:t>stale client</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" DOCPROPERTY RiskScore "><w:r><w:t>stale score</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" DOCVARIABLE ClientCode \* Upper "><w:r><w:t>stale variable</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" CREATEDATE \@ "dddd, MMMM d, yyyy" "><w:r><w:t>stale created date</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" SAVEDATE \@ "MMM dd, yyyy HH:mm:ss" "><w:r><w:t>stale saved date</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" PRINTDATE \@ "yy-M-d h:mm AM/PM" "><w:r><w:t>stale print date</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" NUMPAGES "><w:r><w:t>stale pages</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" NUMWORDS "><w:r><w:t>stale words</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" NUMCHARS "><w:r><w:t>stale chars</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" EDITTIME "><w:r><w:t>stale edit time</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" TEMPLATE \* Upper "><w:r><w:t>stale template</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" DOCPROPERTY Pages "><w:r><w:t>stale docproperty pages</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" INFO "Words" "><w:r><w:t>stale info words</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" DOCPROPERTY CharactersWithSpaces "><w:r><w:t>stale chars with spaces</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" INFO "TotalTime" "><w:r><w:t>stale info total time</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" DOCPROPERTY Company \* Upper "><w:r><w:t>stale company</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" INFO "Manager" "><w:r><w:t>stale manager</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" LASTSAVEDBY "><w:r><w:t>stale editor</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" CATEGORY \* Upper "><w:r><w:t>stale direct category</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" CONTENTSTATUS "><w:r><w:t>stale direct content status</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" VERSION "><w:r><w:t>stale direct version</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" DOCPROPERTY HyperlinkBase "><w:r><w:t>stale hyperlink base</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" INFO "DocSecurity" "><w:r><w:t>stale doc security</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" DOCPROPERTY LinksUpToDate "><w:r><w:t>stale links up to date</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" CREATOR \* Upper "><w:r><w:t>stale creator alias</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" DESCRIPTION \* Upper "><w:r><w:t>stale description alias</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" KEYWORD \* Upper "><w:r><w:t>stale keyword alias</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" LASTMODIFIEDBY \* Upper "><w:r><w:t>stale modified alias</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" APPLICATION \* Upper "><w:r><w:t>stale application</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" APPVERSION "><w:r><w:t>stale app version</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" MANAGER \* Upper "><w:r><w:t>stale direct manager</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" COMPANY \* Upper "><w:r><w:t>stale direct company</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" HYPERLINKBASE "><w:r><w:t>stale direct hyperlink base</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" DOCSECURITY "><w:r><w:t>stale direct doc security</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" LINKSUPTODATE "><w:r><w:t>stale direct links up to date</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" DOCPROPERTY "Review Date" \@ "MMM d, yyyy" "><w:r><w:t>stale review date</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" FILESIZE "><w:r><w:t>stale file size</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn document_info_compact_property_format_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/><Override PartName="/docProps/custom.xml" ContentType="application/vnd.openxmlformats-officedocument.custom-properties+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/><Relationship Id="rIdCustom" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/custom-properties" Target="docProps/custom.xml"/></Relationships>"#,
),
(
"docProps/custom.xml",
r#"<Properties xmlns="http://schemas.openxmlformats.org/officeDocument/2006/custom-properties" xmlns:vt="http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes"><property fmtid="{D5CDD505-2E9C-101B-9397-08002B2CF9AE}" pid="2" name=" Client Name "><vt:lpwstr>acme launch</vt:lpwstr></property></Properties>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:fldSimple w:instr=" DOCPROPERTY "Client Name" \*Caps "><w:r><w:t>stale compact property</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn document_info_unquoted_multi_token_names_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/><Override PartName="/word/settings.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.settings+xml"/><Override PartName="/docProps/custom.xml" ContentType="application/vnd.openxmlformats-officedocument.custom-properties+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/><Relationship Id="rIdCustom" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/custom-properties" Target="docProps/custom.xml"/></Relationships>"#,
),
(
"docProps/custom.xml",
r#"<Properties xmlns="http://schemas.openxmlformats.org/officeDocument/2006/custom-properties" xmlns:vt="http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes"><property fmtid="{D5CDD505-2E9C-101B-9397-08002B2CF9AE}" pid="2" name=" Client Name "><vt:lpwstr>acme launch</vt:lpwstr></property></Properties>"#,
),
(
"word/settings.xml",
r#"<w:settings xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:docVars><w:docVar w:name=" Client Code " w:val="alpha-42"/></w:docVars></w:settings>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:fldSimple w:instr=" DOCPROPERTY Client Name \* Caps "><w:r><w:t>stale client</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" DOCVARIABLE Client Code \* Upper "><w:r><w:t>stale variable</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn document_info_compact_variable_format_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/><Override PartName="/word/settings.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.settings+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/settings.xml",
r#"<w:settings xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:docVars><w:docVar w:name=" ClientCode " w:val="alpha-42"/></w:docVars></w:settings>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:fldSimple w:instr=" DOCVARIABLE ClientCode \*Upper "><w:r><w:t>stale compact variable</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn document_info_compact_date_format_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/><Override PartName="/docProps/core.xml" ContentType="application/vnd.openxmlformats-package.core-properties+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/><Relationship Id="rIdCore" Type="http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties" Target="docProps/core.xml"/></Relationships>"#,
),
(
"docProps/core.xml",
r#"<cp:coreProperties xmlns:cp="http://schemas.openxmlformats.org/package/2006/metadata/core-properties" xmlns:dcterms="http://purl.org/dc/terms/"><dcterms:created>2026-06-01T02:03:04Z</dcterms:created></cp:coreProperties>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:fldSimple w:instr=" CREATEDATE \@"yyyy-MM-dd" "><w:r><w:t>stale compact date</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn document_info_unquoted_date_picture_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/><Override PartName="/docProps/core.xml" ContentType="application/vnd.openxmlformats-package.core-properties+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/><Relationship Id="rIdCore" Type="http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties" Target="docProps/core.xml"/></Relationships>"#,
),
(
"docProps/core.xml",
r#"<cp:coreProperties xmlns:cp="http://schemas.openxmlformats.org/package/2006/metadata/core-properties" xmlns:dcterms="http://purl.org/dc/terms/"><dcterms:created>2026-06-01T02:03:04Z</dcterms:created></cp:coreProperties>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:fldSimple w:instr=" CREATEDATE \@ MMMM d, yyyy \* Upper "><w:r><w:t>stale unquoted date picture</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn dynamic_field_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:fldSimple w:instr=" = (2 + 3) * 4 "><w:r><w:t>stale formula</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" = 10 / 4 \# "0.00" "><w:r><w:t>stale formatted formula</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" IF 1 = 1 "yes" "no" "><w:r><w:t>stale true</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" IF "Tokyo" <> "Tokyo" "yes" "no" "><w:r><w:t>stale false</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" IF 100>=99 "big" "small" "><w:r><w:t>stale compact</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" COMPARE 5 > 3 "><w:r><w:t>stale compare true</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" COMPARE "98512" = "985*" "><w:r><w:t>stale compare wildcard</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" COMPARE "AB" <> "A?" "><w:r><w:t>stale compare false</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" QUOTE "literal" "><w:r><w:t>literal</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" FILLIN "Client?" "><w:r><w:t>Acme</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" ASK ClientCode "Client code?" "><w:r><w:t>cached ask</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" SET ClientName "Acme" "><w:r><w:t>cached set</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" REF ClientName \* Upper "><w:r><w:t>stale set ref</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" SET ClientTier "Gold" \* MERGEFORMAT "><w:r><w:t>cached formatted set</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" REF ClientTier "><w:r><w:t>stale formatted set ref</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" SET ClientCode Client-42 "><w:r><w:t>cached unsupported set</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" NEXT "><w:r><w:t>cached next</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" NEXTIF 1 = 1 "><w:r><w:t>cached nextif</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" SKIPIF 1 = 0 "><w:r><w:t>cached skipif</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" IF 1e2 = 100 "scientific" "bad" "><w:r><w:t>stale scientific if</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" COMPARE 1e309 > 0 "><w:r><w:t>cached nonfinite compare</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" NEXTIF City = "Tokyo" "><w:r><w:t>cached unsupported nextif</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" FILLIN "broken prompt "><w:r><w:t>cached broken fillin</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" NEXTIF 1 = "><w:r><w:t>cached broken nextif</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn set_backed_comparison_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:fldSimple w:instr=" SET ClientTier "Gold" "><w:r><w:t>cached set</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" IF ClientTier = "Gold" "ship" "hold" "><w:r><w:t>stale set if</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" COMPARE ClientTier = "Gold" "><w:r><w:t>stale set compare</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" IF MissingTier = "Gold" "ship" "hold" "><w:r><w:t>cached missing if</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" NEXTIF ClientTier = "Gold" "><w:r><w:t>cached nextif</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" SKIPIF ClientTier <> "Gold" "><w:r><w:t>cached skipif</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn set_backed_numeric_comparison_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:fldSimple w:instr=" SET ClientTotal 42 "><w:r><w:t>cached numeric set</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" IF ClientTotal = 42 "match" "miss" "><w:r><w:t>stale numeric if</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" COMPARE ClientTotal >= 40 "><w:r><w:t>stale numeric compare</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" NEXTIF ClientTotal = 42 "><w:r><w:t>cached numeric nextif</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" SKIPIF ClientTotal < 40 "><w:r><w:t>cached numeric skipif</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" SET ClientTier "Gold" "><w:r><w:t>cached text set</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" COMPARE ClientTier = "G*" "><w:r><w:t>stale text compare</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn bookmark_backed_comparison_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:bookmarkStart w:id="7" w:name="InvoiceTier"/><w:r><w:t>Gold</w:t></w:r><w:bookmarkEnd w:id="7"/></w:p><w:p><w:bookmarkStart w:id="8" w:name="InvoiceTotal"/><w:r><w:t>42</w:t></w:r><w:bookmarkEnd w:id="8"/></w:p><w:p><w:fldSimple w:instr=" IF InvoiceTier = "Gold" "ship" "hold" "><w:r><w:t>stale bookmark if</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" COMPARE InvoiceTier = "G*" "><w:r><w:t>stale bookmark compare</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" IF InvoiceTotal >= 40 "match" "miss" "><w:r><w:t>stale numeric bookmark if</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" COMPARE InvoiceTotal < 40 "><w:r><w:t>stale numeric bookmark compare</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" IF MissingTier = "Gold" "ship" "hold" "><w:r><w:t>cached missing bookmark if</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" NEXTIF InvoiceTier = "Gold" "><w:r><w:t>cached bookmark nextif</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" SKIPIF InvoiceTotal < 40 "><w:r><w:t>cached bookmark skipif</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn set_backed_formula_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:fldSimple w:instr=" SET ClientTotal 42 "><w:r><w:t>cached numeric set</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" = ClientTotal + 8 "><w:r><w:t>stale set formula</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" = SUM(ClientTotal; 8) "><w:r><w:t>stale set formula function</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" = MissingTotal + 8 "><w:r><w:t>cached missing formula</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" SET ClientTier "Gold" "><w:r><w:t>cached text set</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" = ClientTier + 1 "><w:r><w:t>cached text formula</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn bookmark_backed_formula_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:bookmarkStart w:id="7" w:name="InvoiceSubtotal"/><w:r><w:t>42</w:t></w:r><w:bookmarkEnd w:id="7"/></w:p><w:p><w:bookmarkStart w:id="8" w:name="InvoiceTier"/><w:r><w:t>Gold</w:t></w:r><w:bookmarkEnd w:id="8"/></w:p><w:p><w:fldSimple w:instr=" = InvoiceSubtotal + 8 "><w:r><w:t>stale bookmark formula</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" = SUM(InvoiceSubtotal; 8) "><w:r><w:t>stale bookmark formula function</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" = DEFINED(InvoiceSubtotal) "><w:r><w:t>stale bookmark defined</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" = InvoiceTier + 1 "><w:r><w:t>cached text bookmark formula</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" = MissingSubtotal + 1 "><w:r><w:t>cached missing bookmark formula</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn set_backed_defined_formula_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:fldSimple w:instr=" SET ClientTier "Gold" "><w:r><w:t>cached text set</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" = DEFINED(ClientTier) "><w:r><w:t>stale defined text set</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" = IF(DEFINED(ClientTier), 7, 9) "><w:r><w:t>stale defined branch</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" = DEFINED(MissingTier) "><w:r><w:t>stale missing defined</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" = ClientTier + 1 "><w:r><w:t>cached text arithmetic</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn set_backed_formula_identifier_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:fldSimple w:instr=" SET Client_Total_2026 42 "><w:r><w:t>cached named set</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" = Client_Total_2026 + 8 "><w:r><w:t>stale named formula</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" SET _HiddenTotal9 7 "><w:r><w:t>cached hidden set</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" = _HiddenTotal9 * 2 "><w:r><w:t>stale hidden formula</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn set_backed_ref_number_format_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:fldSimple w:instr=" SET ClientTotal 21 "><w:r><w:t>cached numeric set</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" REF ClientTotal \* CardText "><w:r><w:t>stale cardtext ref</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" REF ClientTotal \* Ordinal "><w:r><w:t>stale ordinal ref</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" REF ClientTotal \* CardText \* Upper "><w:r><w:t>stale uppercase cardtext ref</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" SET ClientTier "Gold" "><w:r><w:t>cached text set</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" REF ClientTier \* CardText "><w:r><w:t>cached text ref</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" REF MissingTotal \* CardText "><w:r><w:t>cached missing ref</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn if_diagnostics_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:fldSimple w:instr=" IF CustomerTier = "Gold" "ship" "hold" "><w:r><w:t>cached data if</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" IF 1 = "><w:r><w:t>cached broken if</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn compare_diagnostics_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:fldSimple w:instr=" COMPARE CustomerTier = "Gold" "><w:r><w:t>cached data compare</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" COMPARE 1e309 > 0 "><w:r><w:t>cached nonfinite compare</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" COMPARE \o = "Gold" "><w:r><w:t>cached switch compare</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn formula_diagnostics_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:fldSimple w:instr=" = CustomerTotal \# "0.00" "><w:r><w:t>cached data formula</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" = 1 \# "0.00 "><w:r><w:t>cached broken formula</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn set_diagnostics_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:fldSimple w:instr=" SET ClientName Client 42 "><w:r><w:t>cached unquoted set</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" SET ClientName "Acme "><w:r><w:t>cached broken set</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn prompt_default_field_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:fldSimple w:instr=" FILLIN "Client?" \d "Acme" "><w:r><w:t>stale fillin</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" FILLIN "Department?" \d "ops" \* Upper "><w:r><w:t>stale formatted fillin</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" ASK ClientCode "Client code?" \d "ac-42" \o "><w:r><w:t>cached ask default</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" REF ClientCode \* Upper "><w:r><w:t>stale ask ref</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" FILLIN "Project?" \d Client 42 \* Upper "><w:r><w:t>stale multi-token fillin</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" ASK ClientName "Client name?" \d Client 42 \o "><w:r><w:t>cached multi-token ask default</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" REF ClientName \* Upper "><w:r><w:t>stale multi-token ask ref</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn prompt_unquoted_multi_token_text_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:fldSimple w:instr=" FILLIN Client display prompt \d Acme Corp \* Upper "><w:r><w:t>stale unquoted prompt fillin</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" ASK ClientName Client name prompt \d Acme Corp "><w:r><w:t>cached unquoted prompt ask</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" REF ClientName \* Upper "><w:r><w:t>stale unquoted prompt ask ref</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn prompt_unquoted_multi_token_text_no_default_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:fldSimple w:instr=" FILLIN Client display prompt "><w:r><w:t>cached unquoted prompt fillin</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" ASK ClientName Client name prompt "><w:r><w:t>cached unquoted prompt ask</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" REF ClientName \* Upper "><w:r><w:t>stale unquoted prompt ask ref</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn compact_prompt_default_field_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:fldSimple w:instr=" FILLIN "Client?" \d"Acme" "><w:r><w:t>stale compact fillin</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" ASK ClientCode "Client code?" \d"ac-42" "><w:r><w:t>cached compact ask</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" REF ClientCode \* Upper "><w:r><w:t>stale compact ask ref</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn unquoted_set_field_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:fldSimple w:instr=" SET ClientCode Client-42 "><w:r><w:t>cached set</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" REF ClientCode \* Upper "><w:r><w:t>stale ref</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" SET ClientName Client 42 "><w:r><w:t>cached multi-token set</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" REF ClientName \* Upper "><w:r><w:t>stale multi-token ref</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn set_backed_direct_ref_field_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:fldSimple w:instr=" SET ClientCode Client-42 "><w:r><w:t>cached set</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" ClientCode \* Upper "><w:r><w:t>stale direct set ref</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" SET ClientName Client 42 "><w:r><w:t>cached multi-token set</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" ClientName \* Upper "><w:r><w:t>stale direct multi-token ref</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn set_backed_direct_ref_gap_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:fldSimple w:instr=" SET ClientName Client 42 "><w:r><w:t>cached set</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" ClientName \f "><w:r><w:t>cached field-bookmark note ref</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn formula_numeric_picture_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:fldSimple w:instr=" = 1234.5 \# "$#,##0.00" "><w:r><w:t>stale currency formula</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" = 33 \# "##%" "><w:r><w:t>stale percent formula</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" = 111053 + 111439 \# x## "><w:r><w:t>stale dropped formula</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" = 1 / 8 \# 0.00x "><w:r><w:t>stale precision formula</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" = 3 / 4 \# .x "><w:r><w:t>stale rounded formula</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" = 5 \# "0 units" "><w:r><w:t>stale spaced suffix formula</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn formula_quoted_literal_picture_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:fldSimple w:instr=" = 1234 \# "#,##0 'items'" "><w:r><w:t>stale items formula</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" = 5 \# "0 'units'" "><w:r><w:t>stale units formula</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn formula_unquoted_multi_token_numeric_picture_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:fldSimple w:instr=" = 5 \# 0 units \* MERGEFORMAT "><w:r><w:t>stale unquoted units formula</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn formula_compact_numeric_picture_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:fldSimple w:instr=" = 10 / 4 \#"0.0" "><w:r><w:t>stale compact quoted picture</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" = SUM(100, 20) \#$0 "><w:r><w:t>stale compact unquoted picture</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" = 10 \# "><w:r><w:t>cached missing compact picture</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn formula_sectioned_numeric_picture_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:fldSimple w:instr=" = 1245.65 \# "$#,##0.00;-$#,##0.00" "><w:r><w:t>stale positive section</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" = 0 - 345.56 \# "$#,##0.00;-$#,##0.00" "><w:r><w:t>stale negative section</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" = 0 \# "$#,##0.00;($#,##0.00);$0" "><w:r><w:t>stale zero section</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn formula_sign_control_numeric_picture_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:fldSimple w:instr=" = 100 - 90 \# +## "><w:r><w:t>stale plus positive</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" = 90 - 100 \# +## "><w:r><w:t>stale plus negative</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" = 10 - 90 \# -## "><w:r><w:t>stale minus negative</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" = 10 \# -## "><w:r><w:t>stale minus positive</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn formula_function_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:fldSimple w:instr=" = ABS(-22) "><w:r><w:t>stale abs</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" = SUM(1, 2, 3) "><w:r><w:t>stale sum</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" = PRODUCT(2, 3, 4) "><w:r><w:t>stale product</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" = MIN(5, -2, 9) "><w:r><w:t>stale min</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" = MAX(5, -2, 9) "><w:r><w:t>stale max</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" = ROUND(123.456, 2) "><w:r><w:t>stale round</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" = INT(5.67) "><w:r><w:t>stale int</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" = SIGN(-11) "><w:r><w:t>stale sign</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" = SUM(100, 20) \# "$0" "><w:r><w:t>stale formatted function</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" = 2 ^ 3 "><w:r><w:t>stale exponent</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" = (2 + 1) ^ 3 "><w:r><w:t>stale parenthesized exponent</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" = ROUND(4 ^ 0.5, 1) "><w:r><w:t>stale fractional exponent</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" = 1E3 + 2.5e2 "><w:r><w:t>stale scientific sum</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" = ROUND(1.25e-2, 4) "><w:r><w:t>stale scientific fraction</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" = 2E+3 / 4 "><w:r><w:t>stale signed scientific exponent</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn formula_additional_function_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:fldSimple w:instr=" = AVERAGE(2, 4, 6) "><w:r><w:t>stale average</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" = COUNT(2, 4, 6) "><w:r><w:t>stale count</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" = MOD(10, 4) "><w:r><w:t>stale mod</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" = MOD(-3, 2) "><w:r><w:t>stale negative dividend mod</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" = MOD(3, -2) "><w:r><w:t>stale negative divisor mod</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" = MOD(-3, -2) "><w:r><w:t>stale negative both mod</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" = TRUE "><w:r><w:t>stale true constant</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" = FALSE "><w:r><w:t>stale false constant</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" = AND(1, 2, 3) "><w:r><w:t>stale and true</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" = AND(1, 0, 3) "><w:r><w:t>stale and false</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" = OR(0, 0, 7) "><w:r><w:t>stale or true</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" = NOT(0) "><w:r><w:t>stale not</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" = IF(0, 10, 20) "><w:r><w:t>stale if false</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" = IF(OR(0, TRUE), SUM(1, 2), 9) "><w:r><w:t>stale nested if</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn formula_if_short_circuit_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:fldSimple w:instr=" = IF(1, 7, MissingTotal + 1) "><w:r><w:t>stale guarded true</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" = IF(0, MissingTotal + 1, 9) "><w:r><w:t>stale guarded false</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" = IF(DEFINED(MissingTotal), MissingTotal + 1, 3) "><w:r><w:t>stale defined guard</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" = IF(1; 4; 1 / 0) "><w:r><w:t>stale semicolon guard</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" = IF(1, MissingTotal + 1, 9) "><w:r><w:t>cached selected unsupported</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn formula_semicolon_function_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:fldSimple w:instr=" = SUM(1; 2; 3) "><w:r><w:t>stale semicolon sum</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" = IF(OR(0; TRUE); SUM(1; 2); 9) "><w:r><w:t>stale semicolon nested if</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" = SUM(1, 2; 3) "><w:r><w:t>cached mixed separators</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn formula_neutral_switch_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:fldSimple w:instr=" = 2 + 3 \* MERGEFORMAT "><w:r><w:t>stale neutral formula</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" = SUM(1; 2; 3) \*CHARFORMAT "><w:r><w:t>stale compact neutral formula</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" = 10.25 \* DollarText "><w:r><w:t>stale dollar formula</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" = 31 \* Hex "><w:r><w:t>stale hex formula</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" = 2 + 3 \* Upper "><w:r><w:t>stale upper formula</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" = 10.25 \* DollarText \* Upper "><w:r><w:t>stale dollar upper formula</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn formula_defined_function_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:fldSimple w:instr=" = DEFINED(SUM(1; 2; 3)) "><w:r><w:t>stale defined expression</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" = DEFINED(UnknownBookmark) "><w:r><w:t>stale undefined name</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" = DEFINED(1 / 0) "><w:r><w:t>stale error expression</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" = IF(DEFINED(2 + 3), 7, 9) "><w:r><w:t>stale nested defined</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" = DEFINED() "><w:r><w:t>cached empty defined</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn formula_table_reference_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:tbl><w:tr><w:tc><w:p><w:r><w:t>2</w:t></w:r></w:p></w:tc><w:tc><w:p><w:r><w:t>3</w:t></w:r></w:p></w:tc><w:tc><w:p><w:fldSimple w:instr=" = SUM(LEFT) "><w:r><w:t>stale left sum</w:t></w:r></w:fldSimple></w:p></w:tc></w:tr><w:tr><w:tc><w:p><w:r><w:t>10</w:t></w:r></w:p></w:tc><w:tc><w:p><w:r><w:t>5</w:t></w:r></w:p></w:tc><w:tc><w:p><w:fldSimple w:instr=" = AVERAGE(LEFT) \# "0.0" "><w:r><w:t>stale left average</w:t></w:r></w:fldSimple></w:p></w:tc></w:tr></w:tbl><w:tbl><w:tr><w:tc><w:p><w:r><w:t>1</w:t></w:r></w:p></w:tc><w:tc><w:p><w:fldSimple w:instr=" = SUM(BELOW) "><w:r><w:t>stale below sum</w:t></w:r></w:fldSimple></w:p></w:tc><w:tc><w:p><w:r><w:t>9</w:t></w:r></w:p></w:tc></w:tr><w:tr><w:tc><w:p><w:r><w:t>2</w:t></w:r></w:p></w:tc><w:tc><w:p><w:r><w:t>5</w:t></w:r></w:p></w:tc><w:tc><w:p><w:r><w:t>4</w:t></w:r></w:p></w:tc></w:tr><w:tr><w:tc><w:p><w:r><w:t>3</w:t></w:r></w:p></w:tc><w:tc><w:p><w:r><w:t>6</w:t></w:r></w:p></w:tc><w:tc><w:p><w:r><w:t>8</w:t></w:r></w:p></w:tc></w:tr><w:tr><w:tc><w:p><w:fldSimple w:instr=" = SUM(RIGHT) "><w:r><w:t>stale right sum</w:t></w:r></w:fldSimple></w:p></w:tc><w:tc><w:p><w:r><w:t>7</w:t></w:r></w:p></w:tc><w:tc><w:p><w:r><w:t>8</w:t></w:r></w:p></w:tc></w:tr><w:tr><w:tc><w:p><w:r><w:t>0</w:t></w:r></w:p></w:tc><w:tc><w:p><w:r><w:t>0</w:t></w:r></w:p></w:tc><w:tc><w:p><w:fldSimple w:instr=" = SUM(ABOVE) "><w:r><w:t>stale above sum</w:t></w:r></w:fldSimple></w:p></w:tc></w:tr></w:tbl><w:tbl><w:tr><w:tc><w:p><w:r><w:t>n/a</w:t></w:r></w:p></w:tc><w:tc><w:p><w:fldSimple w:instr=" = SUM(LEFT) "><w:r><w:t>cached nonnumeric left</w:t></w:r></w:fldSimple></w:p></w:tc></w:tr></w:tbl></w:body></w:document>"#,
),
])
}
fn formula_table_header_row_reference_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:tbl><w:tr><w:trPr><w:tblHeader/></w:trPr><w:tc><w:p><w:fldSimple w:instr=" = SUM(BELOW) "><w:r><w:t>stale header below sum</w:t></w:r></w:fldSimple></w:p></w:tc><w:tc><w:p><w:fldSimple w:instr=" = COUNT(BELOW) "><w:r><w:t>stale header below count</w:t></w:r></w:fldSimple></w:p></w:tc><w:tc><w:p><w:r><w:t>400</w:t></w:r></w:p></w:tc></w:tr><w:tr><w:trPr><w:tblHeader/></w:trPr><w:tc><w:p><w:r><w:t>200</w:t></w:r></w:p></w:tc><w:tc><w:p><w:r><w:t>300</w:t></w:r></w:p></w:tc><w:tc><w:p><w:r><w:t>500</w:t></w:r></w:p></w:tc></w:tr><w:tr><w:tc><w:p><w:r><w:t>2</w:t></w:r></w:p></w:tc><w:tc><w:p><w:r><w:t>4</w:t></w:r></w:p></w:tc><w:tc><w:p><w:r><w:t>7</w:t></w:r></w:p></w:tc></w:tr><w:tr><w:tc><w:p><w:r><w:t>3</w:t></w:r></w:p></w:tc><w:tc><w:p><w:r><w:t>6</w:t></w:r></w:p></w:tc><w:tc><w:p><w:r><w:t>8</w:t></w:r></w:p></w:tc></w:tr><w:tr><w:tc><w:p><w:fldSimple w:instr=" = SUM(ABOVE) "><w:r><w:t>stale body above sum</w:t></w:r></w:fldSimple></w:p></w:tc><w:tc><w:p><w:fldSimple w:instr=" = COUNT(ABOVE) "><w:r><w:t>stale body above count</w:t></w:r></w:fldSimple></w:p></w:tc><w:tc><w:p><w:fldSimple w:instr=" = SUM(C) "><w:r><w:t>stale body column sum</w:t></w:r></w:fldSimple></w:p></w:tc></w:tr></w:tbl></w:body></w:document>"#,
),
])
}
fn formula_table_header_row_span_reference_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:tbl><w:tr><w:trPr><w:tblHeader/></w:trPr><w:tc><w:p><w:fldSimple w:instr=" = SUM(BELOW) "><w:r><w:t>stale header below span sum</w:t></w:r></w:fldSimple></w:p></w:tc><w:tc><w:p><w:r><w:t>header formula peer</w:t></w:r></w:p></w:tc></w:tr><w:tr><w:trPr><w:tblHeader/></w:trPr><w:tc><w:tcPr><w:gridSpan w:val="2"/></w:tcPr><w:p><w:r><w:t>spanned heading</w:t></w:r></w:p></w:tc></w:tr><w:tr><w:tc><w:p><w:r><w:t>2</w:t></w:r></w:p></w:tc><w:tc><w:p><w:r><w:t>4</w:t></w:r></w:p></w:tc></w:tr><w:tr><w:tc><w:p><w:r><w:t>3</w:t></w:r></w:p></w:tc><w:tc><w:p><w:r><w:t>6</w:t></w:r></w:p></w:tc></w:tr><w:tr><w:tc><w:p><w:fldSimple w:instr=" = SUM(ABOVE) "><w:r><w:t>stale body above span sum</w:t></w:r></w:fldSimple></w:p></w:tc><w:tc><w:p><w:fldSimple w:instr=" = SUM(A1:A3) "><w:r><w:t>cached explicit spanned header range</w:t></w:r></w:fldSimple></w:p></w:tc></w:tr></w:tbl></w:body></w:document>"#,
),
])
}
fn formula_table_header_formula_row_reference_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:tbl><w:tr><w:trPr><w:tblHeader/></w:trPr><w:tc><w:p><w:fldSimple w:instr=" = SUM(BELOW) "><w:r><w:t>stale header below formula row</w:t></w:r></w:fldSimple></w:p></w:tc><w:tc><w:p><w:r><w:t>heading peer</w:t></w:r></w:p></w:tc></w:tr><w:tr><w:trPr><w:tblHeader/></w:trPr><w:tc><w:p><w:fldSimple w:instr=" = SUM(RIGHT) "><w:r><w:t>cached skipped header formula</w:t></w:r></w:fldSimple></w:p></w:tc><w:tc><w:p><w:r><w:t>99</w:t></w:r></w:p></w:tc></w:tr><w:tr><w:trPr><w:tblHeader/></w:trPr><w:tc><w:p><w:fldSimple w:instr=" = SUM(R) "><w:r><w:t>cached skipped header row formula</w:t></w:r></w:fldSimple></w:p></w:tc><w:tc><w:p><w:r><w:t>400</w:t></w:r></w:p></w:tc><w:tc><w:p><w:r><w:t>500</w:t></w:r></w:p></w:tc></w:tr><w:tr><w:tc><w:p><w:r><w:t>2</w:t></w:r></w:p></w:tc><w:tc><w:p><w:r><w:t>4</w:t></w:r></w:p></w:tc></w:tr><w:tr><w:tc><w:p><w:r><w:t>3</w:t></w:r></w:p></w:tc><w:tc><w:p><w:r><w:t>6</w:t></w:r></w:p></w:tc></w:tr></w:tbl></w:body></w:document>"#,
),
])
}
fn formula_table_empty_included_cell_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:tbl><w:tr><w:tc><w:p><w:r><w:t>2</w:t></w:r></w:p></w:tc><w:tc><w:p/></w:tc><w:tc><w:p><w:fldSimple w:instr=" = SUM(LEFT) "><w:r><w:t>cached empty left</w:t></w:r></w:fldSimple></w:p></w:tc></w:tr><w:tr><w:tc><w:p><w:r><w:t>3</w:t></w:r></w:p></w:tc><w:tc><w:p><w:r><w:t>4</w:t></w:r></w:p></w:tc><w:tc><w:p><w:fldSimple w:instr=" = SUM(LEFT) "><w:r><w:t>stale numeric left</w:t></w:r></w:fldSimple></w:p></w:tc></w:tr><w:tr><w:tc><w:p><w:r><w:t>5</w:t></w:r></w:p></w:tc><w:tc><w:p/></w:tc><w:tc><w:p><w:fldSimple w:instr=" = SUM(ABOVE) "><w:r><w:t>cached empty above</w:t></w:r></w:fldSimple></w:p></w:tc></w:tr></w:tbl></w:body></w:document>"#,
),
])
}
fn formula_table_prior_computed_formula_source_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:tbl><w:tr><w:tc><w:p><w:r><w:t>2</w:t></w:r></w:p></w:tc><w:tc><w:p><w:r><w:t>3</w:t></w:r></w:p></w:tc><w:tc><w:p><w:fldSimple w:instr=" = SUM(LEFT) "><w:r><w:t>stale row total</w:t></w:r></w:fldSimple></w:p></w:tc></w:tr><w:tr><w:tc><w:p><w:r><w:t>1</w:t></w:r></w:p></w:tc><w:tc><w:p><w:r><w:t>1</w:t></w:r></w:p></w:tc><w:tc><w:p><w:fldSimple w:instr=" = SUM(ABOVE) "><w:r><w:t>stale dependent above</w:t></w:r></w:fldSimple></w:p></w:tc></w:tr><w:tr><w:tc><w:p><w:fldSimple w:instr=" = SUM(A1:C1) "><w:r><w:t>cached mixed formula range</w:t></w:r></w:fldSimple></w:p></w:tc><w:tc><w:p><w:r><w:t>0</w:t></w:r></w:p></w:tc><w:tc><w:p><w:r><w:t>0</w:t></w:r></w:p></w:tc></w:tr></w:tbl></w:body></w:document>"#,
),
])
}
fn formula_table_empty_prior_formula_source_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:tbl><w:tr><w:tc><w:p><w:fldSimple w:instr=" = SUM(RIGHT) "></w:fldSimple></w:p></w:tc><w:tc><w:p><w:r><w:t>2</w:t></w:r></w:p></w:tc><w:tc><w:p><w:r><w:t>3</w:t></w:r></w:p></w:tc></w:tr><w:tr><w:tc><w:p><w:fldSimple w:instr=" = SUM(ABOVE) "><w:r><w:t>dependent cached</w:t></w:r></w:fldSimple></w:p></w:tc><w:tc><w:p><w:r><w:t>0</w:t></w:r></w:p></w:tc><w:tc><w:p><w:r><w:t>0</w:t></w:r></w:p></w:tc></w:tr></w:tbl></w:body></w:document>"#,
),
])
}
fn formula_table_source_field_alternate_content_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"><w:body><w:tbl><w:tr><w:tc><w:p><w:fldSimple w:instr=" QUOTE "2" "><mc:AlternateContent><mc:Choice Requires="wps"><w:r><w:t>2</w:t></w:r></mc:Choice><mc:Fallback><w:r><w:t>9</w:t></w:r></mc:Fallback></mc:AlternateContent></w:fldSimple></w:p></w:tc><w:tc><w:p><w:fldSimple w:instr=" = SUM(LEFT) "><w:r><w:t>stale alt source sum</w:t></w:r></w:fldSimple></w:p></w:tc></w:tr></w:tbl></w:body></w:document>"#,
),
])
}
fn formula_table_source_field_nested_simple_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:tbl><w:tr><w:tc><w:p><w:fldSimple w:instr=" QUOTE "123" "><w:r><w:t>1</w:t></w:r><w:fldSimple w:instr=" CUSTOM inner "><w:r><w:t>2</w:t></w:r></w:fldSimple><w:fldSimple w:instr=" = 1 + 2 "><w:r><w:t>3</w:t></w:r></w:fldSimple></w:fldSimple></w:p></w:tc><w:tc><w:p><w:fldSimple w:instr=" = SUM(LEFT) "><w:r><w:t>stale nested source sum</w:t></w:r></w:fldSimple></w:p></w:tc></w:tr></w:tbl></w:body></w:document>"#,
),
])
}
fn formula_table_source_nested_empty_simple_field_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:tbl><w:tr><w:tc><w:p><w:fldSimple w:instr=" CUSTOM outer "><w:r><w:t>1</w:t></w:r><w:fldSimple w:instr=" QUOTE "2" "/><w:r><w:t>3</w:t></w:r></w:fldSimple></w:p></w:tc><w:tc><w:p><w:fldSimple w:instr=" = SUM(LEFT) "><w:r><w:t>stale nested empty source sum</w:t></w:r></w:fldSimple></w:p></w:tc></w:tr></w:tbl></w:body></w:document>"#,
),
])
}
fn formula_table_source_nested_simple_field_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:tbl><w:tr><w:tc><w:p><w:fldSimple w:instr=" CUSTOM outer "><w:r><w:t>1</w:t></w:r><w:fldSimple w:instr=" QUOTE "2" "><w:r><w:t>9</w:t></w:r></w:fldSimple><w:r><w:t>3</w:t></w:r></w:fldSimple></w:p></w:tc><w:tc><w:p><w:fldSimple w:instr=" = SUM(LEFT) "><w:r><w:t>stale nested source sum</w:t></w:r></w:fldSimple></w:p></w:tc></w:tr></w:tbl></w:body></w:document>"#,
),
])
}
fn formula_table_source_nested_complex_field_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:tbl><w:tr><w:tc><w:p><w:fldSimple w:instr=" CUSTOM outer "><w:r><w:t>1</w:t></w:r><w:r><w:fldChar w:fldCharType="begin"/></w:r><w:r><w:instrText> QUOTE "2" </w:instrText></w:r><w:r><w:fldChar w:fldCharType="separate"/></w:r><w:r><w:t>9</w:t></w:r><w:r><w:fldChar w:fldCharType="end"/></w:r><w:r><w:t>3</w:t></w:r></w:fldSimple></w:p></w:tc><w:tc><w:p><w:fldSimple w:instr=" = SUM(LEFT) "><w:r><w:t>stale nested complex source sum</w:t></w:r></w:fldSimple></w:p></w:tc></w:tr></w:tbl></w:body></w:document>"#,
),
])
}
fn formula_table_source_field_stale_nested_simple_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:tbl><w:tr><w:tc><w:p><w:fldSimple w:instr=" QUOTE "123" "><w:r><w:t>stale source value</w:t></w:r></w:fldSimple></w:p></w:tc><w:tc><w:p><w:fldSimple w:instr=" = SUM(LEFT) "><w:r><w:t>stale source sum</w:t></w:r></w:fldSimple></w:p></w:tc></w:tr></w:tbl></w:body></w:document>"#,
),
])
}
fn formula_table_source_field_stale_complex_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:tbl><w:tr><w:tc><w:p><w:r><w:fldChar w:fldCharType="begin"/></w:r><w:r><w:instrText> QUOTE "123" </w:instrText></w:r><w:r><w:fldChar w:fldCharType="separate"/></w:r><w:r><w:t>stale complex source</w:t></w:r><w:r><w:fldChar w:fldCharType="end"/></w:r></w:p></w:tc><w:tc><w:p><w:fldSimple w:instr=" = SUM(LEFT) "><w:r><w:t>stale complex source sum</w:t></w:r></w:fldSimple></w:p></w:tc></w:tr></w:tbl></w:body></w:document>"#,
),
])
}
fn formula_table_source_field_sequence_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:fldSimple w:instr=" SEQ Item "><w:r><w:t>1</w:t></w:r></w:fldSimple></w:p><w:tbl><w:tr><w:tc><w:p><w:fldSimple w:instr=" SEQ Item "><w:r><w:t>99</w:t></w:r></w:fldSimple></w:p></w:tc><w:tc><w:p><w:fldSimple w:instr=" = SUM(LEFT) "><w:r><w:t>stale simple sequence source sum</w:t></w:r></w:fldSimple></w:p></w:tc></w:tr><w:tr><w:tc><w:p><w:r><w:fldChar w:fldCharType="begin"/></w:r><w:r><w:instrText> SEQ Item </w:instrText></w:r><w:r><w:fldChar w:fldCharType="separate"/></w:r><w:r><w:t>98</w:t></w:r><w:r><w:fldChar w:fldCharType="end"/></w:r></w:p></w:tc><w:tc><w:p><w:fldSimple w:instr=" = SUM(LEFT) "><w:r><w:t>stale complex sequence source sum</w:t></w:r></w:fldSimple></w:p></w:tc></w:tr></w:tbl></w:body></w:document>"#,
),
])
}
fn formula_table_source_field_numbering_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:fldSimple w:instr=" AUTONUM "><w:r><w:t>1</w:t></w:r></w:fldSimple></w:p><w:tbl><w:tr><w:tc><w:p><w:fldSimple w:instr=" AUTONUM "><w:r><w:t>99</w:t></w:r></w:fldSimple></w:p></w:tc><w:tc><w:p><w:fldSimple w:instr=" = SUM(LEFT) "><w:r><w:t>stale simple autonum source sum</w:t></w:r></w:fldSimple></w:p></w:tc></w:tr><w:tr><w:tc><w:p><w:r><w:fldChar w:fldCharType="begin"/></w:r><w:r><w:instrText> AUTONUM </w:instrText></w:r><w:r><w:fldChar w:fldCharType="separate"/></w:r><w:r><w:t>98</w:t></w:r><w:r><w:fldChar w:fldCharType="end"/></w:r></w:p></w:tc><w:tc><w:p><w:fldSimple w:instr=" = SUM(LEFT) "><w:r><w:t>stale complex autonum source sum</w:t></w:r></w:fldSimple></w:p></w:tc></w:tr></w:tbl></w:body></w:document>"#,
),
])
}
fn formula_table_source_field_listnum_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:fldSimple w:instr=" LISTNUM NumberDefault "><w:r><w:t>1</w:t></w:r></w:fldSimple></w:p><w:tbl><w:tr><w:tc><w:p><w:fldSimple w:instr=" LISTNUM NumberDefault "><w:r><w:t>99</w:t></w:r></w:fldSimple></w:p></w:tc><w:tc><w:p><w:fldSimple w:instr=" = SUM(LEFT) "><w:r><w:t>stale simple listnum source sum</w:t></w:r></w:fldSimple></w:p></w:tc></w:tr><w:tr><w:tc><w:p><w:r><w:fldChar w:fldCharType="begin"/></w:r><w:r><w:instrText> LISTNUM NumberDefault </w:instrText></w:r><w:r><w:fldChar w:fldCharType="separate"/></w:r><w:r><w:t>98</w:t></w:r><w:r><w:fldChar w:fldCharType="end"/></w:r></w:p></w:tc><w:tc><w:p><w:fldSimple w:instr=" = SUM(LEFT) "><w:r><w:t>stale complex listnum source sum</w:t></w:r></w:fldSimple></w:p></w:tc></w:tr></w:tbl></w:body></w:document>"#,
),
])
}
fn formula_table_source_field_legacy_form_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:fldSimple w:instr=" FORMDROPDOWN "><w:ffData><w:ddList><w:result w:val="1"/><w:listEntry w:val="1"/><w:listEntry w:val="99"/></w:ddList></w:ffData><w:r><w:t>stale prior form</w:t></w:r></w:fldSimple></w:p><w:tbl><w:tr><w:tc><w:p><w:fldSimple w:instr=" FORMDROPDOWN "><w:ffData><w:ddList><w:result w:val="1"/><w:listEntry w:val="3"/><w:listEntry w:val="7"/></w:ddList></w:ffData><w:r><w:t>stale source form</w:t></w:r></w:fldSimple></w:p></w:tc><w:tc><w:p><w:fldSimple w:instr=" = SUM(LEFT) "><w:r><w:t>stale legacy form source sum</w:t></w:r></w:fldSimple></w:p></w:tc></w:tr></w:tbl></w:body></w:document>"#,
),
])
}
fn formula_table_source_field_note_ref_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/><Override PartName="/word/footnotes.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.footnotes+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/_rels/document.xml.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rIdFoot" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/footnotes" Target="footnotes.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:bookmarkStart w:id="7" w:name="FootOne"/><w:r><w:footnoteReference w:id="1"/></w:r><w:bookmarkEnd w:id="7"/></w:p><w:tbl><w:tr><w:tc><w:p><w:fldSimple w:instr=" NOTEREF FootOne "><w:r><w:t>stale note source</w:t></w:r></w:fldSimple></w:p></w:tc><w:tc><w:p><w:fldSimple w:instr=" = SUM(LEFT) "><w:r><w:t>stale note source sum</w:t></w:r></w:fldSimple></w:p></w:tc></w:tr></w:tbl></w:body></w:document>"#,
),
(
"word/footnotes.xml",
r#"<w:footnotes xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:footnote w:type="separator" w:id="-1"><w:p><w:r><w:separator/></w:r></w:p></w:footnote><w:footnote w:id="1"><w:p><w:r><w:t>First footnote.</w:t></w:r></w:p></w:footnote></w:footnotes>"#,
),
])
}
fn formula_table_source_field_relative_note_ref_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/><Override PartName="/word/footnotes.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.footnotes+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/_rels/document.xml.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rIdFoot" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/footnotes" Target="footnotes.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:bookmarkStart w:id="7" w:name="FootOne"/><w:r><w:footnoteReference w:id="1"/></w:r><w:bookmarkEnd w:id="7"/></w:p><w:tbl><w:tr><w:tc><w:p><w:fldSimple w:instr=" NOTEREF FootOne \p "><w:r><w:t>9</w:t></w:r></w:fldSimple></w:p></w:tc><w:tc><w:p><w:fldSimple w:instr=" = SUM(LEFT) "><w:r><w:t>stale relative note source sum</w:t></w:r></w:fldSimple></w:p></w:tc></w:tr></w:tbl></w:body></w:document>"#,
),
(
"word/footnotes.xml",
r#"<w:footnotes xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:footnote w:type="separator" w:id="-1"><w:p><w:r><w:separator/></w:r></w:p></w:footnote><w:footnote w:id="1"><w:p><w:r><w:t>First footnote.</w:t></w:r></w:p></w:footnote></w:footnotes>"#,
),
])
}
fn formula_table_source_field_ref_note_mark_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/><Override PartName="/word/footnotes.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.footnotes+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/_rels/document.xml.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rIdFoot" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/footnotes" Target="footnotes.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:bookmarkStart w:id="7" w:name="FootOne"/><w:r><w:footnoteReference w:id="1"/></w:r><w:bookmarkEnd w:id="7"/></w:p><w:tbl><w:tr><w:tc><w:p><w:fldSimple w:instr=" REF FootOne \f "><w:r><w:t>stale ref note source</w:t></w:r></w:fldSimple></w:p></w:tc><w:tc><w:p><w:fldSimple w:instr=" = SUM(LEFT) "><w:r><w:t>stale ref note source sum</w:t></w:r></w:fldSimple></w:p></w:tc></w:tr></w:tbl></w:body></w:document>"#,
),
(
"word/footnotes.xml",
r#"<w:footnotes xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:footnote w:type="separator" w:id="-1"><w:p><w:r><w:separator/></w:r></w:p></w:footnote><w:footnote w:id="1"><w:p><w:r><w:t>First footnote.</w:t></w:r></w:p></w:footnote></w:footnotes>"#,
),
])
}
fn formula_table_source_field_document_bookmark_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:bookmarkStart w:id="7" w:name="InvoiceTier"/><w:r><w:t>Gold</w:t></w:r><w:bookmarkEnd w:id="7"/></w:p><w:tbl><w:tr><w:tc><w:p><w:fldSimple w:instr=" IF InvoiceTier = "Gold" "123" "0" "><w:r><w:t>stale bookmark source</w:t></w:r></w:fldSimple></w:p></w:tc><w:tc><w:p><w:fldSimple w:instr=" = SUM(LEFT) "><w:r><w:t>stale bookmark source sum</w:t></w:r></w:fldSimple></w:p></w:tc></w:tr></w:tbl></w:body></w:document>"#,
),
])
}
fn formula_table_source_field_document_info_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/><Override PartName="/docProps/core.xml" ContentType="application/vnd.openxmlformats-package.core-properties+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/><Relationship Id="rIdCore" Type="http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties" Target="docProps/core.xml"/></Relationships>"#,
),
(
"docProps/core.xml",
r#"<cp:coreProperties xmlns:cp="http://schemas.openxmlformats.org/package/2006/metadata/core-properties"><cp:version>123</cp:version></cp:coreProperties>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:tbl><w:tr><w:tc><w:p><w:fldSimple w:instr=" VERSION "><w:r><w:t>999</w:t></w:r></w:fldSimple></w:p></w:tc><w:tc><w:p><w:fldSimple w:instr=" = SUM(LEFT) "><w:r><w:t>stale document-info source sum</w:t></w:r></w:fldSimple></w:p></w:tc></w:tr></w:tbl></w:body></w:document>"#,
),
])
}
fn formula_table_source_field_section_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:tbl><w:tr><w:tc><w:p><w:fldSimple w:instr=" SECTION "><w:r><w:t>99</w:t></w:r></w:fldSimple></w:p></w:tc><w:tc><w:p><w:fldSimple w:instr=" = SUM(LEFT) "><w:r><w:t>stale section source sum</w:t></w:r></w:fldSimple></w:p></w:tc></w:tr></w:tbl></w:body></w:document>"#,
),
])
}
fn formula_table_source_field_ref_bookmark_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:bookmarkStart w:id="7" w:name="InvoiceTotal"/><w:r><w:t>123</w:t></w:r><w:bookmarkEnd w:id="7"/></w:p><w:tbl><w:tr><w:tc><w:p><w:fldSimple w:instr=" REF InvoiceTotal "><w:r><w:t>stale ref source</w:t></w:r></w:fldSimple></w:p></w:tc><w:tc><w:p><w:fldSimple w:instr=" = SUM(LEFT) "><w:r><w:t>stale ref source sum</w:t></w:r></w:fldSimple></w:p></w:tc></w:tr><w:tr><w:tc><w:p><w:fldSimple w:instr=" InvoiceTotal "><w:r><w:t>stale direct source</w:t></w:r></w:fldSimple></w:p></w:tc><w:tc><w:p><w:fldSimple w:instr=" = SUM(LEFT) "><w:r><w:t>stale direct source sum</w:t></w:r></w:fldSimple></w:p></w:tc></w:tr></w:tbl></w:body></w:document>"#,
),
])
}
fn formula_table_source_field_prior_set_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:fldSimple w:instr=" SET ClientTier "Gold" "><w:r><w:t>cached set tier</w:t></w:r></w:fldSimple></w:p><w:tbl><w:tr><w:tc><w:p><w:fldSimple w:instr=" IF ClientTier = "Gold" "123" "0" "><w:r><w:t>stale set source</w:t></w:r></w:fldSimple></w:p></w:tc><w:tc><w:p><w:fldSimple w:instr=" = SUM(LEFT) "><w:r><w:t>stale set source sum</w:t></w:r></w:fldSimple></w:p></w:tc></w:tr></w:tbl></w:body></w:document>"#,
),
])
}
fn formula_table_source_field_prior_complex_set_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:r><w:fldChar w:fldCharType="begin"/></w:r><w:r><w:instrText> SET ClientTier "Gold" </w:instrText></w:r><w:r><w:fldChar w:fldCharType="separate"/></w:r><w:r><w:t>cached complex set tier</w:t></w:r><w:r><w:fldChar w:fldCharType="end"/></w:r></w:p><w:tbl><w:tr><w:tc><w:p><w:fldSimple w:instr=" IF ClientTier = "Gold" "123" "0" "><w:r><w:t>stale complex set source</w:t></w:r></w:fldSimple></w:p></w:tc><w:tc><w:p><w:fldSimple w:instr=" = SUM(LEFT) "><w:r><w:t>stale complex set source sum</w:t></w:r></w:fldSimple></w:p></w:tc></w:tr></w:tbl></w:body></w:document>"#,
),
])
}
fn formula_table_source_known_field_name_bookmark_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:bookmarkStart w:id="7" w:name="PAGEREF"/><w:r><w:t>999</w:t></w:r><w:bookmarkEnd w:id="7"/></w:p><w:tbl><w:tr><w:tc><w:p><w:fldSimple w:instr=" PAGEREF "><w:r><w:t>123</w:t></w:r></w:fldSimple></w:p></w:tc><w:tc><w:p><w:fldSimple w:instr=" = SUM(LEFT) "><w:r><w:t>stale known field source sum</w:t></w:r></w:fldSimple></w:p></w:tc></w:tr></w:tbl></w:body></w:document>"#,
),
])
}
fn formula_table_source_toc_entry_marker_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:tbl><w:tr><w:tc><w:p><w:r><w:t>12</w:t></w:r><w:fldSimple w:instr=" TC "Hidden" \f m \l 1 "><w:r><w:t>999</w:t></w:r></w:fldSimple><w:r><w:t>3</w:t></w:r></w:p></w:tc><w:tc><w:p><w:fldSimple w:instr=" = SUM(LEFT) "><w:r><w:t>stale tc source sum</w:t></w:r></w:fldSimple></w:p></w:tc></w:tr></w:tbl></w:body></w:document>"#,
),
])
}
fn formula_table_source_field_symbol_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:tbl><w:tr><w:tc><w:p><w:fldSimple w:instr=" QUOTE "123" "><w:r><w:t>1</w:t><w:sym w:char="0032"/><w:t>3</w:t></w:r></w:fldSimple></w:p></w:tc><w:tc><w:p><w:fldSimple w:instr=" = SUM(LEFT) "><w:r><w:t>stale symbol source sum</w:t></w:r></w:fldSimple></w:p></w:tc></w:tr></w:tbl></w:body></w:document>"#,
),
])
}
fn formula_table_source_empty_simple_field_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:tbl><w:tr><w:tc><w:p><w:fldSimple w:instr=" QUOTE "123" "/></w:p></w:tc><w:tc><w:p><w:fldSimple w:instr=" = SUM(LEFT) "><w:r><w:t>stale empty source sum</w:t></w:r></w:fldSimple></w:p></w:tc></w:tr></w:tbl></w:body></w:document>"#,
),
])
}
fn formula_table_plain_text_symbol_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:tbl><w:tr><w:tc><w:p><w:r><w:t>1</w:t><w:sym w:char="0032"/><w:t>3</w:t></w:r></w:p></w:tc><w:tc><w:p><w:fldSimple w:instr=" = SUM(LEFT) "><w:r><w:t>stale plain symbol sum</w:t></w:r></w:fldSimple></w:p></w:tc></w:tr></w:tbl></w:body></w:document>"#,
),
])
}
fn formula_table_cell_property_revision_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:tbl><w:tr><w:tc><w:p><w:r><w:t>2</w:t></w:r></w:p></w:tc><w:tc><w:tcPr><w:tcPrChange w:id="1" w:author="rwml" w:date="2026-06-30T00:00:00Z"><w:tcPr><w:gridSpan w:val="2"/></w:tcPr></w:tcPrChange></w:tcPr><w:p><w:r><w:t>3</w:t></w:r></w:p></w:tc><w:tc><w:p><w:fldSimple w:instr=" = SUM(LEFT) "><w:r><w:t>cached old span sum</w:t></w:r></w:fldSimple></w:p></w:tc></w:tr></w:tbl></w:body></w:document>"#,
),
])
}
fn formula_table_cell_property_alternate_content_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"><w:body><w:tbl><w:tr><w:tc><w:p><w:r><w:t>2</w:t></w:r></w:p></w:tc><w:tc><w:tcPr><mc:AlternateContent><mc:Choice Requires="w14"><w:tcW w:type="auto" w:w="0"/></mc:Choice><mc:Fallback><w:gridSpan w:val="2"/></mc:Fallback></mc:AlternateContent></w:tcPr><w:p><w:r><w:t>3</w:t></w:r></w:p></w:tc><w:tc><w:p><w:fldSimple w:instr=" = SUM(LEFT) "><w:r><w:t>cached fallback span sum</w:t></w:r></w:fldSimple></w:p></w:tc></w:tr></w:tbl></w:body></w:document>"#,
),
])
}
fn formula_table_span_row_local_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:tbl><w:tr><w:tc><w:tcPr><w:gridSpan w:val="2"/></w:tcPr><w:p><w:r><w:t>spanned heading</w:t></w:r></w:p></w:tc><w:tc><w:p><w:r><w:t>tail heading</w:t></w:r></w:p></w:tc></w:tr><w:tr><w:tc><w:p><w:r><w:t>2</w:t></w:r></w:p></w:tc><w:tc><w:p><w:r><w:t>3</w:t></w:r></w:p></w:tc><w:tc><w:p><w:fldSimple w:instr=" = SUM(LEFT) "><w:r><w:t>cached row-local left</w:t></w:r></w:fldSimple></w:p></w:tc></w:tr><w:tr><w:tc><w:p><w:fldSimple w:instr=" = SUM(RIGHT) "><w:r><w:t>cached row-local right</w:t></w:r></w:fldSimple></w:p></w:tc><w:tc><w:p><w:r><w:t>7</w:t></w:r></w:p></w:tc><w:tc><w:p><w:r><w:t>8</w:t></w:r></w:p></w:tc></w:tr><w:tr><w:tc><w:p><w:r><w:t>0</w:t></w:r></w:p></w:tc><w:tc><w:p><w:r><w:t>0</w:t></w:r></w:p></w:tc><w:tc><w:p><w:fldSimple w:instr=" = SUM(ABOVE) "><w:r><w:t>cached span-table above</w:t></w:r></w:fldSimple></w:p></w:tc></w:tr></w:tbl></w:body></w:document>"#,
),
])
}
fn formula_table_span_current_row_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:tbl><w:tr><w:tc><w:tcPr><w:gridSpan w:val="2"/></w:tcPr><w:p><w:r><w:t>spanned heading</w:t></w:r></w:p></w:tc><w:tc><w:p><w:r><w:t>tail heading</w:t></w:r></w:p></w:tc></w:tr><w:tr><w:tc><w:p><w:r><w:t>2</w:t></w:r></w:p></w:tc><w:tc><w:p><w:r><w:t>3</w:t></w:r></w:p></w:tc><w:tc><w:p><w:fldSimple w:instr=" = SUM(R) "><w:r><w:t>cached span-table row</w:t></w:r></w:fldSimple></w:p></w:tc></w:tr><w:tr><w:tc><w:p><w:r><w:t>4</w:t></w:r></w:p></w:tc><w:tc><w:p><w:fldSimple w:instr=" = SUM(C) "><w:r><w:t>cached span-table column</w:t></w:r></w:fldSimple></w:p></w:tc><w:tc><w:p><w:r><w:t>6</w:t></w:r></w:p></w:tc></w:tr></w:tbl></w:body></w:document>"#,
),
])
}
fn formula_table_span_same_row_cell_reference_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:tbl><w:tr><w:tc><w:tcPr><w:gridSpan w:val="2"/></w:tcPr><w:p><w:r><w:t>spanned heading</w:t></w:r></w:p></w:tc><w:tc><w:p><w:r><w:t>tail heading</w:t></w:r></w:p></w:tc></w:tr><w:tr><w:tc><w:p><w:r><w:t>2</w:t></w:r></w:p></w:tc><w:tc><w:p><w:r><w:t>3</w:t></w:r></w:p></w:tc><w:tc><w:p><w:fldSimple w:instr=" = A2 + B2 \# "0" "><w:r><w:t>cached same-row direct</w:t></w:r></w:fldSimple></w:p></w:tc></w:tr><w:tr><w:tc><w:p><w:r><w:t>4</w:t></w:r></w:p></w:tc><w:tc><w:p><w:r><w:t>6</w:t></w:r></w:p></w:tc><w:tc><w:p><w:fldSimple w:instr=" = SUM(A3:B3) "><w:r><w:t>cached same-row range</w:t></w:r></w:fldSimple></w:p></w:tc></w:tr><w:tr><w:tc><w:p><w:fldSimple w:instr=" = SUM(A1:B2) "><w:r><w:t>cached cross-row range</w:t></w:r></w:fldSimple></w:p></w:tc><w:tc><w:p><w:r><w:t>1</w:t></w:r></w:p></w:tc><w:tc><w:p><w:r><w:t>1</w:t></w:r></w:p></w:tc></w:tr></w:tbl></w:body></w:document>"#,
),
])
}
fn formula_table_span_cross_row_cell_reference_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:tbl><w:tr><w:tc><w:tcPr><w:gridSpan w:val="2"/></w:tcPr><w:p><w:r><w:t>spanned heading</w:t></w:r></w:p></w:tc><w:tc><w:p><w:r><w:t>tail heading</w:t></w:r></w:p></w:tc></w:tr><w:tr><w:tc><w:p><w:r><w:t>2</w:t></w:r></w:p></w:tc><w:tc><w:p><w:r><w:t>3</w:t></w:r></w:p></w:tc><w:tc><w:p><w:fldSimple w:instr=" = A2 + A3 \# "0" "><w:r><w:t>cached cross-row direct</w:t></w:r></w:fldSimple></w:p></w:tc></w:tr><w:tr><w:tc><w:p><w:r><w:t>4</w:t></w:r></w:p></w:tc><w:tc><w:p><w:r><w:t>6</w:t></w:r></w:p></w:tc><w:tc><w:p><w:fldSimple w:instr=" = SUM(A2:B3) "><w:r><w:t>cached unspanned-row range</w:t></w:r></w:fldSimple></w:p></w:tc></w:tr><w:tr><w:tc><w:p><w:fldSimple w:instr=" = SUM(A1:B2) "><w:r><w:t>cached spanned-row range</w:t></w:r></w:fldSimple></w:p></w:tc><w:tc><w:p><w:r><w:t>1</w:t></w:r></w:p></w:tc><w:tc><w:p><w:r><w:t>1</w:t></w:r></w:p></w:tc></w:tr></w:tbl></w:body></w:document>"#,
),
])
}
fn formula_table_span_if_short_circuit_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:tbl><w:tr><w:tc><w:tcPr><w:gridSpan w:val="2"/></w:tcPr><w:p><w:r><w:t>spanned heading</w:t></w:r></w:p></w:tc><w:tc><w:p><w:r><w:t>tail heading</w:t></w:r></w:p></w:tc></w:tr><w:tr><w:tc><w:p><w:r><w:t>2</w:t></w:r></w:p></w:tc><w:tc><w:p><w:r><w:t>3</w:t></w:r></w:p></w:tc><w:tc><w:p><w:fldSimple w:instr=" = IF(SUM(LEFT)>0,SUM(LEFT),SUM(A1:B2)) "><w:r><w:t>cached guarded row-local</w:t></w:r></w:fldSimple></w:p></w:tc></w:tr><w:tr><w:tc><w:p><w:r><w:t>0</w:t></w:r></w:p></w:tc><w:tc><w:p><w:fldSimple w:instr=" = IF(SUM(LEFT)>0,SUM(A1:B2),9) "><w:r><w:t>cached guarded literal</w:t></w:r></w:fldSimple></w:p></w:tc></w:tr><w:tr><w:tc><w:p><w:r><w:t>4</w:t></w:r></w:p></w:tc><w:tc><w:p><w:fldSimple w:instr=" = IF(SUM(LEFT)>0;7;SUM(A1:B2)) "><w:r><w:t>cached semicolon guarded</w:t></w:r></w:fldSimple></w:p></w:tc></w:tr><w:tr><w:tc><w:p><w:r><w:t>5</w:t></w:r></w:p></w:tc><w:tc><w:p><w:fldSimple w:instr=" = IF(SUM(LEFT)>0,SUM(A1:B2),9) "><w:r><w:t>cached selected span branch</w:t></w:r></w:fldSimple></w:p></w:tc></w:tr></w:tbl></w:body></w:document>"#,
),
])
}
fn formula_table_span_directional_reference_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:tbl><w:tr><w:tc><w:p><w:r><w:t>2</w:t></w:r></w:p></w:tc><w:tc><w:p><w:r><w:t>3</w:t></w:r></w:p></w:tc></w:tr><w:tr><w:tc><w:p><w:r><w:t>1</w:t></w:r></w:p></w:tc><w:tc><w:p><w:fldSimple w:instr=" = SUM(ABOVE) "><w:r><w:t>cached safe above</w:t></w:r></w:fldSimple></w:p></w:tc></w:tr><w:tr><w:tc><w:tcPr><w:gridSpan w:val="2"/></w:tcPr><w:p><w:r><w:t>spanned below</w:t></w:r></w:p></w:tc></w:tr></w:tbl><w:tbl><w:tr><w:tc><w:tcPr><w:gridSpan w:val="2"/></w:tcPr><w:p><w:r><w:t>spanned above</w:t></w:r></w:p></w:tc></w:tr><w:tr><w:tc><w:p><w:fldSimple w:instr=" = SUM(BELOW) "><w:r><w:t>cached safe below</w:t></w:r></w:fldSimple></w:p></w:tc><w:tc><w:p><w:r><w:t>1</w:t></w:r></w:p></w:tc></w:tr><w:tr><w:tc><w:p><w:r><w:t>4</w:t></w:r></w:p></w:tc><w:tc><w:p><w:r><w:t>1</w:t></w:r></w:p></w:tc></w:tr><w:tr><w:tc><w:p><w:r><w:t>6</w:t></w:r></w:p></w:tc><w:tc><w:p><w:r><w:t>1</w:t></w:r></w:p></w:tc></w:tr></w:tbl><w:tbl><w:tr><w:tc><w:tcPr><w:gridSpan w:val="2"/></w:tcPr><w:p><w:r><w:t>spanned heading</w:t></w:r></w:p></w:tc></w:tr><w:tr><w:tc><w:p><w:r><w:t>2</w:t></w:r></w:p></w:tc><w:tc><w:p><w:r><w:t>3</w:t></w:r></w:p></w:tc></w:tr><w:tr><w:tc><w:p><w:r><w:t>1</w:t></w:r></w:p></w:tc><w:tc><w:p><w:fldSimple w:instr=" = SUM(ABOVE) "><w:r><w:t>cached spanned above</w:t></w:r></w:fldSimple></w:p></w:tc></w:tr></w:tbl><w:tbl><w:tr><w:tc><w:p><w:fldSimple w:instr=" = SUM(BELOW) "><w:r><w:t>cached spanned below</w:t></w:r></w:fldSimple></w:p></w:tc><w:tc><w:p><w:r><w:t>1</w:t></w:r></w:p></w:tc></w:tr><w:tr><w:tc><w:tcPr><w:gridSpan w:val="2"/></w:tcPr><w:p><w:r><w:t>8</w:t></w:r></w:p></w:tc></w:tr></w:tbl></w:body></w:document>"#,
),
])
}
fn formula_table_structural_wrapper_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:tbl><w:sdt><w:sdtPr/><w:sdtContent><w:tr><w:tc><w:p><w:r><w:t>2</w:t></w:r></w:p></w:tc><w:tc><w:p><w:r><w:t>3</w:t></w:r></w:p></w:tc><w:tc><w:p><w:fldSimple w:instr=" = SUM(LEFT) "><w:r><w:t>cached row wrapper sum</w:t></w:r></w:fldSimple></w:p></w:tc></w:tr></w:sdtContent></w:sdt></w:tbl><w:tbl><w:tr><w:sdt><w:sdtPr/><w:sdtContent><w:tc><w:p><w:r><w:t>4</w:t></w:r></w:p></w:tc></w:sdtContent></w:sdt><w:sdt><w:sdtPr/><w:sdtContent><w:tc><w:p><w:r><w:t>6</w:t></w:r></w:p></w:tc></w:sdtContent></w:sdt><w:sdt><w:sdtPr/><w:sdtContent><w:tc><w:p><w:fldSimple w:instr=" = SUM(LEFT) "><w:r><w:t>cached cell wrapper sum</w:t></w:r></w:fldSimple></w:p></w:tc></w:sdtContent></w:sdt></w:tr></w:tbl></w:body></w:document>"#,
),
])
}
fn formula_table_structural_alternate_content_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"><w:body><w:tbl><mc:AlternateContent><mc:Choice Requires="w14"><w:tr><w:tc><w:p><w:r><w:t>2</w:t></w:r></w:p></w:tc><w:tc><w:p><w:r><w:t>3</w:t></w:r></w:p></w:tc><w:tc><w:p><w:fldSimple w:instr=" = SUM(LEFT) "><w:r><w:t>cached alternate row sum</w:t></w:r></w:fldSimple></w:p></w:tc></w:tr></mc:Choice><mc:Fallback><w:tr><w:tc><w:p><w:r><w:t>fallback row</w:t></w:r></w:p></w:tc></w:tr></mc:Fallback></mc:AlternateContent></w:tbl><w:tbl><w:tr><mc:AlternateContent><mc:Choice Requires="w14"><w:tc><w:p><w:r><w:t>4</w:t></w:r></w:p></w:tc></mc:Choice><mc:Fallback><w:tc><w:p><w:r><w:t>fallback left</w:t></w:r></w:p></w:tc></mc:Fallback></mc:AlternateContent><mc:AlternateContent><mc:Choice Requires="w14"><w:tc><w:p><w:r><w:t>6</w:t></w:r></w:p></w:tc></mc:Choice><mc:Fallback><w:tc><w:p><w:r><w:t>fallback middle</w:t></w:r></w:p></w:tc></mc:Fallback></mc:AlternateContent><mc:AlternateContent><mc:Choice Requires="w14"><w:tc><w:p><w:fldSimple w:instr=" = SUM(LEFT) "><w:r><w:t>cached alternate cell sum</w:t></w:r></w:fldSimple></w:p></w:tc></mc:Choice><mc:Fallback><w:tc><w:p><w:r><w:t>fallback formula</w:t></w:r></w:p></w:tc></mc:Fallback></mc:AlternateContent></w:tr></w:tbl></w:body></w:document>"#,
),
])
}
fn formula_table_general_number_format_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:tbl><w:tr><w:tc><w:p><w:r><w:t>10.25</w:t></w:r></w:p></w:tc><w:tc><w:p><w:fldSimple w:instr=" = SUM(LEFT) \* DollarText "><w:r><w:t>stale table dollar</w:t></w:r></w:fldSimple></w:p></w:tc></w:tr></w:tbl><w:tbl><w:tr><w:tc><w:p><w:r><w:t>31</w:t></w:r></w:p></w:tc><w:tc><w:p><w:fldSimple w:instr=" = SUM(LEFT) \* Hex "><w:r><w:t>stale table hex</w:t></w:r></w:fldSimple></w:p></w:tc></w:tr></w:tbl><w:tbl><w:tr><w:tc><w:p><w:r><w:t>21</w:t></w:r></w:p></w:tc><w:tc><w:p><w:fldSimple w:instr=" = SUM(LEFT) \* OrdText "><w:r><w:t>stale table ordinal text</w:t></w:r></w:fldSimple></w:p></w:tc></w:tr></w:tbl><w:tbl><w:tr><w:tc><w:p><w:r><w:t>10.25</w:t></w:r></w:p></w:tc><w:tc><w:p><w:fldSimple w:instr=" = SUM(LEFT) \* DollarText \* Upper "><w:r><w:t>stale table dollar upper</w:t></w:r></w:fldSimple></w:p></w:tc></w:tr></w:tbl></w:body></w:document>"#,
),
])
}
fn formula_table_deleted_preceding_field_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:del><w:p><w:fldSimple w:instr=" = SUM(LEFT) "><w:r><w:t>deleted formula</w:t></w:r></w:fldSimple></w:p></w:del><w:tbl><w:tr><w:tc><w:p><w:r><w:t>2</w:t></w:r></w:p></w:tc><w:tc><w:p><w:r><w:t>3</w:t></w:r></w:p></w:tc><w:tc><w:p><w:fldSimple w:instr=" = SUM(LEFT) "><w:r><w:t>stale visible sum</w:t></w:r></w:fldSimple></w:p></w:tc></w:tr></w:tbl></w:body></w:document>"#,
),
])
}
fn formula_table_alternate_content_preceding_field_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"><w:body><mc:AlternateContent><mc:Choice Requires="wps"><w:p/></mc:Choice><mc:Fallback><w:p><w:fldSimple w:instr=" = SUM(LEFT) "><w:r><w:t>fallback formula</w:t></w:r></w:fldSimple></w:p></mc:Fallback></mc:AlternateContent><w:tbl><w:tr><w:tc><w:p><w:r><w:t>2</w:t></w:r></w:p></w:tc><w:tc><w:p><w:r><w:t>3</w:t></w:r></w:p></w:tc><w:tc><w:p><w:fldSimple w:instr=" = SUM(LEFT) "><w:r><w:t>stale visible sum</w:t></w:r></w:fldSimple></w:p></w:tc></w:tr></w:tbl></w:body></w:document>"#,
),
])
}
fn formula_table_combined_reference_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:tbl><w:tr><w:tc><w:p><w:r><w:t>1</w:t></w:r></w:p></w:tc><w:tc><w:p><w:r><w:t>2</w:t></w:r></w:p></w:tc><w:tc><w:p><w:r><w:t>3</w:t></w:r></w:p></w:tc></w:tr><w:tr><w:tc><w:p><w:r><w:t>4</w:t></w:r></w:p></w:tc><w:tc><w:p><w:fldSimple w:instr=" = SUM(LEFT,ABOVE) "><w:r><w:t>stale left above sum</w:t></w:r></w:fldSimple></w:p></w:tc><w:tc><w:p><w:r><w:t>6</w:t></w:r></w:p></w:tc></w:tr><w:tr><w:tc><w:p><w:fldSimple w:instr=" = SUM(RIGHT;ABOVE) "><w:r><w:t>stale right above sum</w:t></w:r></w:fldSimple></w:p></w:tc><w:tc><w:p><w:r><w:t>5</w:t></w:r></w:p></w:tc><w:tc><w:p><w:r><w:t>6</w:t></w:r></w:p></w:tc></w:tr><w:tr><w:tc><w:p><w:r><w:t>7</w:t></w:r></w:p></w:tc><w:tc><w:p><w:fldSimple w:instr=" = COUNT(LEFT,RIGHT) "><w:r><w:t>stale side count</w:t></w:r></w:fldSimple></w:p></w:tc><w:tc><w:p><w:r><w:t>8</w:t></w:r></w:p></w:tc></w:tr><w:tr><w:tc><w:p><w:r><w:t>1</w:t></w:r></w:p></w:tc><w:tc><w:p><w:fldSimple w:instr=" = SUM(LEFT,RIGHT;ABOVE) "><w:r><w:t>cached mixed positional separators</w:t></w:r></w:fldSimple></w:p></w:tc><w:tc><w:p><w:r><w:t>2</w:t></w:r></w:p></w:tc></w:tr></w:tbl></w:body></w:document>"#,
),
])
}
fn formula_table_cell_reference_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:tbl><w:tr><w:tc><w:p><w:r><w:t>2</w:t></w:r></w:p></w:tc><w:tc><w:p><w:r><w:t>3</w:t></w:r></w:p></w:tc><w:tc><w:p><w:r><w:t>4</w:t></w:r></w:p></w:tc></w:tr><w:tr><w:tc><w:p><w:r><w:t>5</w:t></w:r></w:p></w:tc><w:tc><w:p><w:r><w:t>6</w:t></w:r></w:p></w:tc><w:tc><w:p><w:r><w:t>7</w:t></w:r></w:p></w:tc></w:tr><w:tr><w:tc><w:p><w:fldSimple w:instr=" = SUM(A1:B2) "><w:r><w:t>stale a1 range</w:t></w:r></w:fldSimple></w:p></w:tc><w:tc><w:p><w:fldSimple w:instr=" = PRODUCT(R1C2:R2C3) "><w:r><w:t>stale rncn range</w:t></w:r></w:fldSimple></w:p></w:tc><w:tc><w:p><w:fldSimple w:instr=" = SUM(A1,C2) "><w:r><w:t>stale a1 list</w:t></w:r></w:fldSimple></w:p></w:tc></w:tr></w:tbl><w:tbl><w:tr><w:tc><w:p><w:r><w:t>1</w:t></w:r></w:p></w:tc><w:tc><w:p><w:r><w:t>2</w:t></w:r></w:p></w:tc><w:tc><w:p><w:r><w:t>3</w:t></w:r></w:p></w:tc></w:tr><w:tr><w:tc><w:p><w:r><w:t>4</w:t></w:r></w:p></w:tc><w:tc><w:p><w:fldSimple w:instr=" = SUM(R) "><w:r><w:t>stale current row</w:t></w:r></w:fldSimple></w:p></w:tc><w:tc><w:p><w:r><w:t>6</w:t></w:r></w:p></w:tc></w:tr><w:tr><w:tc><w:p><w:r><w:t>7</w:t></w:r></w:p></w:tc><w:tc><w:p><w:r><w:t>8</w:t></w:r></w:p></w:tc><w:tc><w:p><w:r><w:t>9</w:t></w:r></w:p></w:tc></w:tr></w:tbl><w:tbl><w:tr><w:tc><w:p><w:r><w:t>1</w:t></w:r></w:p></w:tc><w:tc><w:p><w:r><w:t>2</w:t></w:r></w:p></w:tc><w:tc><w:p><w:r><w:t>3</w:t></w:r></w:p></w:tc></w:tr><w:tr><w:tc><w:p><w:r><w:t>4</w:t></w:r></w:p></w:tc><w:tc><w:p><w:fldSimple w:instr=" = SUM(C) "><w:r><w:t>stale current column</w:t></w:r></w:fldSimple></w:p></w:tc><w:tc><w:p><w:r><w:t>6</w:t></w:r></w:p></w:tc></w:tr><w:tr><w:tc><w:p><w:r><w:t>7</w:t></w:r></w:p></w:tc><w:tc><w:p><w:r><w:t>8</w:t></w:r></w:p></w:tc><w:tc><w:p><w:r><w:t>9</w:t></w:r></w:p></w:tc></w:tr></w:tbl><w:tbl><w:tr><w:tc><w:p><w:r><w:t>1</w:t></w:r></w:p></w:tc><w:tc><w:p><w:r><w:t>2</w:t></w:r></w:p></w:tc><w:tc><w:p><w:r><w:t>3</w:t></w:r></w:p></w:tc></w:tr><w:tr><w:tc><w:p><w:r><w:t>4</w:t></w:r></w:p></w:tc><w:tc><w:p><w:r><w:t>5</w:t></w:r></w:p></w:tc><w:tc><w:p><w:r><w:t>6</w:t></w:r></w:p></w:tc></w:tr><w:tr><w:tc><w:p><w:r><w:t>7</w:t></w:r></w:p></w:tc><w:tc><w:p><w:fldSimple w:instr=" = SUM(R2C1:R2C3) "><w:r><w:t>stale explicit row range</w:t></w:r></w:fldSimple></w:p></w:tc><w:tc><w:p><w:fldSimple w:instr=" = SUM(R1C1:R3C1) "><w:r><w:t>stale explicit column range</w:t></w:r></w:fldSimple></w:p></w:tc></w:tr></w:tbl><w:tbl><w:tr><w:tc><w:p><w:r><w:t>1</w:t></w:r></w:p></w:tc><w:tc><w:p><w:r><w:t>2</w:t></w:r></w:p></w:tc><w:tc><w:p><w:r><w:t>3</w:t></w:r></w:p></w:tc></w:tr><w:tr><w:tc><w:p><w:fldSimple w:instr=" = SUM(A1,B1;C1) "><w:r><w:t>cached mixed cell separators</w:t></w:r></w:fldSimple></w:p></w:tc></w:tr></w:tbl></w:body></w:document>"#,
),
])
}
fn formula_table_direct_cell_reference_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:tbl><w:tr><w:tc><w:p><w:r><w:t>2</w:t></w:r></w:p></w:tc><w:tc><w:p><w:r><w:t>3</w:t></w:r></w:p></w:tc><w:tc><w:p><w:r><w:t>n/a</w:t></w:r></w:p></w:tc></w:tr><w:tr><w:tc><w:p><w:fldSimple w:instr=" = A1 + R1C2 \# "0" "><w:r><w:t>stale direct expression</w:t></w:r></w:fldSimple></w:p></w:tc><w:tc><w:p><w:fldSimple w:instr=" = B1 "><w:r><w:t>stale direct cell</w:t></w:r></w:fldSimple></w:p></w:tc><w:tc><w:p><w:fldSimple w:instr=" = C1 "><w:r><w:t>cached nonnumeric direct cell</w:t></w:r></w:fldSimple></w:p></w:tc></w:tr></w:tbl></w:body></w:document>"#,
),
])
}
fn formula_table_nested_expression_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:tbl><w:tr><w:tc><w:p><w:r><w:t>4</w:t></w:r></w:p></w:tc><w:tc><w:p><w:r><w:t>6</w:t></w:r></w:p></w:tc><w:tc><w:p><w:fldSimple w:instr=" = IF(SUM(LEFT)>=10,10,0) "><w:r><w:t>stale nested if</w:t></w:r></w:fldSimple></w:p></w:tc></w:tr></w:tbl><w:tbl><w:tr><w:tc><w:p><w:r><w:t>1</w:t></w:r></w:p></w:tc><w:tc><w:p><w:r><w:t>2</w:t></w:r></w:p></w:tc><w:tc><w:p><w:r><w:t>3</w:t></w:r></w:p></w:tc></w:tr><w:tr><w:tc><w:p><w:r><w:t>3</w:t></w:r></w:p></w:tc><w:tc><w:p><w:fldSimple w:instr=" = AND(SUM(LEFT)<10,SUM(ABOVE)>=2) "><w:r><w:t>stale nested and</w:t></w:r></w:fldSimple></w:p></w:tc><w:tc><w:p><w:r><w:t>6</w:t></w:r></w:p></w:tc></w:tr></w:tbl><w:tbl><w:tr><w:tc><w:p><w:r><w:t>2</w:t></w:r></w:p></w:tc><w:tc><w:p><w:r><w:t>4</w:t></w:r></w:p></w:tc></w:tr><w:tr><w:tc><w:p><w:r><w:t>6</w:t></w:r></w:p></w:tc><w:tc><w:p><w:r><w:t>8</w:t></w:r></w:p></w:tc></w:tr><w:tr><w:tc><w:p><w:fldSimple w:instr=" = ROUND(AVERAGE(A1:B2),1) "><w:r><w:t>stale nested round</w:t></w:r></w:fldSimple></w:p></w:tc><w:tc><w:p/></w:tc></w:tr></w:tbl><w:tbl><w:tr><w:tc><w:p><w:r><w:t>1</w:t></w:r></w:p></w:tc><w:tc><w:p><w:fldSimple w:instr=" = IF(SUM(LEFT,RIGHT;ABOVE)>0,1,0) "><w:r><w:t>cached mixed nested table expression</w:t></w:r></w:fldSimple></w:p></w:tc><w:tc><w:p><w:r><w:t>2</w:t></w:r></w:p></w:tc></w:tr></w:tbl><w:tbl><w:tr><w:tc><w:p><w:r><w:t>4</w:t></w:r></w:p></w:tc><w:tc><w:p><w:r><w:t>6</w:t></w:r></w:p></w:tc><w:tc><w:p><w:fldSimple w:instr=" = SUM(LEFT,1) "><w:r><w:t>stale table literal sum</w:t></w:r></w:fldSimple></w:p></w:tc></w:tr></w:tbl><w:tbl><w:tr><w:tc><w:p><w:r><w:t>2</w:t></w:r></w:p></w:tc><w:tc><w:p><w:r><w:t>3</w:t></w:r></w:p></w:tc><w:tc><w:p><w:fldSimple w:instr=" = ROUND(SUM(LEFT,1),0) "><w:r><w:t>stale nested literal round</w:t></w:r></w:fldSimple></w:p></w:tc></w:tr></w:tbl><w:tbl><w:tr><w:tc><w:p><w:r><w:t>2</w:t></w:r></w:p></w:tc><w:tc><w:p><w:r><w:t>4</w:t></w:r></w:p></w:tc><w:tc><w:p><w:fldSimple w:instr=" = SUM(A1:B1,10) "><w:r><w:t>stale table range literal sum</w:t></w:r></w:fldSimple></w:p></w:tc></w:tr></w:tbl></w:body></w:document>"#,
),
])
}
fn formula_table_defined_reference_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:tbl><w:tr><w:tc><w:p><w:r><w:t>2</w:t></w:r></w:p></w:tc><w:tc><w:p><w:fldSimple w:instr=" = DEFINED(A1) "><w:r><w:t>stale defined direct cell</w:t></w:r></w:fldSimple></w:p></w:tc></w:tr></w:tbl><w:tbl><w:tr><w:tc><w:p><w:r><w:t>4</w:t></w:r></w:p></w:tc><w:tc><w:p><w:r><w:t>6</w:t></w:r></w:p></w:tc><w:tc><w:p><w:fldSimple w:instr=" = DEFINED(SUM(LEFT,1)) "><w:r><w:t>stale defined aggregate</w:t></w:r></w:fldSimple></w:p></w:tc></w:tr></w:tbl><w:tbl><w:tr><w:tc><w:p><w:r><w:t>5</w:t></w:r></w:p></w:tc><w:tc><w:p><w:fldSimple w:instr=" = DEFINED(Z99) "><w:r><w:t>stale missing defined</w:t></w:r></w:fldSimple></w:p></w:tc></w:tr></w:tbl><w:tbl><w:tr><w:tc><w:p><w:r><w:t>5</w:t></w:r></w:p></w:tc><w:tc><w:p><w:fldSimple w:instr=" = IF(DEFINED(Z99),Z99,7) "><w:r><w:t>stale guarded missing defined</w:t></w:r></w:fldSimple></w:p></w:tc></w:tr></w:tbl><w:tbl><w:tr><w:tc><w:p><w:r><w:t>1</w:t></w:r></w:p></w:tc><w:tc><w:p><w:fldSimple w:instr=" = DEFINED() "><w:r><w:t>cached empty defined</w:t></w:r></w:fldSimple></w:p></w:tc></w:tr></w:tbl></w:body></w:document>"#,
),
])
}
fn formula_table_ragged_reference_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:tbl><w:tr><w:tc><w:p><w:r><w:t>2</w:t></w:r></w:p></w:tc><w:tc><w:p><w:r><w:t>4</w:t></w:r></w:p></w:tc><w:tc><w:p><w:r><w:t>6</w:t></w:r></w:p></w:tc></w:tr><w:tr><w:tc><w:p><w:r><w:t>3</w:t></w:r></w:p></w:tc></w:tr><w:tr><w:tc><w:p><w:fldSimple w:instr=" = SUM(A1:C2) "><w:r><w:t>stale ragged range</w:t></w:r></w:fldSimple></w:p></w:tc><w:tc><w:p><w:fldSimple w:instr=" = SUM(C) "><w:r><w:t>stale ragged column</w:t></w:r></w:fldSimple></w:p></w:tc><w:tc><w:p><w:fldSimple w:instr=" = SUM(ABOVE) "><w:r><w:t>stale ragged above</w:t></w:r></w:fldSimple></w:p></w:tc></w:tr></w:tbl><w:tbl><w:tr><w:tc><w:p><w:r><w:t>1</w:t></w:r></w:p></w:tc></w:tr><w:tr><w:tc><w:p><w:r><w:t>0</w:t></w:r></w:p></w:tc><w:tc><w:p><w:fldSimple w:instr=" = SUM(ABOVE) "><w:r><w:t>cached absent above</w:t></w:r></w:fldSimple></w:p></w:tc></w:tr></w:tbl></w:body></w:document>"#,
),
])
}
fn formula_table_if_short_circuit_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:tbl><w:tr><w:tc><w:p><w:r><w:t>2</w:t></w:r></w:p></w:tc><w:tc><w:p><w:r><w:t>3</w:t></w:r></w:p></w:tc><w:tc><w:p><w:fldSimple w:instr=" = IF(SUM(LEFT)>0,SUM(LEFT),Z99) "><w:r><w:t>stale guarded left</w:t></w:r></w:fldSimple></w:p></w:tc></w:tr></w:tbl><w:tbl><w:tr><w:tc><w:p><w:r><w:t>0</w:t></w:r></w:p></w:tc><w:tc><w:p><w:fldSimple w:instr=" = IF(SUM(LEFT)>0,Z99,9) "><w:r><w:t>stale guarded literal</w:t></w:r></w:fldSimple></w:p></w:tc></w:tr></w:tbl><w:tbl><w:tr><w:tc><w:p><w:r><w:t>4</w:t></w:r></w:p></w:tc><w:tc><w:p><w:fldSimple w:instr=" = IF(SUM(LEFT)>0;7;Z99) "><w:r><w:t>stale semicolon guarded</w:t></w:r></w:fldSimple></w:p></w:tc></w:tr></w:tbl><w:tbl><w:tr><w:tc><w:p><w:r><w:t>5</w:t></w:r></w:p></w:tc><w:tc><w:p><w:fldSimple w:instr=" = IF(SUM(LEFT)>0,Z99,9) "><w:r><w:t>cached selected table branch</w:t></w:r></w:fldSimple></w:p></w:tc></w:tr></w:tbl></w:body></w:document>"#,
),
])
}
fn formula_comparison_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:fldSimple w:instr=" = IF(2 > 1, 10, 20) "><w:r><w:t>stale greater if</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" = IF(2 < 1, 10, 20) "><w:r><w:t>stale less if</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" = 2 = 2 "><w:r><w:t>stale equal</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" = 3 <> 3 "><w:r><w:t>stale not equal false</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" = AND(2 >= 2, 3 <= 4, 5 <> 6) "><w:r><w:t>stale logical comparisons</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" = OR(1 > 2, 3 < 4) "><w:r><w:t>stale or comparison</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" = NOT(7 = 8) "><w:r><w:t>stale not comparison</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn quote_field_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:fldSimple w:instr=" QUOTE "literal text" "><w:r><w:t>stale literal</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" QUOTE "mixed words" \* Caps "><w:r><w:t>stale caps</w:t></w:r></w:fldSimple></w:p><w:p><w:r><w:fldChar w:fldCharType="begin"/></w:r><w:r><w:instrText> QUOTE "word" \* Upper </w:instrText></w:r><w:r><w:fldChar w:fldCharType="separate"/></w:r><w:r><w:t>stale upper</w:t></w:r><w:r><w:fldChar w:fldCharType="end"/></w:r></w:p><w:p><w:fldSimple w:instr=" QUOTE PlainToken "><w:r><w:t>stale unquoted token</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" QUOTE plain words \* Upper "><w:r><w:t>stale unquoted phrase</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" QUOTE "broken literal "><w:r><w:t>cached broken quote</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn inserted_content_field_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:fldSimple w:instr=" INCLUDETEXT "appendix.docx" "><w:r><w:t>Appendix text</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" INCLUDEPICTURE "chart.png" "><w:r><w:t>Chart preview</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" LINK Excel.Sheet.12 "book.xlsx" "Sheet1!R1C1" "><w:r><w:t>42</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" EMBED Excel.Sheet.12 "><w:r><w:t>Embedded object</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" DATABASE \d "source.accdb" "><w:r><w:t>Rows</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" DDE Excel "book.xlsx" "R1C1" "><w:r><w:t>DDE value</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" DDEAUTO Excel "book.xlsx" "R2C1" "><w:r><w:t>Auto DDE value</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" IMPORT "legacy.wmf" "><w:r><w:t>Imported object</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" INCLUDE "legacy.doc" "><w:r><w:t>Included text</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" AUTOTEXT Signature "><w:r><w:t>AutoText signature</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" AUTOTEXTLIST "Choose clause" \s Legal "><w:r><w:t>AutoText list</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn mail_merge_helper_field_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:fldSimple w:instr=" ADDRESSBLOCK "><w:r><w:t>Acme Corp</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" GREETINGLINE "><w:r><w:t>Dear Hyunjo,</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" MERGEREC "><w:r><w:t>7</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" MERGESEQ "><w:r><w:t>3</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn reference_index_field_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:fldSimple w:instr=" BIBLIOGRAPHY \l 1033 "><w:r><w:t>Works cited</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" CITATION Smith2026 \l 1033 "><w:r><w:t>(Smith, 2026)</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" INDEX \e " - " "><w:r><w:t>Index preview</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" TOA \c "1" "><w:r><w:t>Authorities</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" TA \l "Case v. Example" \c 1 "><w:r><w:t>Case v. Example</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" XE "Term" "><w:r><w:t>Term</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" RD "appendix.docx" "><w:r><w:t>Referenced doc</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" TA \l"Compact Case" \c2 "><w:r><w:t>Compact Case</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" TA \sShortEntry \c3 "><w:r><w:t>Short Entry</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" XE "See Term" \t"See Also" "><w:r><w:t>See Term</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" RD "formatted-appendix.docx" \*MERGEFORMAT "><w:r><w:t>Formatted referenced doc</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" TA \l "Formatted Case" \c 1 \*CHARFORMAT "><w:r><w:t>Formatted Case</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" XE "Formatted Term" \*MERGEFORMAT "><w:r><w:t>Formatted Term</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" XE "Duplicate Format" \* Upper \* Lower "><w:r><w:t>Duplicate Format</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" TA \l "Broken Case" \c 99 "><w:r><w:t>Broken Case</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn reference_index_unquoted_multi_token_marker_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:fldSimple w:instr=" TA \l Case v. Example \c 1 "><w:r><w:t>cached unquoted ta marker</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" XE "Mercury" \t See planets \* FirstCap "><w:r><w:t>cached unquoted xe marker</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn numbering_field_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:fldSimple w:instr=" AUTONUM "><w:r><w:t>stale autonum one</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" AUTONUM \* MERGEFORMAT "><w:r><w:t>stale autonum two</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" AUTONUM \* roman "><w:r><w:t>stale autonum roman</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" AUTONUM \* Unknown "><w:r><w:t>cached unsupported autonum</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" AUTONUM "><w:r><w:t>stale autonum after unsupported</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" AUTONUM \s. "><w:r><w:t>stale autonum separator</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" AUTONUM \s ")" "><w:r><w:t>stale quoted autonum separator</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" AUTONUMLGL "><w:r><w:t>cached legal number</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" AUTONUMLGL \* roman "><w:r><w:t>cached legal roman</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" AUTONUMOUT "><w:r><w:t>cached outline number</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" AUTONUMOUT \* roman "><w:r><w:t>cached outline roman</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" LISTNUM LegalDefault \l 2 "><w:r><w:t>cached list number</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" BIDIOUTLINE "><w:r><w:t>cached bidi outline</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" BIDIOUTLINE \x "><w:r><w:t>cached malformed bidi outline</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn listnum_number_default_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:fldSimple w:instr=" LISTNUM NumberDefault "><w:r><w:t>stale listnum one</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" LISTNUM NumberDefault \* MERGEFORMAT "><w:r><w:t>stale listnum mergeformat</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" LISTNUM NumberDefault \*CHARFORMAT "><w:r><w:t>stale listnum charformat</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" LISTNUM NumberDefault \s 4 "><w:r><w:t>stale listnum reset</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" LISTNUM NumberDefault "><w:r><w:t>stale listnum after reset</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" LISTNUM NumberDefault \* roman "><w:r><w:t>stale listnum roman</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" LISTNUM NumberDefault \l 2 "><w:r><w:t>cached nested listnum</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" LISTNUM LegalDefault "><w:r><w:t>cached legal listnum</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" LISTNUM "NumberDefault" "><w:r><w:t>stale quoted listnum</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" LISTNUM "><w:r><w:t>stale unnamed listnum</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn sequence_numbering_text_format_field_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:fldSimple w:instr=" SEQ Figure \* CardText \* Upper "><w:r><w:t>stale sequence card</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" SEQ Figure \* roman \* Upper "><w:r><w:t>stale sequence roman</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" SEQ Invoice \r 21 \* DollarText "><w:r><w:t>stale sequence dollars</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" AUTONUM \* CardText \* Upper "><w:r><w:t>stale autonum card</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" AUTONUM \* roman \* Upper "><w:r><w:t>stale autonum roman</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" LISTNUM NumberDefault \* CardText \* Upper "><w:r><w:t>stale listnum card</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" LISTNUM NumberDefault \* roman \* Upper "><w:r><w:t>stale listnum roman</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn document_structure_field_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/><Override PartName="/docProps/core.xml" ContentType="application/vnd.openxmlformats-package.core-properties+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/><Relationship Id="rIdCore" Type="http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties" Target="docProps/core.xml"/></Relationships>"#,
),
(
"docProps/core.xml",
r#"<cp:coreProperties xmlns:cp="http://schemas.openxmlformats.org/package/2006/metadata/core-properties"><cp:revision>12</cp:revision></cp:coreProperties>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:fldSimple w:instr=" REVNUM "><w:r><w:t>4</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" SECTION "><w:r><w:t>2</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" SECTIONPAGES "><w:r><w:t>5</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" STYLEREF "Heading 1" \n "><w:r><w:t>Executive Summary</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" STYLEREF "Heading 1 "><w:r><w:t>cached broken style ref</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" STYLEREF \p "Heading 1" "><w:r><w:t>cached switch-first style ref</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn revision_number_text_format_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/><Override PartName="/docProps/core.xml" ContentType="application/vnd.openxmlformats-package.core-properties+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/><Relationship Id="rIdCore" Type="http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties" Target="docProps/core.xml"/></Relationships>"#,
),
(
"docProps/core.xml",
r#"<cp:coreProperties xmlns:cp="http://schemas.openxmlformats.org/package/2006/metadata/core-properties"><cp:revision>draft REVISION</cp:revision></cp:coreProperties>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:fldSimple w:instr=" REVNUM \* Upper "><w:r><w:t>stale upper revision</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" REVNUM \*Lower "><w:r><w:t>stale lower revision</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" REVNUM \* Caps "><w:r><w:t>stale caps revision</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" REVNUM \* FirstCap "><w:r><w:t>stale first-cap revision</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn doc_property_revision_number_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/><Override PartName="/docProps/core.xml" ContentType="application/vnd.openxmlformats-package.core-properties+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/><Relationship Id="rIdCore" Type="http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties" Target="docProps/core.xml"/></Relationships>"#,
),
(
"docProps/core.xml",
r#"<cp:coreProperties xmlns:cp="http://schemas.openxmlformats.org/package/2006/metadata/core-properties"><cp:revision>12</cp:revision></cp:coreProperties>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:fldSimple w:instr=" DOCPROPERTY RevisionNumber "><w:r><w:t>stale revnum property</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" DOCPROPERTY "Revision Number" "><w:r><w:t>stale spaced revnum</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn doc_property_last_author_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/><Override PartName="/docProps/core.xml" ContentType="application/vnd.openxmlformats-package.core-properties+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/><Relationship Id="rIdCore" Type="http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties" Target="docProps/core.xml"/></Relationships>"#,
),
(
"docProps/core.xml",
r#"<cp:coreProperties xmlns:cp="http://schemas.openxmlformats.org/package/2006/metadata/core-properties"><cp:lastModifiedBy>Dana Reviewer</cp:lastModifiedBy></cp:coreProperties>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:fldSimple w:instr=" DOCPROPERTY "Last Author" "><w:r><w:t>stale author name</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" DOCPROPERTY LastAuthor "><w:r><w:t>stale author name 2</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn context_document_info_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:fldSimple w:instr=" DATE \@ "yyyy-MM-dd" "><w:r><w:t>stale cached date</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" TIME \@ "HH:mm" "><w:r><w:t>stale cached time</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" DATE "><w:r><w:t>stale plain date</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" USERNAME "><w:r><w:t>stale user</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" USERNAME "Override Name" "><w:r><w:t>stale override</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn context_merge_include_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:fldSimple w:instr=" MERGEFIELD "Client Name" \* Upper "><w:r><w:t>stale client</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" MERGEFIELD UncoveredName "><w:r><w:t>stale uncovered merge</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" INCLUDETEXT "appendix.docx" "><w:r><w:t>stale appendix</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" INCLUDETEXT missing.docx "><w:r><w:t>stale missing include</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn numeric_doc_info_star_format_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/><Override PartName="/docProps/app.xml" ContentType="application/vnd.openxmlformats-officedocument.extended-properties+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/><Relationship Id="rIdApp" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties" Target="docProps/app.xml"/></Relationships>"#,
),
(
"docProps/app.xml",
r#"<Properties xmlns="http://schemas.openxmlformats.org/officeDocument/2006/extended-properties"><Pages>12</Pages><Words>321</Words></Properties>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:fldSimple w:instr=" NUMPAGES \* roman "><w:r><w:t>stale roman pages</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" NUMPAGES \* ROMAN "><w:r><w:t>stale upper roman pages</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" NUMPAGES \* Arabic "><w:r><w:t>stale arabic pages</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" NUMWORDS \* Ordinal "><w:r><w:t>stale ordinal words</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn edittime_number_format_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/><Override PartName="/docProps/app.xml" ContentType="application/vnd.openxmlformats-officedocument.extended-properties+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/><Relationship Id="rIdApp" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties" Target="docProps/app.xml"/></Relationships>"#,
),
(
"docProps/app.xml",
r#"<Properties xmlns="http://schemas.openxmlformats.org/officeDocument/2006/extended-properties"><TotalTime>7</TotalTime></Properties>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:fldSimple w:instr=" EDITTIME \* roman "><w:r><w:t>stale roman time</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" EDITTIME \* Arabic "><w:r><w:t>stale arabic time</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn section_field_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:fldSimple w:instr=" SECTION "><w:r><w:t>stale first section</w:t></w:r></w:fldSimple></w:p><w:p><w:pPr><w:sectPr><w:type w:val="nextPage"/></w:sectPr></w:pPr></w:p><w:p><w:fldSimple w:instr=" SECTION "><w:r><w:t>stale second section</w:t></w:r></w:fldSimple></w:p><w:p><w:pPr><w:sectPr/></w:pPr></w:p><w:p><w:r><w:fldChar w:fldCharType="begin"/></w:r><w:r><w:instrText> SECTION \* MERGEFORMAT </w:instrText></w:r><w:r><w:fldChar w:fldCharType="separate"/></w:r><w:r><w:t>stale third section</w:t></w:r><w:r><w:fldChar w:fldCharType="end"/></w:r></w:p><w:sectPr/></w:body></w:document>"#,
),
])
}
fn section_field_text_format_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:fldSimple w:instr=" SECTION \* ROMAN "><w:r><w:t>stale roman section</w:t></w:r></w:fldSimple></w:p><w:p><w:pPr><w:sectPr><w:type w:val="nextPage"/></w:sectPr></w:pPr></w:p><w:p><w:fldSimple w:instr=" SECTION \* CardText \* Upper "><w:r><w:t>stale card section</w:t></w:r></w:fldSimple></w:p><w:p><w:pPr><w:sectPr><w:type w:val="nextPage"/></w:sectPr></w:pPr></w:p><w:p><w:fldSimple w:instr=" SECTION \* Ordinal "><w:r><w:t>stale ordinal section</w:t></w:r></w:fldSimple></w:p><w:sectPr/></w:body></w:document>"#,
),
])
}
fn section_field_invalid_switch_alignment_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:fldSimple w:instr=" SECTION \* Unknown "><w:r><w:t>cached invalid section</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" SECTION "><w:r><w:t>stale valid section</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn section_alternate_content_break_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="wps"><w:body><mc:AlternateContent><mc:Choice Requires="wps"><w:p><w:pPr><w:sectPr/></w:pPr></w:p></mc:Choice><mc:Fallback><w:p><w:pPr><w:sectPr/></w:pPr></w:p></mc:Fallback></mc:AlternateContent><w:p><w:fldSimple w:instr=" SECTION "><w:r><w:t>stale alternate section</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn section_pages_field_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:fldSimple w:instr=" SECTIONPAGES "></w:fldSimple></w:p><w:p><w:r><w:br w:type="page"/></w:r></w:p><w:p><w:fldSimple w:instr=" SECTIONPAGES \* ROMAN "></w:fldSimple></w:p><w:p><w:pPr><w:pageBreakBefore/></w:pPr><w:fldSimple w:instr=" SECTIONPAGES \* CardText \* Upper "></w:fldSimple></w:p><w:p><w:pPr><w:sectPr><w:type w:val="nextPage"/></w:sectPr></w:pPr></w:p><w:p><w:r><w:fldChar w:fldCharType="begin"/></w:r><w:r><w:instrText> SECTIONPAGES \* Ordinal </w:instrText></w:r><w:r><w:fldChar w:fldCharType="separate"/></w:r><w:r><w:fldChar w:fldCharType="end"/></w:r></w:p><w:sectPr/></w:body></w:document>"#,
),
])
}
fn section_pages_cached_result_text_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:fldSimple w:instr=" SECTIONPAGES "><w:r><w:t>stale pages</w:t></w:r></w:fldSimple></w:p><w:p><w:r><w:br w:type="page"/></w:r></w:p><w:p><w:r><w:fldChar w:fldCharType="begin"/></w:r><w:r><w:instrText> SECTIONPAGES \* ROMAN </w:instrText></w:r><w:r><w:fldChar w:fldCharType="separate"/></w:r><w:r><w:t>stale roman pages</w:t></w:r><w:r><w:fldChar w:fldCharType="end"/></w:r></w:p><w:sectPr/></w:body></w:document>"#,
),
])
}
fn section_pages_symbol_content_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:r><w:sym w:font="Symbol" w:char="F0B7"/></w:r></w:p><w:p><w:fldSimple w:instr=" SECTIONPAGES "></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn section_pages_note_mark_content_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:r><w:footnoteReference w:id="1"/></w:r></w:p><w:p><w:fldSimple w:instr=" SECTIONPAGES "></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn section_pages_endnote_mark_content_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:r><w:endnoteReference w:id="2"/></w:r></w:p><w:p><w:fldSimple w:instr=" SECTIONPAGES "></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn section_pages_stale_computed_field_marker_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:fldSimple w:instr=" SET SimpleHidden "Plain" "><w:r><w:footnoteReference w:id="1"/></w:r></w:fldSimple></w:p><w:p><w:r><w:fldChar w:fldCharType="begin"/></w:r><w:r><w:instrText> SET ComplexHidden "Plain" </w:instrText></w:r><w:r><w:fldChar w:fldCharType="separate"/></w:r><w:r><w:footnoteReference w:id="2"/></w:r><w:r><w:fldChar w:fldCharType="end"/></w:r></w:p><w:p><w:fldSimple w:instr=" SECTIONPAGES "><w:r><w:t>cached section pages</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn section_pages_empty_document_info_result_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/><Override PartName="/docProps/core.xml" ContentType="application/vnd.openxmlformats-package.core-properties+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/><Relationship Id="rIdCore" Type="http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties" Target="docProps/core.xml"/></Relationships>"#,
),
(
"docProps/core.xml",
r#"<cp:coreProperties xmlns:cp="http://schemas.openxmlformats.org/package/2006/metadata/core-properties" xmlns:dc="http://purl.org/dc/elements/1.1/"><dc:title/></cp:coreProperties>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:fldSimple w:instr=" TITLE "><w:r><w:t>stale section title</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" SECTIONPAGES "><w:r><w:t>cached section pages</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn section_pages_empty_revision_number_result_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/><Override PartName="/docProps/core.xml" ContentType="application/vnd.openxmlformats-package.core-properties+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/><Relationship Id="rIdCore" Type="http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties" Target="docProps/core.xml"/></Relationships>"#,
),
(
"docProps/core.xml",
r#"<cp:coreProperties xmlns:cp="http://schemas.openxmlformats.org/package/2006/metadata/core-properties"><cp:revision/></cp:coreProperties>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:fldSimple w:instr=" REVNUM "><w:r><w:t>stale section revision</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" SECTIONPAGES "><w:r><w:t>cached section revision pages</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn section_pages_empty_legacy_form_result_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:fldSimple w:instr=" FORMDROPDOWN "><w:ffData><w:ddList><w:result w:val="0"/><w:listEntry w:val=""/></w:ddList></w:ffData><w:r><w:t>stale section option</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" SECTIONPAGES "><w:r><w:t>cached section form pages</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn section_pages_bookmark_merge_control_result_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:fldSimple w:instr=" NEXTIF Gate = "Ready" "><w:r><w:t>stale section merge control</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" SECTIONPAGES "><w:r><w:t>cached section bookmark pages</w:t></w:r></w:fldSimple></w:p><w:p><w:pPr><w:sectPr><w:type w:val="nextPage"/></w:sectPr></w:pPr></w:p><w:p><w:bookmarkStart w:id="7" w:name="Gate"/><w:r><w:t>Ready</w:t></w:r><w:bookmarkEnd w:id="7"/></w:p><w:sectPr/></w:body></w:document>"#,
),
])
}
fn section_pages_bookmark_if_result_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:fldSimple w:instr=" IF Gate = "Ready" "" "" "><w:r><w:t>stale section if</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" SECTIONPAGES "><w:r><w:t>cached section if pages</w:t></w:r></w:fldSimple></w:p><w:p><w:pPr><w:sectPr><w:type w:val="nextPage"/></w:sectPr></w:pPr></w:p><w:p><w:bookmarkStart w:id="7" w:name="Gate"/><w:r><w:t>Ready</w:t></w:r><w:bookmarkEnd w:id="7"/></w:p><w:sectPr/></w:body></w:document>"#,
),
])
}
fn section_pages_bookmark_formula_result_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:fldSimple w:instr=" = InvoiceSubtotal + 8 "/></w:p><w:p><w:fldSimple w:instr=" SECTIONPAGES "><w:r><w:t>cached section formula pages</w:t></w:r></w:fldSimple></w:p><w:p><w:pPr><w:sectPr><w:type w:val="nextPage"/></w:sectPr></w:pPr></w:p><w:p><w:bookmarkStart w:id="7" w:name="InvoiceSubtotal"/><w:r><w:t>42</w:t></w:r><w:bookmarkEnd w:id="7"/></w:p><w:sectPr/></w:body></w:document>"#,
),
])
}
fn section_pages_empty_ref_result_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:bookmarkStart w:id="1" w:name="EmptyTarget"/><w:bookmarkEnd w:id="1"/></w:p><w:p><w:fldSimple w:instr=" REF EmptyTarget "><w:r><w:t>stale empty section ref</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" SECTIONPAGES "><w:r><w:t>cached section pages</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn section_pages_empty_direct_bookmark_result_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:bookmarkStart w:id="1" w:name="EmptyTarget"/><w:bookmarkEnd w:id="1"/></w:p><w:p><w:fldSimple w:instr=" EmptyTarget "><w:r><w:t>stale empty direct section ref</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" SECTIONPAGES "><w:r><w:t>cached section pages</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn style_ref_field_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/styles.xml",
r#"<w:styles xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:style w:type="paragraph" w:styleId=" Heading1 "><w:name w:val=" heading 1 "/></w:style><w:style w:type="paragraph" w:styleId=" CustomCallout "><w:name w:val=" Custom Heading "/></w:style></w:styles>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:pPr><w:pStyle w:val=" Heading1 "/></w:pPr><w:r><w:t>Executive Summary</w:t></w:r></w:p><w:p><w:fldSimple w:instr=" STYLEREF "heading 1" "><w:r><w:t>stale heading style</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" STYLEREF "heading 1" \p "><w:r><w:t>stale heading relative</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" STYLEREF \p "heading 1" "><w:r><w:t>stale switch-first heading relative</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" STYLEREF CustomCallout "><w:r><w:t>stale forward style</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" STYLEREF CustomCallout \p \* Upper "><w:r><w:t>stale forward relative</w:t></w:r></w:fldSimple></w:p><w:p><w:pPr><w:pStyle w:val=" CustomCallout "/></w:pPr><w:r><w:t>Forward Finding</w:t></w:r></w:p><w:p><w:r><w:fldChar w:fldCharType="begin"/></w:r><w:r><w:instrText> STYLEREF "Custom Heading" \* MERGEFORMAT </w:instrText></w:r><w:r><w:fldChar w:fldCharType="separate"/></w:r><w:r><w:t>stale custom style</w:t></w:r><w:r><w:fldChar w:fldCharType="end"/></w:r></w:p></w:body></w:document>"#,
),
])
}
fn style_ref_unquoted_multi_token_style_name_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/styles.xml",
r#"<w:styles xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:style w:type="paragraph" w:styleId="Heading1"><w:name w:val="Heading 1"/></w:style><w:style w:type="paragraph" w:styleId="CustomCallout"><w:name w:val="Custom Heading"/></w:style></w:styles>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:pPr><w:pStyle w:val="Heading1"/></w:pPr><w:r><w:t>Executive Summary</w:t></w:r></w:p><w:p><w:fldSimple w:instr=" STYLEREF Heading 1 \* Upper "><w:r><w:t>stale unquoted heading</w:t></w:r></w:fldSimple></w:p><w:p><w:pPr><w:pStyle w:val="CustomCallout"/></w:pPr><w:r><w:t>Forward Finding</w:t></w:r></w:p><w:p><w:r><w:fldChar w:fldCharType="begin"/></w:r><w:r><w:instrText> STYLEREF Custom Heading \* MERGEFORMAT </w:instrText></w:r><w:r><w:fldChar w:fldCharType="separate"/></w:r><w:r><w:t>stale unquoted custom style</w:t></w:r><w:r><w:fldChar w:fldCharType="end"/></w:r></w:p></w:body></w:document>"#,
),
])
}
fn style_ref_deleted_heading_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/styles.xml",
r#"<w:styles xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:style w:type="paragraph" w:styleId="Heading1"><w:name w:val="heading 1"/></w:style></w:styles>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:pPr><w:pStyle w:val="Heading1"/></w:pPr><w:r><w:t>Visible Heading</w:t></w:r></w:p><w:del><w:p><w:pPr><w:pStyle w:val="Heading1"/></w:pPr><w:r><w:t>Deleted Heading</w:t></w:r></w:p></w:del><w:moveFrom><w:p><w:pPr><w:pStyle w:val="Heading1"/></w:pPr><w:r><w:t>Moved Heading</w:t></w:r></w:p></w:moveFrom><w:p><w:fldSimple w:instr=" STYLEREF "heading 1" "><w:r><w:t>stale style ref</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn style_ref_property_revision_heading_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/styles.xml",
r#"<w:styles xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:style w:type="paragraph" w:styleId="Heading1"><w:name w:val="heading 1"/></w:style></w:styles>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:pPr><w:pPrChange w:id="9" w:author="Reviewer"><w:pPr><w:pStyle w:val="Heading1"/></w:pPr></w:pPrChange></w:pPr><w:r><w:t>Former heading only</w:t></w:r></w:p><w:p><w:fldSimple w:instr=" STYLEREF "heading 1" "><w:r><w:t>stale before current heading</w:t></w:r></w:fldSimple></w:p><w:p><w:pPr><w:pStyle w:val="Heading1"/></w:pPr><w:r><w:t>Current Heading</w:t></w:r></w:p><w:p><w:fldSimple w:instr=" STYLEREF "heading 1" "><w:r><w:t>stale after current heading</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn style_ref_alternate_content_heading_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/styles.xml",
r#"<w:styles xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:style w:type="paragraph" w:styleId="Heading1"><w:name w:val="heading 1"/></w:style></w:styles>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="wps"><w:body><mc:AlternateContent><mc:Choice Requires="wps"><w:p><w:pPr><w:pStyle w:val="Heading1"/></w:pPr><w:r><w:t>Choice </w:t><mc:AlternateContent><mc:Choice Requires="wps"><w:t>Heading</w:t></mc:Choice><mc:Fallback><w:t>Fallback Inline</w:t></mc:Fallback></mc:AlternateContent></w:r></w:p></mc:Choice><mc:Fallback><w:p><w:pPr><w:pStyle w:val="Heading1"/></w:pPr><w:r><w:t>Fallback Heading</w:t></w:r></w:p></mc:Fallback></mc:AlternateContent><w:p><w:fldSimple w:instr=" STYLEREF "heading 1" "><w:r><w:t>stale style ref</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn style_ref_simple_field_source_text_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/styles.xml",
r#"<w:styles xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:style w:type="paragraph" w:styleId="Heading1"><w:name w:val="heading 1"/></w:style></w:styles>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:pPr><w:pStyle w:val="Heading1"/></w:pPr><w:r><w:t>Chapter </w:t></w:r><w:fldSimple w:instr=" SEQ Chapter "><w:r><w:t>1</w:t></w:r></w:fldSimple><w:r><w:t>: Scope</w:t></w:r></w:p><w:p><w:fldSimple w:instr=" STYLEREF "heading 1" "><w:r><w:t>stale simple-field source</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" STYLEREF "heading 1" \* Upper "><w:r><w:t>stale upper simple-field source</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn style_ref_stale_simple_field_source_text_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/styles.xml",
r#"<w:styles xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:style w:type="paragraph" w:styleId="Heading1"><w:name w:val="heading 1"/></w:style></w:styles>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:pPr><w:pStyle w:val="Heading1"/></w:pPr><w:r><w:t>Chapter </w:t></w:r><w:fldSimple w:instr=" QUOTE "Computed" "><w:r><w:t>stale simple source</w:t></w:r></w:fldSimple><w:r><w:t> Scope</w:t></w:r></w:p><w:p><w:fldSimple w:instr=" STYLEREF "heading 1" "><w:r><w:t>stale style source</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" STYLEREF "heading 1" \* Upper "><w:r><w:t>stale upper style source</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn style_ref_legacy_form_source_text_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/styles.xml",
r#"<w:styles xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:style w:type="paragraph" w:styleId="Heading1"><w:name w:val="heading 1"/></w:style></w:styles>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:fldSimple w:instr=" FORMDROPDOWN "><w:ffData><w:ddList><w:result w:val="1"/><w:listEntry w:val="1"/><w:listEntry w:val="99"/></w:ddList></w:ffData><w:r><w:t>stale prior form</w:t></w:r></w:fldSimple></w:p><w:p><w:pPr><w:pStyle w:val="Heading1"/></w:pPr><w:r><w:t>Choice </w:t></w:r><w:fldSimple w:instr=" FORMDROPDOWN "><w:ffData><w:ddList><w:result w:val="1"/><w:listEntry w:val="3"/><w:listEntry w:val="7"/></w:ddList></w:ffData><w:r><w:t>stale source form</w:t></w:r></w:fldSimple><w:r><w:t> ready</w:t></w:r></w:p><w:p><w:fldSimple w:instr=" STYLEREF "heading 1" "><w:r><w:t>stale legacy form style source</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" STYLEREF "heading 1" \* Upper "><w:r><w:t>stale upper legacy form style source</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn style_ref_empty_simple_field_source_text_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/styles.xml",
r#"<w:styles xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:style w:type="paragraph" w:styleId="Heading1"><w:name w:val="heading 1"/></w:style></w:styles>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:pPr><w:pStyle w:val="Heading1"/></w:pPr><w:r><w:t>Chapter </w:t></w:r><w:fldSimple w:instr=" QUOTE "Computed" "/><w:r><w:t> Scope</w:t></w:r></w:p><w:p><w:fldSimple w:instr=" STYLEREF "heading 1" "><w:r><w:t>stale empty style source</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" STYLEREF "heading 1" \* Upper "><w:r><w:t>stale upper empty style source</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn style_ref_nested_empty_simple_field_source_text_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/styles.xml",
r#"<w:styles xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:style w:type="paragraph" w:styleId="Heading1"><w:name w:val="heading 1"/></w:style></w:styles>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:pPr><w:pStyle w:val="Heading1"/></w:pPr><w:r><w:t>Chapter </w:t></w:r><w:fldSimple w:instr=" CUSTOM outer "><w:r><w:t>Prefix </w:t></w:r><w:fldSimple w:instr=" QUOTE "Inner" "/><w:r><w:t> Suffix</w:t></w:r></w:fldSimple><w:r><w:t> Done</w:t></w:r></w:p><w:p><w:fldSimple w:instr=" STYLEREF "heading 1" "><w:r><w:t>stale nested empty style source</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" STYLEREF "heading 1" \* Upper "><w:r><w:t>stale upper nested empty style source</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn style_ref_nested_simple_field_source_text_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/styles.xml",
r#"<w:styles xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:style w:type="paragraph" w:styleId="Heading1"><w:name w:val="heading 1"/></w:style></w:styles>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:pPr><w:pStyle w:val="Heading1"/></w:pPr><w:r><w:t>Chapter </w:t></w:r><w:fldSimple w:instr=" CUSTOM outer "><w:r><w:t>Prefix </w:t></w:r><w:fldSimple w:instr=" QUOTE "Inner" "><w:r><w:t>stale inner</w:t></w:r></w:fldSimple><w:r><w:t> Suffix</w:t></w:r></w:fldSimple><w:r><w:t> Done</w:t></w:r></w:p><w:p><w:fldSimple w:instr=" STYLEREF "heading 1" "><w:r><w:t>stale nested style source</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" STYLEREF "heading 1" \* Upper "><w:r><w:t>stale upper nested style source</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn style_ref_stale_sequence_field_source_text_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/styles.xml",
r#"<w:styles xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:style w:type="paragraph" w:styleId="Heading1"><w:name w:val="heading 1"/></w:style></w:styles>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:pPr><w:pStyle w:val="Heading1"/></w:pPr><w:r><w:t>Simple </w:t></w:r><w:fldSimple w:instr=" SEQ Chapter "><w:r><w:t>99</w:t></w:r></w:fldSimple><w:r><w:t> Source</w:t></w:r></w:p><w:p><w:fldSimple w:instr=" STYLEREF "heading 1" "><w:r><w:t>stale simple sequence style source</w:t></w:r></w:fldSimple></w:p><w:p><w:pPr><w:pStyle w:val="Heading1"/></w:pPr><w:r><w:t>Complex </w:t></w:r><w:r><w:fldChar w:fldCharType="begin"/></w:r><w:r><w:instrText> SEQ Chapter </w:instrText></w:r><w:r><w:fldChar w:fldCharType="separate"/></w:r><w:r><w:t>98</w:t></w:r><w:r><w:fldChar w:fldCharType="end"/></w:r><w:r><w:t> Source</w:t></w:r></w:p><w:p><w:fldSimple w:instr=" STYLEREF "heading 1" "><w:r><w:t>stale complex sequence style source</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn style_ref_stale_numbering_field_source_text_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/styles.xml",
r#"<w:styles xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:style w:type="paragraph" w:styleId="Heading1"><w:name w:val="heading 1"/></w:style></w:styles>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:pPr><w:pStyle w:val="Heading1"/></w:pPr><w:r><w:t>Simple </w:t></w:r><w:fldSimple w:instr=" AUTONUM "><w:r><w:t>99</w:t></w:r></w:fldSimple><w:r><w:t> Source</w:t></w:r></w:p><w:p><w:fldSimple w:instr=" STYLEREF "heading 1" "><w:r><w:t>stale simple autonum style source</w:t></w:r></w:fldSimple></w:p><w:p><w:pPr><w:pStyle w:val="Heading1"/></w:pPr><w:r><w:t>Complex </w:t></w:r><w:r><w:fldChar w:fldCharType="begin"/></w:r><w:r><w:instrText> AUTONUM </w:instrText></w:r><w:r><w:fldChar w:fldCharType="separate"/></w:r><w:r><w:t>98</w:t></w:r><w:r><w:fldChar w:fldCharType="end"/></w:r><w:r><w:t> Source</w:t></w:r></w:p><w:p><w:fldSimple w:instr=" STYLEREF "heading 1" "><w:r><w:t>stale complex autonum style source</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn style_ref_stale_listnum_field_source_text_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/styles.xml",
r#"<w:styles xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:style w:type="paragraph" w:styleId="Heading1"><w:name w:val="heading 1"/></w:style></w:styles>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:pPr><w:pStyle w:val="Heading1"/></w:pPr><w:r><w:t>Simple </w:t></w:r><w:fldSimple w:instr=" LISTNUM NumberDefault "><w:r><w:t>99</w:t></w:r></w:fldSimple><w:r><w:t> Source</w:t></w:r></w:p><w:p><w:fldSimple w:instr=" STYLEREF "heading 1" "><w:r><w:t>stale simple listnum style source</w:t></w:r></w:fldSimple></w:p><w:p><w:pPr><w:pStyle w:val="Heading1"/></w:pPr><w:r><w:t>Complex </w:t></w:r><w:r><w:fldChar w:fldCharType="begin"/></w:r><w:r><w:instrText> LISTNUM NumberDefault </w:instrText></w:r><w:r><w:fldChar w:fldCharType="separate"/></w:r><w:r><w:t>98</w:t></w:r><w:r><w:fldChar w:fldCharType="end"/></w:r><w:r><w:t> Source</w:t></w:r></w:p><w:p><w:fldSimple w:instr=" STYLEREF "heading 1" "><w:r><w:t>stale complex listnum style source</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn style_ref_source_prior_set_operand_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/styles.xml",
r#"<w:styles xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:style w:type="paragraph" w:styleId="Heading1"><w:name w:val="heading 1"/></w:style></w:styles>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:fldSimple w:instr=" SET ClientTotal 40 "><w:r><w:t>cached style set</w:t></w:r></w:fldSimple></w:p><w:p><w:pPr><w:pStyle w:val="Heading1"/></w:pPr><w:r><w:t>Total </w:t></w:r><w:fldSimple w:instr=" = ClientTotal + 8 "><w:r><w:t>stale style formula</w:t></w:r></w:fldSimple><w:r><w:t> due</w:t></w:r></w:p><w:p><w:fldSimple w:instr=" STYLEREF "heading 1" "><w:r><w:t>stale set style source</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" STYLEREF "heading 1" \* Upper "><w:r><w:t>stale upper set style source</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn style_ref_source_document_bookmark_operand_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/styles.xml",
r#"<w:styles xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:style w:type="paragraph" w:styleId="Heading1"><w:name w:val="heading 1"/></w:style></w:styles>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:bookmarkStart w:id="7" w:name="InvoiceSubtotal"/><w:r><w:t>40</w:t></w:r><w:bookmarkEnd w:id="7"/></w:p><w:p><w:pPr><w:pStyle w:val="Heading1"/></w:pPr><w:r><w:t>Total </w:t></w:r><w:fldSimple w:instr=" = InvoiceSubtotal + 8 "><w:r><w:t>stale bookmark style formula</w:t></w:r></w:fldSimple><w:r><w:t> due</w:t></w:r></w:p><w:p><w:fldSimple w:instr=" STYLEREF "heading 1" "><w:r><w:t>stale bookmark style source</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" STYLEREF "heading 1" \* Upper "><w:r><w:t>stale upper bookmark style source</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn style_ref_source_document_info_field_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/><Override PartName="/docProps/core.xml" ContentType="application/vnd.openxmlformats-package.core-properties+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/><Relationship Id="rIdCore" Type="http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties" Target="docProps/core.xml"/></Relationships>"#,
),
(
"docProps/core.xml",
r#"<cp:coreProperties xmlns:cp="http://schemas.openxmlformats.org/package/2006/metadata/core-properties" xmlns:dc="http://purl.org/dc/elements/1.1/"><dc:title>Quarter Plan</dc:title></cp:coreProperties>"#,
),
(
"word/styles.xml",
r#"<w:styles xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:style w:type="paragraph" w:styleId="Heading1"><w:name w:val="heading 1"/></w:style></w:styles>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:pPr><w:pStyle w:val="Heading1"/></w:pPr><w:r><w:t>Topic </w:t></w:r><w:fldSimple w:instr=" TITLE "><w:r><w:t>stale style title</w:t></w:r></w:fldSimple><w:r><w:t> Scope</w:t></w:r></w:p><w:p><w:fldSimple w:instr=" STYLEREF "heading 1" "><w:r><w:t>stale document-info style source</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" STYLEREF "heading 1" \* Upper "><w:r><w:t>stale upper document-info style source</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn style_ref_source_section_field_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/styles.xml",
r#"<w:styles xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:style w:type="paragraph" w:styleId="Heading1"><w:name w:val="heading 1"/></w:style></w:styles>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:pPr><w:pStyle w:val="Heading1"/></w:pPr><w:r><w:t>Topic </w:t></w:r><w:fldSimple w:instr=" SECTION "><w:r><w:t>99</w:t></w:r></w:fldSimple><w:r><w:t> Review</w:t></w:r></w:p><w:p><w:fldSimple w:instr=" STYLEREF "heading 1" "><w:r><w:t>stale section style source</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn style_ref_source_ref_bookmark_field_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/styles.xml",
r#"<w:styles xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:style w:type="paragraph" w:styleId="Heading1"><w:name w:val="heading 1"/></w:style></w:styles>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:bookmarkStart w:id="7" w:name="BaseText"/><w:r><w:t>current base</w:t></w:r><w:bookmarkEnd w:id="7"/></w:p><w:p><w:pPr><w:pStyle w:val="Heading1"/></w:pPr><w:r><w:t>Source </w:t></w:r><w:fldSimple w:instr=" REF BaseText \* Upper "><w:r><w:t>stale explicit source ref</w:t></w:r></w:fldSimple><w:r><w:t> and </w:t></w:r><w:fldSimple w:instr=" BaseText \* FirstCap "><w:r><w:t>stale direct source ref</w:t></w:r></w:fldSimple><w:r><w:t> ready</w:t></w:r></w:p><w:p><w:fldSimple w:instr=" STYLEREF "heading 1" "><w:r><w:t>stale ref style source</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" STYLEREF "heading 1" \* Upper "><w:r><w:t>stale upper ref style source</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn style_ref_source_note_ref_field_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/><Override PartName="/word/styles.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml"/><Override PartName="/word/footnotes.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.footnotes+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/_rels/document.xml.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rIdFoot" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/footnotes" Target="footnotes.xml"/></Relationships>"#,
),
(
"word/styles.xml",
r#"<w:styles xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:style w:type="paragraph" w:styleId="Heading1"><w:name w:val="heading 1"/></w:style></w:styles>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:bookmarkStart w:id="1" w:name="FootOne"/><w:r><w:footnoteReference w:id="1"/></w:r><w:bookmarkEnd w:id="1"/></w:p><w:p><w:pPr><w:pStyle w:val="Heading1"/></w:pPr><w:r><w:t>Topic </w:t></w:r><w:fldSimple w:instr=" NOTEREF FootOne "><w:r><w:t>stale style note</w:t></w:r></w:fldSimple><w:r><w:t> / </w:t></w:r><w:fldSimple w:instr=" NOTEREF FootOne \p "><w:r><w:t>stale style relative note</w:t></w:r></w:fldSimple><w:r><w:t> / </w:t></w:r><w:fldSimple w:instr=" FTNREF FootOne \p "><w:r><w:t>stale style relative ftnref</w:t></w:r></w:fldSimple><w:r><w:t> Scope</w:t></w:r></w:p><w:p><w:fldSimple w:instr=" STYLEREF "heading 1" "><w:r><w:t>stale note-ref style source</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" STYLEREF "heading 1" \* Upper "><w:r><w:t>stale upper note-ref style source</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
(
"word/footnotes.xml",
r#"<w:footnotes xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:footnote w:type="separator" w:id="-1"><w:p><w:r><w:separator/></w:r></w:p></w:footnote><w:footnote w:id="1"><w:p><w:r><w:t>First footnote.</w:t></w:r></w:p></w:footnote></w:footnotes>"#,
),
])
}
fn style_ref_source_ref_note_mark_field_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/><Override PartName="/word/styles.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml"/><Override PartName="/word/footnotes.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.footnotes+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/_rels/document.xml.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rIdFoot" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/footnotes" Target="footnotes.xml"/></Relationships>"#,
),
(
"word/styles.xml",
r#"<w:styles xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:style w:type="paragraph" w:styleId="Heading1"><w:name w:val="heading 1"/></w:style></w:styles>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:bookmarkStart w:id="1" w:name="FootOne"/><w:r><w:footnoteReference w:id="1"/></w:r><w:bookmarkEnd w:id="1"/></w:p><w:p><w:pPr><w:pStyle w:val="Heading1"/></w:pPr><w:r><w:t>Topic </w:t></w:r><w:fldSimple w:instr=" REF FootOne \f "><w:r><w:t>stale style ref note</w:t></w:r></w:fldSimple><w:r><w:t> Scope</w:t></w:r></w:p><w:p><w:fldSimple w:instr=" STYLEREF "heading 1" "><w:r><w:t>stale ref-note style source</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" STYLEREF "heading 1" \* Upper "><w:r><w:t>stale upper ref-note style source</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
(
"word/footnotes.xml",
r#"<w:footnotes xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:footnote w:type="separator" w:id="-1"><w:p><w:r><w:separator/></w:r></w:p></w:footnote><w:footnote w:id="1"><w:p><w:r><w:t>First footnote.</w:t></w:r></w:p></w:footnote></w:footnotes>"#,
),
])
}
fn style_ref_source_known_field_name_bookmark_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/styles.xml",
r#"<w:styles xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:style w:type="paragraph" w:styleId="Heading1"><w:name w:val="heading 1"/></w:style></w:styles>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:bookmarkStart w:id="7" w:name="PAGEREF"/><w:r><w:t>bookmark target</w:t></w:r><w:bookmarkEnd w:id="7"/></w:p><w:p><w:pPr><w:pStyle w:val="Heading1"/></w:pPr><w:r><w:t>Heading </w:t></w:r><w:fldSimple w:instr=" PAGEREF "><w:r><w:t>known field source</w:t></w:r></w:fldSimple><w:r><w:t> ready</w:t></w:r></w:p><w:p><w:fldSimple w:instr=" STYLEREF "heading 1" "><w:r><w:t>stale known field style source</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn style_ref_source_toc_entry_marker_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/styles.xml",
r#"<w:styles xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:style w:type="paragraph" w:styleId="Heading1"><w:name w:val="heading 1"/></w:style></w:styles>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:pPr><w:pStyle w:val="Heading1"/></w:pPr><w:r><w:t>Chapter</w:t></w:r><w:fldSimple w:instr=" TC "Hidden" \f m \l 1 "><w:r><w:t>stale tc marker</w:t></w:r></w:fldSimple><w:r><w:t> Scope</w:t></w:r></w:p><w:p><w:fldSimple w:instr=" STYLEREF "heading 1" "><w:r><w:t>stale tc style source</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn style_ref_complex_field_source_text_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/styles.xml",
r#"<w:styles xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:style w:type="paragraph" w:styleId="Heading1"><w:name w:val="heading 1"/></w:style></w:styles>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:pPr><w:pStyle w:val="Heading1"/></w:pPr><w:r><w:t>Chapter </w:t></w:r><w:r><w:fldChar w:fldCharType="begin"/></w:r><w:r><w:instrText> SEQ Chapter </w:instrText></w:r><w:r><w:fldChar w:fldCharType="separate"/></w:r><w:r><w:t>1</w:t></w:r><w:r><w:fldChar w:fldCharType="end"/></w:r><w:r><w:t>: Depth</w:t></w:r></w:p><w:p><w:fldSimple w:instr=" STYLEREF "heading 1" "><w:r><w:t>stale complex-field source</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" STYLEREF "heading 1" \* Caps "><w:r><w:t>stale caps complex-field source</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn style_ref_stale_complex_field_source_text_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/styles.xml",
r#"<w:styles xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:style w:type="paragraph" w:styleId="Heading1"><w:name w:val="heading 1"/></w:style></w:styles>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:pPr><w:pStyle w:val="Heading1"/></w:pPr><w:r><w:t>Chapter </w:t></w:r><w:r><w:fldChar w:fldCharType="begin"/></w:r><w:r><w:instrText> QUOTE "Computed" </w:instrText></w:r><w:r><w:fldChar w:fldCharType="separate"/></w:r><w:r><w:t>stale complex source</w:t></w:r><w:r><w:fldChar w:fldCharType="end"/></w:r><w:r><w:t> Scope</w:t></w:r></w:p><w:p><w:fldSimple w:instr=" STYLEREF "heading 1" "><w:r><w:t>stale style source</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" STYLEREF "heading 1" \* Upper "><w:r><w:t>stale upper style source</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn numbered_style_ref_switch_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/><Override PartName="/word/numbering.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.numbering+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/styles.xml",
r#"<w:styles xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:style w:type="paragraph" w:styleId="NumberedTarget"><w:name w:val="Numbered Target"/></w:style></w:styles>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:pPr><w:numPr><w:ilvl w:val="0"/><w:numId w:val="91"/></w:numPr></w:pPr><w:r><w:t>Top 4</w:t></w:r></w:p><w:p><w:pPr><w:numPr><w:ilvl w:val="1"/><w:numId w:val="91"/></w:numPr></w:pPr><w:r><w:t>Child 4.3</w:t></w:r></w:p><w:p><w:pPr><w:numPr><w:ilvl w:val="2"/><w:numId w:val="91"/></w:numPr></w:pPr><w:fldSimple w:instr=" STYLEREF NumberedTarget \r "><w:r><w:t>stale relative style number</w:t></w:r></w:fldSimple><w:r><w:t> </w:t></w:r><w:fldSimple w:instr=" STYLEREF NumberedTarget \r \t "><w:r><w:t>stale relative numeric style number</w:t></w:r></w:fldSimple></w:p><w:p><w:pPr><w:numPr><w:ilvl w:val="1"/><w:numId w:val="91"/></w:numPr></w:pPr><w:r><w:t>Child 4.4</w:t></w:r></w:p><w:p><w:pPr><w:numPr><w:ilvl w:val="1"/><w:numId w:val="91"/></w:numPr></w:pPr><w:r><w:t>Child 4.5</w:t></w:r></w:p><w:p><w:pPr><w:pStyle w:val="NumberedTarget"/><w:numPr><w:ilvl w:val="2"/><w:numId w:val="91"/></w:numPr></w:pPr><w:r><w:t>Target number</w:t></w:r></w:p><w:p><w:fldSimple w:instr=" STYLEREF NumberedTarget \n "><w:r><w:t>stale style number</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" STYLEREF NumberedTarget \n\t "><w:r><w:t>stale numeric style number</w:t></w:r></w:fldSimple></w:p><w:p><w:r><w:fldChar w:fldCharType="begin"/></w:r><w:r><w:instrText> STYLEREF "Numbered Target" \w \* MERGEFORMAT </w:instrText></w:r><w:r><w:fldChar w:fldCharType="separate"/></w:r><w:r><w:t>stale full style number</w:t></w:r><w:r><w:fldChar w:fldCharType="end"/></w:r></w:p></w:body></w:document>"#,
),
(
"word/numbering.xml",
r#"<w:numbering xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:abstractNum w:abstractNumId="15"><w:lvl w:ilvl="0"><w:start w:val="4"/><w:numFmt w:val="decimal"/><w:lvlText w:val="%1."/></w:lvl><w:lvl w:ilvl="1"><w:start w:val="3"/><w:numFmt w:val="decimal"/><w:lvlText w:val="%2."/></w:lvl><w:lvl w:ilvl="2"><w:start w:val="1"/><w:numFmt w:val="decimal"/><w:lvlText w:val="Part %3."/></w:lvl></w:abstractNum><w:num w:numId="91"><w:abstractNumId w:val="15"/></w:num></w:numbering>"#,
),
])
}
fn style_ref_nested_complex_field_source_text_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/styles.xml",
r#"<w:styles xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:style w:type="paragraph" w:styleId="Heading1"><w:name w:val="heading 1"/></w:style></w:styles>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:pPr><w:pStyle w:val="Heading1"/></w:pPr><w:r><w:t>Lead </w:t></w:r><w:r><w:fldChar w:fldCharType="begin"/></w:r><w:r><w:instrText> QUOTE "Outer" </w:instrText></w:r><w:r><w:fldChar w:fldCharType="separate"/></w:r><w:r><w:t>cached before </w:t></w:r><w:r><w:fldChar w:fldCharType="begin"/></w:r><w:r><w:instrText> QUOTE "Inner" </w:instrText></w:r><w:r><w:fldChar w:fldCharType="separate"/></w:r><w:r><w:t>stale inner</w:t></w:r><w:r><w:fldChar w:fldCharType="end"/></w:r><w:r><w:t> cached after</w:t></w:r><w:r><w:fldChar w:fldCharType="end"/></w:r><w:r><w:t> Tail</w:t></w:r></w:p><w:p><w:fldSimple w:instr=" STYLEREF "heading 1" "><w:r><w:t>stale nested complex source</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" STYLEREF "heading 1" \* Upper "><w:r><w:t>stale upper nested complex source</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn character_style_ref_field_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/styles.xml",
r#"<w:styles xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:style w:type="character" w:styleId="LastName"><w:name w:val="Last Name"/></w:style></w:styles>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:fldSimple w:instr=" STYLEREF "Last Name" "><w:r><w:t>stale forward last</w:t></w:r></w:fldSimple></w:p><w:p><w:r><w:rPr><w:rStyle w:val="LastName"/></w:rPr><w:t>Ackerman</w:t></w:r><w:r><w:t> / </w:t></w:r><w:fldSimple w:instr=" STYLEREF LastName "><w:r><w:t>stale same paragraph first</w:t></w:r></w:fldSimple><w:r><w:t> / </w:t></w:r><w:r><w:rPr><w:rStyle w:val="LastName"/></w:rPr><w:t>Berg</w:t></w:r><w:r><w:t> / </w:t></w:r><w:r><w:fldChar w:fldCharType="begin"/></w:r><w:r><w:instrText> STYLEREF "Last Name" \* Upper </w:instrText></w:r><w:r><w:fldChar w:fldCharType="separate"/></w:r><w:r><w:t>stale same paragraph second</w:t></w:r><w:r><w:fldChar w:fldCharType="end"/></w:r></w:p></w:body></w:document>"#,
),
])
}
fn character_style_ref_simple_field_source_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/styles.xml",
r#"<w:styles xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:style w:type="character" w:styleId="LastName"><w:name w:val="Last Name"/></w:style></w:styles>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:fldSimple w:instr=" QUOTE "Curie" "><w:r><w:rPr><w:rStyle w:val="LastName"/></w:rPr><w:t>Curie</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" STYLEREF "Last Name" "><w:r><w:t>stale simple field character source</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" STYLEREF LastName \* Upper "><w:r><w:t>stale upper simple field character source</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn character_style_ref_stale_simple_field_source_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/styles.xml",
r#"<w:styles xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:style w:type="character" w:styleId="LastName"><w:name w:val="Last Name"/></w:style></w:styles>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:fldSimple w:instr=" QUOTE "Curie" "><w:r><w:rPr><w:rStyle w:val="LastName"/></w:rPr><w:t>stale character source</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" STYLEREF "Last Name" "><w:r><w:t>stale simple field character source</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" STYLEREF LastName \* Upper "><w:r><w:t>stale upper simple field character source</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn character_style_ref_split_simple_field_source_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/styles.xml",
r#"<w:styles xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:style w:type="character" w:styleId="LastName"><w:name w:val="Last Name"/></w:style></w:styles>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:fldSimple w:instr=" QUOTE "Curie" "><w:r><w:rPr><w:rStyle w:val="LastName"/></w:rPr><w:t>stale </w:t></w:r><w:r><w:rPr><w:rStyle w:val="LastName"/></w:rPr><w:t>character source</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" STYLEREF "Last Name" "><w:r><w:t>stale split simple field character source</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" STYLEREF LastName \* Upper "><w:r><w:t>stale upper split simple field character source</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn character_style_ref_nested_simple_field_source_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/styles.xml",
r#"<w:styles xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:style w:type="character" w:styleId="LastName"><w:name w:val="Last Name"/></w:style></w:styles>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:fldSimple w:instr=" CUSTOM outer "><w:r><w:rPr><w:rStyle w:val="LastName"/></w:rPr><w:t>Cu</w:t></w:r><w:fldSimple w:instr=" QUOTE "rie" "><w:r><w:rPr><w:rStyle w:val="LastName"/></w:rPr><w:t>stale nested character source</w:t></w:r></w:fldSimple></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" STYLEREF "Last Name" "><w:r><w:t>stale nested simple character source</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" STYLEREF LastName \* Upper "><w:r><w:t>stale upper nested simple character source</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn character_style_ref_stale_complex_field_source_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/styles.xml",
r#"<w:styles xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:style w:type="character" w:styleId="LastName"><w:name w:val="Last Name"/></w:style></w:styles>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:r><w:fldChar w:fldCharType="begin"/></w:r><w:r><w:instrText> QUOTE "Curie" </w:instrText></w:r><w:r><w:fldChar w:fldCharType="separate"/></w:r><w:r><w:rPr><w:rStyle w:val="LastName"/></w:rPr><w:t>stale character complex source</w:t></w:r><w:r><w:fldChar w:fldCharType="end"/></w:r></w:p><w:p><w:fldSimple w:instr=" STYLEREF "Last Name" "><w:r><w:t>stale complex field character source</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" STYLEREF LastName \* Upper "><w:r><w:t>stale upper complex field character source</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn style_ref_symbol_source_text_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/styles.xml",
r#"<w:styles xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:style w:type="paragraph" w:styleId="Heading1"><w:name w:val="heading 1"/></w:style><w:style w:type="character" w:styleId="SymbolTarget"><w:name w:val="Symbol Target"/></w:style></w:styles>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:pPr><w:pStyle w:val="Heading1"/></w:pPr><w:r><w:t>Risk </w:t><w:sym w:font="Symbol" w:char="F0B7"/><w:t> Control</w:t></w:r></w:p><w:p><w:r><w:rPr><w:rStyle w:val="SymbolTarget"/></w:rPr><w:t>Marked </w:t><w:sym w:font="Symbol" w:char="F0B7"/><w:t> Run</w:t></w:r></w:p><w:p><w:fldSimple w:instr=" STYLEREF "heading 1" "><w:r><w:t>stale symbol heading</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" STYLEREF "Symbol Target" "><w:r><w:t>stale symbol character</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn character_style_ref_property_revision_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/styles.xml",
r#"<w:styles xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:style w:type="character" w:styleId="LastName"><w:name w:val="Last Name"/></w:style></w:styles>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:fldSimple w:instr=" STYLEREF "Last Name" "><w:r><w:t>stale before old run</w:t></w:r></w:fldSimple></w:p><w:p><w:r><w:rPr><w:rPrChange w:id="9" w:author="Reviewer"><w:rPr><w:rStyle w:val="LastName"/></w:rPr></w:rPrChange></w:rPr><w:t>Former Styled</w:t></w:r></w:p><w:p><w:fldSimple w:instr=" STYLEREF "Last Name" "><w:r><w:t>stale after old run</w:t></w:r></w:fldSimple></w:p><w:p><w:r><w:rPr><w:rStyle w:val="LastName"/></w:rPr><w:t>Current Last</w:t></w:r></w:p><w:p><w:fldSimple w:instr=" STYLEREF "Last Name" \* Upper "><w:r><w:t>stale after current run</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn display_field_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:fldSimple w:instr=" ADVANCE \r 2 \d4 \* MERGEFORMAT "><w:r><w:t>offset text</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" ADVANCE \z 2 "><w:r><w:t>cached unsupported advance</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" EQ \f(1,2) "><w:r><w:t>stale equation</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" EQ \f( "Alpha, One" , "Beta Two" ) \* Upper "><w:r><w:t>stale quoted equation</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" EQ \f(3;4) "><w:r><w:t>stale semicolon equation</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" EQ \f(A\,B,C\\D) "><w:r><w:t>stale escaped equation</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" EQ \r(9) "><w:r><w:t>stale square root</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" EQ \r(3,27) "><w:r><w:t>stale cube root</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" EQ \f(1,\f(2,3)) "><w:r><w:t>stale nested equation</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" EQ \r(\f(1,4)) "><w:r><w:t>stale nested radical</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" EQ \b("Chapter One") "><w:r><w:t>stale bracket equation</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" EQ \x \to \bo(\f(5,8)) \* Upper "><w:r><w:t>stale boxed equation</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" EQ \b \bc\{ (\r(3,x)) "><w:r><w:t>stale brace bracket equation</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" EQ \b \lc\[ \rc\] ("Range") "><w:r><w:t>stale explicit bracket equation</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" EQ \l(A,"B, C",\r(4,16)) "><w:r><w:t>stale list equation</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" EQ \a \al \co2 \vs3 \hs3(Axy,Bxy,A,B) "><w:r><w:t>stale array equation</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" EQ \d \fo10 \li() "><w:r><w:t>stale displace equation</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" EQ \s\up8(UB)\s\do8(2) "><w:r><w:t>stale script equation</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" EQ \i(0,1,x) "><w:r><w:t>stale integral equation</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" EQ \i \su(1,5,\f(3,4)) "><w:r><w:t>stale summation equation</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" EQ \i \pr(1,3,y) "><w:r><w:t>stale product equation</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" EQ \i \in(a,b,\r(9)) "><w:r><w:t>stale integral option equation</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" EQ \i \fc\∮(C,D,z) "><w:r><w:t>stale custom integral equation</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" EQ \i \vc\∯(S,T,w) "><w:r><w:t>stale vertical custom integral equation</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" EQ \o \ac("A",/) "><w:r><w:t>stale overstrike equation</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" SYMBOL 183 \f Symbol "><w:r><w:t>symbol</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" EQ \s\ai4()\di3() "><w:r><w:t>stale empty script equation</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" EQ \s\ai4()\up8(UB)\s\di3()\do8(2) "><w:r><w:t>stale layout script equation</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn advance_compact_quoted_display_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:fldSimple w:instr=" ADVANCE \r"2" "><w:r><w:t>stale compact right</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" ADVANCE \u "3" \d4 "><w:r><w:t>stale quoted up down</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" ADVANCE \l2 \y "5" \* Upper "><w:r><w:t>stale compact left vertical</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn symbol_field_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:fldSimple w:instr=" SYMBOL 163 "><w:r><w:t>stale pound</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" SYMBOL 0x03BB \u \h "><w:r><w:t>stale lambda</w:t></w:r></w:fldSimple></w:p><w:p><w:r><w:fldChar w:fldCharType="begin"/></w:r><w:r><w:instrText> SYMBOL 211 \f "Symbol" \s 12 </w:instrText></w:r><w:r><w:fldChar w:fldCharType="separate"/></w:r><w:r><w:t>stale copyright</w:t></w:r><w:r><w:fldChar w:fldCharType="end"/></w:r></w:p><w:p><w:fldSimple w:instr=" SYMBOL 183 \fSymbol \s12 "><w:r><w:t>stale compact symbol</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" SYMBOL 0x03BB \u \f Symbol "><w:r><w:t>stale unicode font</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" SYMBOL 0x0041 \u \s "10" "><w:r><w:t>stale quoted size</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" SYMBOL 0x0042 \u \s"11" "><w:r><w:t>stale compact quoted size</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn symbol_multi_token_font_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:fldSimple w:instr=" SYMBOL 0x03BB \u \f Times New Roman \* Upper "><w:r><w:t>stale multi-token font</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn action_field_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:fldSimple w:instr=" GOTOBUTTON TargetBookmark "Jump" "><w:r><w:t>stale jump</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" GOTOBUTTON TargetBookmark Jump Now \* Upper "><w:r><w:t>stale jump upper</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" MACROBUTTON RunReport "Run report" "><w:r><w:t>stale run</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" MACROBUTTON RunReport Run \* Upper Again "><w:r><w:t>cached malformed action</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" MACROBUTTON RunReport \* MERGEFORMAT "><w:r><w:t>cached target-only action</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" PRINT "page \p" "><w:r><w:t>Print instruction</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" PRINT status "><w:r><w:t>Unquoted print instruction</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" PRINT status ready \* MERGEFORMAT "><w:r><w:t>Multi-token print instruction</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" PRINT \p ReportBox "0 0 moveto" \* MERGEFORMAT "><w:r><w:t>PostScript instruction</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" PRINT \pReportBox "compact moveto" "><w:r><w:t>Compact PostScript instruction</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" PRINT \z "bad" "><w:r><w:t>cached unsupported print</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn action_compact_format_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:fldSimple w:instr=" PRINT status ready \*MERGEFORMAT "><w:r><w:t>cached compact print</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn action_button_compact_format_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:fldSimple w:instr=" GOTOBUTTON TargetBookmark Jump Now \*Upper "><w:r><w:t>stale compact jump</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" MACROBUTTON RunReport \*MERGEFORMAT "><w:r><w:t>cached compact target-only action</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn action_print_group_unquoted_code_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:fldSimple w:instr=" PRINT \p ReportBox 0 0 moveto \* MERGEFORMAT "><w:r><w:t>cached unquoted print group</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" PRINT \pReportBox compact moveto "><w:r><w:t>cached compact unquoted print group</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn action_accepted_current_field_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="wps"><w:body><w:del><w:p><w:fldSimple w:instr=" GOTOBUTTON HiddenTarget "Deleted Jump" "><w:r><w:t>deleted cached jump</w:t></w:r></w:fldSimple></w:p></w:del><mc:AlternateContent><mc:Choice Requires="wps"><w:p><w:fldSimple w:instr=" GOTOBUTTON TargetBookmark "Choice Jump" "><w:r><w:t>stale choice jump</w:t></w:r></w:fldSimple></w:p></mc:Choice><mc:Fallback><w:p><w:fldSimple w:instr=" GOTOBUTTON FallbackTarget "Fallback Jump" "><w:r><w:t>fallback cached jump</w:t></w:r></w:fldSimple></w:p></mc:Fallback></mc:AlternateContent><w:moveFrom><w:p><w:fldSimple w:instr=" PRINT moved status "><w:r><w:t>moved print cache</w:t></w:r></w:fldSimple></w:p></w:moveFrom><w:p><w:fldSimple w:instr=" PRINT status ready "><w:r><w:t>visible print cache</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn compatibility_field_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:fldSimple w:instr=" PRIVATE "><w:r><w:rPr><w:vanish/></w:rPr><w:t>converted payload</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" ADDIN hidden-data "><w:r><w:rPr><w:vanish/></w:rPr><w:t>addin payload</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" DATA legacy-data "><w:r><w:rPr><w:vanish/></w:rPr><w:t>data payload</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" GLOSSARY AutoTextName "><w:r><w:t>glossary payload</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" HTMLACTIVEX LegacyControl "><w:r><w:t>activex payload</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn barcode_field_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:fldSimple w:instr=" DISPLAYBARCODE "https://example.com" QR \q H "><w:r><w:t>QR preview</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" MERGEBARCODE CustomerId CODE128 \t "><w:r><w:t>Merge barcode preview</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" BARCODE "9781234567890" "><w:r><w:t>Legacy barcode preview</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn legacy_form_field_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:fldSimple w:instr=" FORMTEXT "><w:r><w:t>Alice</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" FORMTEXT "><w:ffData><w:textInput><w:default w:val="No content."/></w:textInput></w:ffData><w:r><w:t></w:t></w:r></w:fldSimple></w:p><w:p><w:r><w:fldChar w:fldCharType="begin"><w:ffData><w:checkBox><w:checked w:val="true"/></w:checkBox></w:ffData></w:fldChar></w:r><w:r><w:instrText> FORMCHECKBOX </w:instrText></w:r><w:r><w:fldChar w:fldCharType="separate"/></w:r><w:r><w:t>stale checked</w:t></w:r><w:r><w:fldChar w:fldCharType="end"/></w:r></w:p><w:p><w:r><w:fldChar w:fldCharType="begin"><w:ffData><w:checkBox><w:checked w:val="false"/></w:checkBox></w:ffData></w:fldChar></w:r><w:r><w:instrText> FORMCHECKBOX </w:instrText></w:r><w:r><w:fldChar w:fldCharType="separate"/></w:r><w:r><w:t>stale unchecked</w:t></w:r><w:r><w:fldChar w:fldCharType="end"/></w:r></w:p><w:p><w:r><w:fldChar w:fldCharType="begin"><w:ffData><w:checkBox><w:default w:val="true"/></w:checkBox></w:ffData></w:fldChar></w:r><w:r><w:instrText> FORMCHECKBOX </w:instrText></w:r><w:r><w:fldChar w:fldCharType="separate"/></w:r><w:r><w:t>stale default checked</w:t></w:r><w:r><w:fldChar w:fldCharType="end"/></w:r></w:p><w:p><w:fldSimple w:instr=" FORMDROPDOWN "><w:ffData><w:ddList><w:default w:val="0"/><w:result w:val="2"/><w:listEntry w:val="Option A"/><w:listEntry w:val="Option B"/><w:listEntry w:val="Option C"/></w:ddList></w:ffData><w:r><w:t>stale option</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" FORMDROPDOWN "><w:ffData><w:ddList><w:default w:val="1"/><w:listEntry w:val="Default A"/><w:listEntry w:val="Default B"/></w:ddList></w:ffData><w:r><w:t>stale default option</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" FORMDROPDOWN "><w:ffData><w:ddList><w:default w:val="1"/><w:result w:val="9"/><w:listEntry w:val="Fallback A"/><w:listEntry w:val="Fallback B"/></w:ddList></w:ffData><w:r><w:t>stale invalid option</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn legacy_form_ref_target_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:fldSimple w:instr=" FORMDROPDOWN "><w:ffData><w:ddList><w:result w:val="1"/><w:listEntry w:val="Prior A"/><w:listEntry w:val="Prior B"/></w:ddList></w:ffData><w:r><w:t>stale prior option</w:t></w:r></w:fldSimple></w:p><w:p><w:bookmarkStart w:id="11" w:name="SelectedOption"/><w:fldSimple w:instr=" FORMDROPDOWN "><w:ffData><w:ddList><w:result w:val="1"/><w:listEntry w:val="Target A"/><w:listEntry w:val="Target B"/></w:ddList></w:ffData><w:r><w:t>stale target option</w:t></w:r></w:fldSimple><w:bookmarkEnd w:id="11"/></w:p><w:p><w:fldSimple w:instr=" REF SelectedOption "><w:r><w:t>cached form ref</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn legacy_form_deleted_field_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:del><w:r><w:fldChar w:fldCharType="begin"><w:ffData><w:checkBox><w:checked w:val="true"/></w:checkBox></w:ffData></w:fldChar></w:r><w:r><w:instrText> FORMCHECKBOX </w:instrText></w:r><w:r><w:fldChar w:fldCharType="separate"/></w:r><w:r><w:t>deleted checked</w:t></w:r><w:r><w:fldChar w:fldCharType="end"/></w:r></w:del><w:p><w:r><w:fldChar w:fldCharType="begin"><w:ffData><w:checkBox><w:checked w:val="false"/></w:checkBox></w:ffData></w:fldChar></w:r><w:r><w:instrText> FORMCHECKBOX </w:instrText></w:r><w:r><w:fldChar w:fldCharType="separate"/></w:r><w:r><w:t>stale visible unchecked</w:t></w:r><w:r><w:fldChar w:fldCharType="end"/></w:r></w:p></w:body></w:document>"#,
),
])
}
fn legacy_form_alternate_content_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"><w:body><mc:AlternateContent><mc:Choice Requires="wps"><w:p/></mc:Choice><mc:Fallback><w:p><w:r><w:fldChar w:fldCharType="begin"><w:ffData><w:checkBox><w:checked w:val="true"/></w:checkBox></w:ffData></w:fldChar></w:r><w:r><w:instrText> FORMCHECKBOX </w:instrText></w:r><w:r><w:fldChar w:fldCharType="separate"/></w:r><w:r><w:t>fallback checked</w:t></w:r><w:r><w:fldChar w:fldCharType="end"/></w:r></w:p></mc:Fallback></mc:AlternateContent><w:p><w:fldSimple w:instr=" FORMDROPDOWN "><w:ffData><mc:AlternateContent><mc:Choice Requires="wps"><w:ddList><w:result w:val="0"/><w:listEntry w:val="Choice option"/></w:ddList></mc:Choice><mc:Fallback><w:ddList><w:result w:val="1"/><w:listEntry w:val="Fallback option"/></w:ddList></mc:Fallback></mc:AlternateContent></w:ffData><w:r><w:t>stale option</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn simple_cached_result_inline_marker_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:fldSimple w:instr=" CUSTOM value "><w:r><w:t>Alpha</w:t><w:tab/><w:t>Beta</w:t><w:br/><w:t>Gamma</w:t><w:noBreakHyphen/><w:t>Hard</w:t><w:softHyphen/><w:t>Soft</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn simple_cached_result_alternate_content_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"><w:body><w:p><w:fldSimple w:instr=" CUSTOM value "><w:r><w:t>Before </w:t></w:r><mc:AlternateContent><mc:Choice Requires="wps"><w:r><w:t>Choice</w:t></w:r></mc:Choice><mc:Fallback><w:r><w:t>Fallback</w:t></w:r></mc:Fallback></mc:AlternateContent><w:r><w:t> After</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn simple_cached_result_nested_simple_field_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:fldSimple w:instr=" CUSTOM outer "><w:r><w:t>Outer </w:t></w:r><w:fldSimple w:instr=" CUSTOM inner "><w:r><w:t>Inner</w:t></w:r></w:fldSimple><w:r><w:t> Tail</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn complex_cached_result_inline_marker_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:r><w:fldChar w:fldCharType="begin"/></w:r><w:r><w:instrText> CUSTOM value </w:instrText></w:r><w:r><w:fldChar w:fldCharType="separate"/></w:r><w:r><w:t>One</w:t><w:tab/><w:t>Two</w:t><w:br/><w:t>Three</w:t><w:noBreakHyphen/><w:t>Hard</w:t><w:softHyphen/><w:t>Soft</w:t></w:r><w:r><w:fldChar w:fldCharType="end"/></w:r></w:p><w:p><w:r><w:fldChar w:fldCharType="begin"/></w:r><w:r><w:instrText> CUSTOM markersOnly </w:instrText></w:r><w:r><w:fldChar w:fldCharType="separate"/></w:r><w:r><w:tab/><w:br/><w:noBreakHyphen/><w:softHyphen/></w:r><w:r><w:fldChar w:fldCharType="end"/></w:r></w:p></w:body></w:document>"#,
),
])
}
fn cached_field_result_symbol_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:fldSimple w:instr=" CUSTOM simple "><w:r><w:t>Simple </w:t><w:sym w:font="Symbol" w:char="F0B7"/><w:t> result</w:t></w:r></w:fldSimple></w:p><w:p><w:r><w:fldChar w:fldCharType="begin"/></w:r><w:r><w:instrText> CUSTOM complex </w:instrText></w:r><w:r><w:fldChar w:fldCharType="separate"/></w:r><w:r><w:t>Complex </w:t><w:sym w:font="Symbol" w:char="F0B7"/><w:t> result</w:t></w:r><w:r><w:fldChar w:fldCharType="end"/></w:r></w:p></w:body></w:document>"#,
),
])
}
fn complex_split_cached_result_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:r><w:fldChar w:fldCharType="begin"/></w:r><w:r><w:instrText> CUSTOM split </w:instrText></w:r><w:r><w:fldChar w:fldCharType="separate"/></w:r><w:r><w:t>Alpha </w:t></w:r><w:r><w:t>Beta</w:t></w:r><w:r><w:fldChar w:fldCharType="end"/></w:r></w:p></w:body></w:document>"#,
),
])
}
fn nested_complex_field_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:r><w:fldChar w:fldCharType="begin"/></w:r><w:r><w:instrText> CUSTOM outer </w:instrText></w:r><w:r><w:fldChar w:fldCharType="separate"/></w:r><w:r><w:t>Before </w:t></w:r><w:r><w:fldChar w:fldCharType="begin"/></w:r><w:r><w:instrText> MERGEFIELD InnerName </w:instrText></w:r><w:r><w:fldChar w:fldCharType="separate"/></w:r><w:r><w:t>Inner Value</w:t></w:r><w:r><w:fldChar w:fldCharType="end"/></w:r><w:r><w:t> After</w:t></w:r><w:r><w:fldChar w:fldCharType="end"/></w:r></w:p></w:body></w:document>"#,
),
])
}
fn nested_complex_with_simple_field_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:r><w:fldChar w:fldCharType="begin"/></w:r><w:r><w:instrText> CUSTOM outer </w:instrText></w:r><w:r><w:fldChar w:fldCharType="separate"/></w:r><w:r><w:t>Before </w:t></w:r><w:fldSimple w:instr=" MERGEFIELD InnerName "><w:r><w:t>Inner Value</w:t></w:r></w:fldSimple><w:r><w:t> After</w:t></w:r><w:r><w:fldChar w:fldCharType="end"/></w:r></w:p></w:body></w:document>"#,
),
])
}
fn ref_bookmark_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:bookmarkStart w:id="7" w:name="Figure1"/><w:r><w:t>Figure 1</w:t></w:r><w:bookmarkEnd w:id="7"/></w:p><w:p><w:fldSimple w:instr=" REF Figure1 "><w:r><w:t>stale cached text</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" REF MissingBookmark "><w:r><w:t>Missing</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn ref_empty_bookmark_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:bookmarkStart w:id="7" w:name="EmptyTarget"/><w:bookmarkEnd w:id="7"/></w:p><w:p><w:fldSimple w:instr=" REF EmptyTarget "><w:r><w:t>stale empty ref</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" REF EmptyTarget \* Upper "><w:r><w:t>stale empty upper ref</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" REF MissingTarget "><w:r><w:t>cached missing ref</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn nested_simple_field_ref_bookmark_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:bookmarkStart w:id="7" w:name="ComputedText"/><w:fldSimple w:instr=" QUOTE "Current target" "><w:r><w:t>stale nested quote</w:t></w:r></w:fldSimple><w:bookmarkEnd w:id="7"/></w:p><w:p><w:fldSimple w:instr=" REF ComputedText "><w:r><w:t>stale outer ref</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn nested_note_ref_field_ref_bookmark_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/><Override PartName="/word/footnotes.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.footnotes+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/_rels/document.xml.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rIdFoot" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/footnotes" Target="footnotes.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:bookmarkStart w:id="7" w:name="FootOne"/><w:r><w:footnoteReference w:id="1"/></w:r><w:bookmarkEnd w:id="7"/></w:p><w:p><w:bookmarkStart w:id="8" w:name="ComputedNoteText"/><w:fldSimple w:instr=" NOTEREF FootOne "><w:r><w:t>stale target note</w:t></w:r></w:fldSimple><w:r><w:t> / </w:t></w:r><w:fldSimple w:instr=" NOTEREF FootOne \p "><w:r><w:t>stale target relative note</w:t></w:r></w:fldSimple><w:bookmarkEnd w:id="8"/></w:p><w:p><w:fldSimple w:instr=" REF ComputedNoteText "><w:r><w:t>stale outer note target ref</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
(
"word/footnotes.xml",
r#"<w:footnotes xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:footnote w:type="separator" w:id="-1"><w:p><w:r><w:separator/></w:r></w:p></w:footnote><w:footnote w:id="1"><w:p><w:r><w:t>First footnote.</w:t></w:r></w:p></w:footnote></w:footnotes>"#,
),
])
}
fn nested_ref_note_mark_field_ref_bookmark_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/><Override PartName="/word/footnotes.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.footnotes+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/_rels/document.xml.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rIdFoot" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/footnotes" Target="footnotes.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:bookmarkStart w:id="7" w:name="FootOne"/><w:r><w:footnoteReference w:id="1"/></w:r><w:bookmarkEnd w:id="7"/></w:p><w:p><w:bookmarkStart w:id="8" w:name="ComputedRefNoteMark"/><w:fldSimple w:instr=" REF FootOne \f "><w:r><w:t>stale target ref note mark</w:t></w:r></w:fldSimple><w:bookmarkEnd w:id="8"/></w:p><w:p><w:fldSimple w:instr=" REF ComputedRefNoteMark "><w:r><w:t>stale outer ref note target</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
(
"word/footnotes.xml",
r#"<w:footnotes xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:footnote w:type="separator" w:id="-1"><w:p><w:r><w:separator/></w:r></w:p></w:footnote><w:footnote w:id="1"><w:p><w:r><w:t>First footnote.</w:t></w:r></w:p></w:footnote></w:footnotes>"#,
),
])
}
fn nested_empty_simple_field_ref_bookmark_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:bookmarkStart w:id="7" w:name="ComputedText"/><w:fldSimple w:instr=" QUOTE "Current target" "/><w:bookmarkEnd w:id="7"/></w:p><w:p><w:fldSimple w:instr=" REF ComputedText "><w:r><w:t>stale empty outer ref</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn document_info_ref_target_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/><Override PartName="/docProps/core.xml" ContentType="application/vnd.openxmlformats-package.core-properties+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/><Relationship Id="rIdCore" Type="http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties" Target="docProps/core.xml"/></Relationships>"#,
),
(
"docProps/core.xml",
r#"<cp:coreProperties xmlns:cp="http://schemas.openxmlformats.org/package/2006/metadata/core-properties" xmlns:dc="http://purl.org/dc/elements/1.1/"><dc:title>Quarter Plan</dc:title></cp:coreProperties>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:bookmarkStart w:id="7" w:name="ComputedTitle"/><w:fldSimple w:instr=" TITLE "><w:r><w:t>stale nested title</w:t></w:r></w:fldSimple><w:bookmarkEnd w:id="7"/></w:p><w:p><w:fldSimple w:instr=" REF ComputedTitle "><w:r><w:t>stale title ref</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn revision_number_source_scanners_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/><Override PartName="/docProps/core.xml" ContentType="application/vnd.openxmlformats-package.core-properties+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/><Relationship Id="rIdCore" Type="http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties" Target="docProps/core.xml"/></Relationships>"#,
),
(
"docProps/core.xml",
r#"<cp:coreProperties xmlns:cp="http://schemas.openxmlformats.org/package/2006/metadata/core-properties"><cp:revision>12</cp:revision></cp:coreProperties>"#,
),
(
"word/styles.xml",
r#"<w:styles xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:style w:type="paragraph" w:styleId="Heading1"><w:name w:val="heading 1"/></w:style></w:styles>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:bookmarkStart w:id="7" w:name="ComputedRevision"/><w:fldSimple w:instr=" REVNUM "><w:r><w:t>stale ref revision</w:t></w:r></w:fldSimple><w:bookmarkEnd w:id="7"/></w:p><w:p><w:fldSimple w:instr=" REF ComputedRevision "><w:r><w:t>stale revision ref</w:t></w:r></w:fldSimple></w:p><w:p><w:pPr><w:pStyle w:val="Heading1"/></w:pPr><w:r><w:t>Release </w:t></w:r><w:fldSimple w:instr=" REVNUM "><w:r><w:t>stale style revision</w:t></w:r></w:fldSimple><w:r><w:t> Notes</w:t></w:r></w:p><w:p><w:fldSimple w:instr=" STYLEREF "heading 1" "><w:r><w:t>stale revision style source</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" TOC \o "1-1" "><w:r><w:t>stale revision toc source</w:t></w:r></w:fldSimple></w:p><w:tbl><w:tr><w:tc><w:p><w:fldSimple w:instr=" REVNUM "><w:r><w:t>99</w:t></w:r></w:fldSimple></w:p></w:tc><w:tc><w:p><w:fldSimple w:instr=" = SUM(LEFT) "><w:r><w:t>stale revision source sum</w:t></w:r></w:fldSimple></w:p></w:tc></w:tr></w:tbl></w:body></w:document>"#,
),
])
}
fn nested_empty_simple_field_inside_ref_target_result_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:bookmarkStart w:id="7" w:name="ComputedText"/><w:fldSimple w:instr=" CUSTOM outer "><w:r><w:t>Prefix </w:t></w:r><w:fldSimple w:instr=" QUOTE "Inner target" "/><w:r><w:t> Suffix</w:t></w:r></w:fldSimple><w:bookmarkEnd w:id="7"/></w:p><w:p><w:fldSimple w:instr=" REF ComputedText "><w:r><w:t>stale nested empty result ref</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn nested_simple_field_inside_ref_target_result_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:bookmarkStart w:id="7" w:name="ComputedText"/><w:fldSimple w:instr=" CUSTOM outer "><w:r><w:t>Prefix </w:t></w:r><w:fldSimple w:instr=" QUOTE "Inner target" "><w:r><w:t>stale inner target</w:t></w:r></w:fldSimple><w:r><w:t> Suffix</w:t></w:r></w:fldSimple><w:bookmarkEnd w:id="7"/></w:p><w:p><w:fldSimple w:instr=" REF ComputedText "><w:r><w:t>stale nested result ref</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn nested_complex_field_inside_ref_target_result_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:bookmarkStart w:id="7" w:name="ComputedText"/><w:fldSimple w:instr=" CUSTOM outer "><w:r><w:t>Prefix </w:t></w:r><w:r><w:fldChar w:fldCharType="begin"/></w:r><w:r><w:instrText> QUOTE "Inner target" </w:instrText></w:r><w:r><w:fldChar w:fldCharType="separate"/></w:r><w:r><w:t>stale inner target</w:t></w:r><w:r><w:fldChar w:fldCharType="end"/></w:r><w:r><w:t> Suffix</w:t></w:r></w:fldSimple><w:bookmarkEnd w:id="7"/></w:p><w:p><w:fldSimple w:instr=" REF ComputedText "><w:r><w:t>stale nested complex result ref</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn nested_complex_field_ref_bookmark_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:bookmarkStart w:id="7" w:name="ComputedText"/><w:r><w:fldChar w:fldCharType="begin"/></w:r><w:r><w:instrText> QUOTE "Complex target" </w:instrText></w:r><w:r><w:fldChar w:fldCharType="separate"/></w:r><w:r><w:t>stale complex quote</w:t></w:r><w:r><w:fldChar w:fldCharType="end"/></w:r><w:bookmarkEnd w:id="7"/></w:p><w:p><w:fldSimple w:instr=" REF ComputedText "><w:r><w:t>stale outer ref</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn nested_sequence_field_ref_bookmark_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:fldSimple w:instr=" SEQ Item "><w:r><w:t>1</w:t></w:r></w:fldSimple></w:p><w:p><w:bookmarkStart w:id="7" w:name="SimpleSeq"/><w:fldSimple w:instr=" SEQ Item "><w:r><w:t>99</w:t></w:r></w:fldSimple><w:bookmarkEnd w:id="7"/></w:p><w:p><w:bookmarkStart w:id="8" w:name="ComplexSeq"/><w:r><w:fldChar w:fldCharType="begin"/></w:r><w:r><w:instrText> SEQ Item </w:instrText></w:r><w:r><w:fldChar w:fldCharType="separate"/></w:r><w:r><w:t>98</w:t></w:r><w:r><w:fldChar w:fldCharType="end"/></w:r><w:bookmarkEnd w:id="8"/></w:p><w:p><w:fldSimple w:instr=" REF SimpleSeq "><w:r><w:t>stale simple sequence ref</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" REF ComplexSeq "><w:r><w:t>stale complex sequence ref</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn nested_numbering_field_ref_bookmark_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:fldSimple w:instr=" AUTONUM "><w:r><w:t>1</w:t></w:r></w:fldSimple></w:p><w:p><w:bookmarkStart w:id="7" w:name="SimpleAuto"/><w:fldSimple w:instr=" AUTONUM "><w:r><w:t>99</w:t></w:r></w:fldSimple><w:bookmarkEnd w:id="7"/></w:p><w:p><w:bookmarkStart w:id="8" w:name="ComplexAuto"/><w:r><w:fldChar w:fldCharType="begin"/></w:r><w:r><w:instrText> AUTONUM </w:instrText></w:r><w:r><w:fldChar w:fldCharType="separate"/></w:r><w:r><w:t>98</w:t></w:r><w:r><w:fldChar w:fldCharType="end"/></w:r><w:bookmarkEnd w:id="8"/></w:p><w:p><w:fldSimple w:instr=" REF SimpleAuto "><w:r><w:t>stale simple autonum ref</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" REF ComplexAuto "><w:r><w:t>stale complex autonum ref</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn nested_listnum_field_ref_bookmark_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:fldSimple w:instr=" LISTNUM NumberDefault "><w:r><w:t>1</w:t></w:r></w:fldSimple></w:p><w:p><w:bookmarkStart w:id="7" w:name="SimpleList"/><w:fldSimple w:instr=" LISTNUM NumberDefault "><w:r><w:t>99</w:t></w:r></w:fldSimple><w:bookmarkEnd w:id="7"/></w:p><w:p><w:bookmarkStart w:id="8" w:name="ComplexList"/><w:r><w:fldChar w:fldCharType="begin"/></w:r><w:r><w:instrText> LISTNUM NumberDefault </w:instrText></w:r><w:r><w:fldChar w:fldCharType="separate"/></w:r><w:r><w:t>98</w:t></w:r><w:r><w:fldChar w:fldCharType="end"/></w:r><w:bookmarkEnd w:id="8"/></w:p><w:p><w:fldSimple w:instr=" REF SimpleList "><w:r><w:t>stale simple listnum ref</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" REF ComplexList "><w:r><w:t>stale complex listnum ref</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn nested_bookmark_operand_field_ref_bookmark_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:bookmarkStart w:id="7" w:name="InvoiceSubtotal"/><w:r><w:t>40</w:t></w:r><w:bookmarkEnd w:id="7"/></w:p><w:p><w:bookmarkStart w:id="8" w:name="ComputedTotal"/><w:fldSimple w:instr=" = InvoiceSubtotal + 8 "><w:r><w:t>stale nested formula</w:t></w:r></w:fldSimple><w:bookmarkEnd w:id="8"/></w:p><w:p><w:fldSimple w:instr=" REF ComputedTotal "><w:r><w:t>stale total ref</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn nested_set_operand_field_ref_bookmark_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:fldSimple w:instr=" SET ClientTotal 40 "><w:r><w:t>cached set total</w:t></w:r></w:fldSimple></w:p><w:p><w:bookmarkStart w:id="8" w:name="ComputedTotal"/><w:fldSimple w:instr=" = ClientTotal + 8 "><w:r><w:t>stale set nested formula</w:t></w:r></w:fldSimple><w:bookmarkEnd w:id="8"/></w:p><w:p><w:fldSimple w:instr=" REF ComputedTotal "><w:r><w:t>stale set total ref</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn nested_complex_set_operand_field_ref_bookmark_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:r><w:fldChar w:fldCharType="begin"/></w:r><w:r><w:instrText> SET ClientTotal 40 </w:instrText></w:r><w:r><w:fldChar w:fldCharType="separate"/></w:r><w:r><w:t>cached complex set total</w:t></w:r><w:r><w:fldChar w:fldCharType="end"/></w:r></w:p><w:p><w:bookmarkStart w:id="8" w:name="ComputedTotal"/><w:fldSimple w:instr=" = ClientTotal + 8 "><w:r><w:t>stale complex set nested formula</w:t></w:r></w:fldSimple><w:bookmarkEnd w:id="8"/></w:p><w:p><w:fldSimple w:instr=" REF ComputedTotal "><w:r><w:t>stale complex set total ref</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn known_field_name_bookmark_ref_target_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:bookmarkStart w:id="7" w:name="PAGEREF"/><w:r><w:t>bookmark target</w:t></w:r><w:bookmarkEnd w:id="7"/></w:p><w:p><w:bookmarkStart w:id="8" w:name="ComputedTarget"/><w:fldSimple w:instr=" PAGEREF "><w:r><w:t>known field target</w:t></w:r></w:fldSimple><w:bookmarkEnd w:id="8"/></w:p><w:p><w:fldSimple w:instr=" REF ComputedTarget "><w:r><w:t>stale known field target ref</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn toc_entry_marker_ref_target_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:bookmarkStart w:id="8" w:name="ComputedTarget"/><w:r><w:t>Alpha </w:t></w:r><w:fldSimple w:instr=" TC "Hidden" \f m \l 1 "><w:r><w:t>stale tc marker</w:t></w:r></w:fldSimple><w:r><w:t>Beta</w:t></w:r><w:bookmarkEnd w:id="8"/></w:p><w:p><w:fldSimple w:instr=" REF ComputedTarget "><w:r><w:t>stale tc target ref</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn nested_ref_field_ref_bookmark_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:bookmarkStart w:id="7" w:name="BaseText"/><w:r><w:t>current base</w:t></w:r><w:bookmarkEnd w:id="7"/></w:p><w:p><w:bookmarkStart w:id="8" w:name="ComputedExplicit"/><w:fldSimple w:instr=" REF BaseText \* Upper "><w:r><w:t>stale nested explicit ref</w:t></w:r></w:fldSimple><w:bookmarkEnd w:id="8"/></w:p><w:p><w:bookmarkStart w:id="9" w:name="ComputedDirect"/><w:fldSimple w:instr=" BaseText \* FirstCap "><w:r><w:t>stale nested direct ref</w:t></w:r></w:fldSimple><w:bookmarkEnd w:id="9"/></w:p><w:p><w:fldSimple w:instr=" REF ComputedExplicit "><w:r><w:t>stale outer explicit ref</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" REF ComputedDirect "><w:r><w:t>stale outer direct ref</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn ref_deleted_bookmark_text_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:bookmarkStart w:id="7" w:name="ClauseText"/><w:r><w:t>Visible clause</w:t></w:r><w:del><w:r><w:t> deleted clause</w:t></w:r></w:del><w:moveFrom><w:r><w:t> moved clause</w:t></w:r></w:moveFrom><w:bookmarkEnd w:id="7"/></w:p><w:p><w:fldSimple w:instr=" REF ClauseText "><w:r><w:t>stale deleted ref</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn ref_alternate_content_bookmark_text_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"><w:body><w:p><w:bookmarkStart w:id="7" w:name="AltText"/><w:r><mc:AlternateContent><mc:Choice Requires="wps"><w:t>Choice clause</w:t></mc:Choice><mc:Fallback><w:t>Fallback clause</w:t></mc:Fallback></mc:AlternateContent></w:r><w:bookmarkEnd w:id="7"/></w:p><w:p><w:fldSimple w:instr=" REF AltText "><w:r><w:t>stale alternate ref</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn complex_ref_bookmark_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:bookmarkStart w:id="7" w:name="Figure1"/><w:r><w:t>Figure 1</w:t></w:r><w:bookmarkEnd w:id="7"/></w:p><w:p><w:r><w:fldChar w:fldCharType="begin"/></w:r><w:r><w:instrText> REF Figure1 </w:instrText></w:r><w:r><w:fldChar w:fldCharType="separate"/></w:r><w:r><w:t>stale complex ref</w:t></w:r><w:r><w:fldChar w:fldCharType="end"/></w:r></w:p></w:body></w:document>"#,
),
])
}
fn complex_direct_bookmark_ref_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:bookmarkStart w:id="7" w:name="Figure1"/><w:r><w:t>figure one</w:t></w:r><w:bookmarkEnd w:id="7"/></w:p><w:p><w:r><w:fldChar w:fldCharType="begin"/></w:r><w:r><w:instrText> Figure1 \* Upper </w:instrText></w:r><w:r><w:fldChar w:fldCharType="separate"/></w:r><w:r><w:t>stale complex direct ref</w:t></w:r><w:r><w:fldChar w:fldCharType="end"/></w:r></w:p></w:body></w:document>"#,
),
])
}
fn multi_paragraph_ref_bookmark_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:bookmarkStart w:id="11" w:name="ClauseText"/><w:r><w:t>First paragraph.</w:t></w:r></w:p><w:p><w:r><w:t>Second paragraph.</w:t></w:r><w:bookmarkEnd w:id="11"/></w:p><w:p><w:fldSimple w:instr=" REF ClauseText "><w:r><w:t>stale multi ref</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn inline_break_ref_bookmark_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:bookmarkStart w:id="12" w:name="InlineText"/><w:r><w:t>Alpha</w:t><w:tab/><w:t>Beta</w:t><w:br/><w:t>Gamma</w:t><w:noBreakHyphen/><w:t>Delta</w:t></w:r><w:bookmarkEnd w:id="12"/></w:p><w:p><w:fldSimple w:instr=" REF InlineText "><w:r><w:t>stale inline ref</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn symbol_ref_bookmark_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:bookmarkStart w:id="13" w:name="SymbolText"/><w:r><w:t>Alpha </w:t><w:sym w:font="Symbol" w:char="F0B7"/><w:t> Beta</w:t></w:r><w:bookmarkEnd w:id="13"/></w:p><w:p><w:fldSimple w:instr=" REF SymbolText "><w:r><w:t>stale symbol ref</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn hidden_ref_bookmark_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:bookmarkStart w:id="9" w:name="_Ref123456789"/><w:r><w:t>Table 2</w:t></w:r><w:bookmarkEnd w:id="9"/></w:p><w:p><w:fldSimple w:instr=" REF _Ref123456789 "><w:r><w:t>stale hidden ref</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn direct_bookmark_ref_field_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:bookmarkStart w:id="7" w:name="Figure1"/><w:r><w:t>Figure 1</w:t></w:r><w:bookmarkEnd w:id="7"/></w:p><w:p><w:fldSimple w:instr=" Figure1 "><w:r><w:t>stale direct ref</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn known_field_name_direct_bookmark_collision_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:bookmarkStart w:id="7" w:name="PAGEREF"/><w:r><w:t>bookmark target</w:t></w:r><w:bookmarkEnd w:id="7"/></w:p><w:p><w:fldSimple w:instr=" PAGEREF "><w:r><w:t>cached known page ref</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn direct_bookmark_ref_switch_field_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:bookmarkStart w:id="7" w:name="Figure1"/><w:r><w:t>figure one</w:t></w:r><w:bookmarkEnd w:id="7"/></w:p><w:p><w:fldSimple w:instr=" Figure1 \* Upper "><w:r><w:t>stale direct upper</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" Figure1 \*FirstCap "><w:r><w:t>stale direct first-cap</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" Figure1 \h "><w:r><w:t>stale direct hyperlink</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" Figure1 \d "-" "><w:r><w:t>direct sequence separator</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" Figure1 \f "><w:r><w:t>direct note mark</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn bookmark_ref_number_format_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:bookmarkStart w:id="7" w:name="InvoiceTotal"/><w:r><w:t>21</w:t></w:r><w:bookmarkEnd w:id="7"/></w:p><w:p><w:fldSimple w:instr=" REF InvoiceTotal \* CardText "><w:r><w:t>stale cardtext ref</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" InvoiceTotal \* Ordinal "><w:r><w:t>stale direct ordinal</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" InvoiceTotal \* CardText \* Upper "><w:r><w:t>stale direct uppercase cardtext</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn direct_relative_ref_switch_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:fldSimple w:instr=" LaterBookmark \p "><w:r><w:t>stale direct below</w:t></w:r></w:fldSimple></w:p><w:p><w:bookmarkStart w:id="8" w:name="LaterBookmark"/><w:r><w:t>Later target</w:t></w:r><w:bookmarkEnd w:id="8"/></w:p><w:p><w:bookmarkStart w:id="7" w:name="Figure1"/><w:r><w:t>Figure 1</w:t></w:r><w:bookmarkEnd w:id="7"/></w:p><w:p><w:fldSimple w:instr=" Figure1 \p "><w:r><w:t>stale direct above</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn ref_text_format_switch_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:bookmarkStart w:id="7" w:name="Figure1"/><w:r><w:t>figure one</w:t></w:r><w:bookmarkEnd w:id="7"/></w:p><w:p><w:fldSimple w:instr=" REF Figure1 \* Upper "><w:r><w:t>stale upper ref</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" REF Figure1 \*Lower "><w:r><w:t>stale lower ref</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" REF Figure1 \* Caps "><w:r><w:t>stale caps ref</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" REF Figure1 \*FirstCap "><w:r><w:t>stale first-cap ref</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" REF Figure1 \* MERGEFORMATINET "><w:r><w:t>stale web-format ref</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn broader_ref_switch_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:bookmarkStart w:id="7" w:name="Figure1"/><w:r><w:t>Figure 1</w:t></w:r><w:bookmarkEnd w:id="7"/></w:p><w:p><w:fldSimple w:instr=" REF Figure1 \f "><w:r><w:t>note mark</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn ref_gap_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:bookmarkStart w:id="7" w:name="PlainText"/><w:r><w:t>Plain target</w:t></w:r><w:bookmarkEnd w:id="7"/></w:p><w:p><w:fldSimple w:instr=" REF PlainText \f "><w:r><w:t>cached non-note ref mark</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" REF PlainText \d- "><w:r><w:t>cached ref separator</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" REF MissingRef "><w:r><w:t>cached missing ref</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
#[cfg(feature = "render")]
fn ref_existing_target_numeric_gap_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:bookmarkStart w:id="7" w:name="PlainText"/><w:r><w:t>Plain target</w:t></w:r><w:bookmarkEnd w:id="7"/></w:p><w:p><w:fldSimple w:instr=" REF PlainText \n "><w:r><w:t>cached number</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn note_ref_field_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/><Override PartName="/word/footnotes.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.footnotes+xml"/><Override PartName="/word/endnotes.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.endnotes+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/_rels/document.xml.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rIdFoot" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/footnotes" Target="footnotes.xml"/><Relationship Id="rIdEnd" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/endnotes" Target="endnotes.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:fldSimple w:instr=" NOTEREF LaterNote \p "><w:r><w:t>stale below note</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" NOTEREF LaterNote \p \* Upper "><w:r><w:t>stale uppercase below note</w:t></w:r></w:fldSimple></w:p><w:del><w:r><w:footnoteReference w:id="99"/></w:r></w:del><w:p><w:r><w:t>First reference</w:t></w:r><w:bookmarkStart w:id="7" w:name="FootOne"/><w:r><w:footnoteReference w:id="1"/></w:r><w:bookmarkEnd w:id="7"/></w:p><w:p><w:r><w:t>Second reference</w:t></w:r><w:bookmarkStart w:id="8" w:name="LaterNote"/><w:r><w:footnoteReference w:id="2"/></w:r><w:bookmarkEnd w:id="8"/></w:p><w:p><w:fldSimple w:instr=" NOTEREF FootOne \h "><w:r><w:t>stale note mark</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" FTNREF FootOne "><w:r><w:t>stale legacy note mark</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" NOTEREF FootOne \f \* MERGEFORMAT "><w:r><w:t>stale formatted note mark</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" NOTEREF FootOne \h\f "><w:r><w:t>stale compact note mark</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" NOTEREF FootOne \p "><w:r><w:t>stale above note</w:t></w:r></w:fldSimple></w:p><w:p><w:bookmarkStart w:id="9" w:name="EndOne"/><w:r><w:endnoteReference w:id="3"/></w:r><w:bookmarkEnd w:id="9"/></w:p><w:p><w:fldSimple w:instr=" NOTEREF EndOne "><w:r><w:t>stale endnote mark</w:t></w:r></w:fldSimple></w:p><w:p><w:r><w:fldChar w:fldCharType="begin"/></w:r><w:r><w:instrText> NOTEREF LaterNote </w:instrText></w:r><w:r><w:fldChar w:fldCharType="separate"/></w:r><w:r><w:t>stale complex note mark</w:t></w:r><w:r><w:fldChar w:fldCharType="end"/></w:r></w:p><w:p><w:fldSimple w:instr=" NOTEREF MissingNote "><w:r><w:t>stale missing note</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
(
"word/footnotes.xml",
r#"<w:footnotes xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:footnote w:type="separator" w:id="-1"><w:p><w:r><w:separator/></w:r></w:p></w:footnote><w:footnote w:id="1"><w:p><w:r><w:t>First footnote.</w:t></w:r></w:p></w:footnote><w:footnote w:id="2"><w:p><w:r><w:t>Second footnote.</w:t></w:r></w:p></w:footnote></w:footnotes>"#,
),
(
"word/endnotes.xml",
r#"<w:endnotes xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:endnote w:id="3"><w:p><w:r><w:t>First endnote.</w:t></w:r></w:p></w:endnote></w:endnotes>"#,
),
])
}
fn note_ref_gap_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:bookmarkStart w:id="7" w:name="PlainText"/><w:r><w:t>Plain target</w:t></w:r><w:bookmarkEnd w:id="7"/></w:p><w:p><w:fldSimple w:instr=" NOTEREF PlainText "><w:r><w:t>cached plain note ref</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" NOTEREF MissingNote "><w:r><w:t>cached missing note ref</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" NOTEREF PlainText \x "><w:r><w:t>cached bad note ref switch</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn note_body_field_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/><Override PartName="/word/footnotes.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.footnotes+xml"/><Override PartName="/word/endnotes.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.endnotes+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/_rels/document.xml.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rIdFoot" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/footnotes" Target="footnotes.xml"/><Relationship Id="rIdEnd" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/endnotes" Target="endnotes.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:r><w:t>Body</w:t></w:r><w:r><w:footnoteReference w:id="1"/></w:r><w:r><w:endnoteReference w:id="2"/></w:r></w:p></w:body></w:document>"#,
),
(
"word/footnotes.xml",
r#"<w:footnotes xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:footnote w:type="separator" w:id="-1"><w:p><w:r><w:separator/></w:r></w:p></w:footnote><w:footnote w:id="1"><w:p><w:fldSimple w:instr=" FILENAME \p "><w:r><w:t>note.docx</w:t></w:r></w:fldSimple></w:p></w:footnote></w:footnotes>"#,
),
(
"word/endnotes.xml",
r#"<w:endnotes xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:endnote w:id="2"><w:p><w:fldSimple w:instr=" PAGE "><w:r><w:t>4</w:t></w:r></w:fldSimple></w:p></w:endnote></w:endnotes>"#,
),
])
}
fn note_ref_stale_computed_field_result_marker_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:bookmarkStart w:id="7" w:name="ComputedNote"/><w:fldSimple w:instr=" QUOTE "Plain text" "><w:r><w:footnoteReference w:id="1"/></w:r></w:fldSimple><w:bookmarkEnd w:id="7"/></w:p><w:p><w:fldSimple w:instr=" NOTEREF ComputedNote "><w:r><w:t>cached stale note ref</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn note_ref_empty_document_info_result_marker_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/><Override PartName="/docProps/core.xml" ContentType="application/vnd.openxmlformats-package.core-properties+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/><Relationship Id="rIdCore" Type="http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties" Target="docProps/core.xml"/></Relationships>"#,
),
(
"docProps/core.xml",
r#"<cp:coreProperties xmlns:cp="http://schemas.openxmlformats.org/package/2006/metadata/core-properties" xmlns:dc="http://purl.org/dc/elements/1.1/"><dc:title/></cp:coreProperties>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:bookmarkStart w:id="7" w:name="ComputedNote"/><w:fldSimple w:instr=" TITLE "><w:r><w:footnoteReference w:id="1"/></w:r><w:r><w:t>stale note title</w:t></w:r></w:fldSimple><w:bookmarkEnd w:id="7"/></w:p><w:p><w:fldSimple w:instr=" NOTEREF ComputedNote "><w:r><w:t>cached stale document-info note ref</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn note_ref_empty_revision_number_result_marker_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/><Override PartName="/docProps/core.xml" ContentType="application/vnd.openxmlformats-package.core-properties+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/><Relationship Id="rIdCore" Type="http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties" Target="docProps/core.xml"/></Relationships>"#,
),
(
"docProps/core.xml",
r#"<cp:coreProperties xmlns:cp="http://schemas.openxmlformats.org/package/2006/metadata/core-properties"><cp:revision/></cp:coreProperties>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:bookmarkStart w:id="7" w:name="ComputedNote"/><w:fldSimple w:instr=" REVNUM "><w:r><w:footnoteReference w:id="1"/></w:r><w:r><w:t>stale note revision</w:t></w:r></w:fldSimple><w:bookmarkEnd w:id="7"/></w:p><w:p><w:fldSimple w:instr=" NOTEREF ComputedNote "><w:r><w:t>cached stale revision note ref</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn note_ref_empty_legacy_form_result_marker_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:bookmarkStart w:id="7" w:name="ComputedNote"/><w:fldSimple w:instr=" FORMDROPDOWN "><w:ffData><w:ddList><w:result w:val="0"/><w:listEntry w:val=""/></w:ddList></w:ffData><w:r><w:footnoteReference w:id="1"/></w:r><w:r><w:t>stale note option</w:t></w:r></w:fldSimple><w:bookmarkEnd w:id="7"/></w:p><w:p><w:fldSimple w:instr=" NOTEREF ComputedNote "><w:r><w:t>cached stale legacy form note ref</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn note_ref_bookmark_merge_control_result_marker_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:bookmarkStart w:id="7" w:name="ComputedNote"/><w:fldSimple w:instr=" NEXTIF Gate = "Ready" "><w:r><w:footnoteReference w:id="1"/></w:r><w:r><w:t>stale note merge control</w:t></w:r></w:fldSimple><w:bookmarkEnd w:id="7"/></w:p><w:p><w:fldSimple w:instr=" NOTEREF ComputedNote "><w:r><w:t>cached stale bookmark merge note ref</w:t></w:r></w:fldSimple></w:p><w:p><w:bookmarkStart w:id="8" w:name="Gate"/><w:r><w:t>Ready</w:t></w:r><w:bookmarkEnd w:id="8"/></w:p></w:body></w:document>"#,
),
])
}
fn note_ref_bookmark_if_result_marker_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:bookmarkStart w:id="7" w:name="ComputedNote"/><w:fldSimple w:instr=" IF Gate = "Ready" "" "" "><w:r><w:footnoteReference w:id="1"/></w:r><w:r><w:t>stale note if</w:t></w:r></w:fldSimple><w:bookmarkEnd w:id="7"/></w:p><w:p><w:fldSimple w:instr=" NOTEREF ComputedNote "><w:r><w:t>cached stale bookmark if note ref</w:t></w:r></w:fldSimple></w:p><w:p><w:bookmarkStart w:id="8" w:name="Gate"/><w:r><w:t>Ready</w:t></w:r><w:bookmarkEnd w:id="8"/></w:p></w:body></w:document>"#,
),
])
}
fn note_ref_bookmark_compare_result_marker_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:bookmarkStart w:id="7" w:name="ComputedNote"/><w:fldSimple w:instr=" COMPARE Gate = "Ready" "><w:r><w:footnoteReference w:id="1"/></w:r><w:r><w:t>stale note compare</w:t></w:r></w:fldSimple><w:bookmarkEnd w:id="7"/></w:p><w:p><w:fldSimple w:instr=" NOTEREF ComputedNote "><w:r><w:t>cached stale bookmark compare note ref</w:t></w:r></w:fldSimple></w:p><w:p><w:bookmarkStart w:id="8" w:name="Gate"/><w:r><w:t>Ready</w:t></w:r><w:bookmarkEnd w:id="8"/></w:p></w:body></w:document>"#,
),
])
}
fn note_ref_bookmark_formula_result_marker_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:bookmarkStart w:id="7" w:name="ComputedNote"/><w:fldSimple w:instr=" = InvoiceSubtotal + 8 "><w:r><w:footnoteReference w:id="1"/></w:r><w:r><w:t>stale note formula</w:t></w:r></w:fldSimple><w:bookmarkEnd w:id="7"/></w:p><w:p><w:fldSimple w:instr=" NOTEREF ComputedNote "><w:r><w:t>cached stale bookmark formula note ref</w:t></w:r></w:fldSimple></w:p><w:p><w:bookmarkStart w:id="8" w:name="InvoiceSubtotal"/><w:r><w:t>42</w:t></w:r><w:bookmarkEnd w:id="8"/></w:p></w:body></w:document>"#,
),
])
}
fn note_ref_stale_ref_result_marker_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:bookmarkStart w:id="1" w:name="EmptyTarget"/><w:bookmarkEnd w:id="1"/></w:p><w:p><w:bookmarkStart w:id="7" w:name="ComputedNote"/><w:fldSimple w:instr=" REF EmptyTarget "><w:r><w:footnoteReference w:id="1"/></w:r></w:fldSimple><w:bookmarkEnd w:id="7"/></w:p><w:p><w:fldSimple w:instr=" NOTEREF ComputedNote "><w:r><w:t>cached stale ref note ref</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn note_ref_stale_direct_bookmark_result_marker_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:bookmarkStart w:id="1" w:name="EmptyTarget"/><w:bookmarkEnd w:id="1"/></w:p><w:p><w:bookmarkStart w:id="7" w:name="ComputedNote"/><w:fldSimple w:instr=" EmptyTarget "><w:r><w:footnoteReference w:id="1"/></w:r></w:fldSimple><w:bookmarkEnd w:id="7"/></w:p><w:p><w:fldSimple w:instr=" NOTEREF ComputedNote "><w:r><w:t>cached stale direct note ref</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn note_ref_stale_complex_computed_field_result_marker_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:bookmarkStart w:id="7" w:name="ComputedNote"/><w:r><w:fldChar w:fldCharType="begin"/></w:r><w:r><w:instrText> QUOTE "Plain text" </w:instrText></w:r><w:r><w:fldChar w:fldCharType="separate"/></w:r><w:r><w:footnoteReference w:id="1"/></w:r><w:r><w:fldChar w:fldCharType="end"/></w:r><w:bookmarkEnd w:id="7"/></w:p><w:p><w:fldSimple w:instr=" NOTEREF ComputedNote "><w:r><w:t>cached stale complex note ref</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn note_ref_alternate_content_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/><Override PartName="/word/footnotes.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.footnotes+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/_rels/document.xml.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rIdFoot" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/footnotes" Target="footnotes.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="wps"><w:body><mc:AlternateContent><mc:Choice Requires="wps"><w:p/></mc:Choice><mc:Fallback><w:p><w:r><w:bookmarkStart w:id="50" w:name="FallbackNote"/><w:footnoteReference w:id="50"/><w:bookmarkEnd w:id="50"/></w:r></w:p></mc:Fallback></mc:AlternateContent><w:p><w:r><w:t>Target note</w:t></w:r><w:bookmarkStart w:id="7" w:name="FootOne"/><w:r><w:footnoteReference w:id="1"/></w:r><w:bookmarkEnd w:id="7"/></w:p><w:p><w:fldSimple w:instr=" NOTEREF FootOne "><w:r><w:t>stale alternate note</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" NOTEREF FootOne \p "><w:r><w:t>stale alternate relative</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
(
"word/footnotes.xml",
r#"<w:footnotes xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:footnote w:type="separator" w:id="-1"><w:p><w:r><w:separator/></w:r></w:p></w:footnote><w:footnote w:id="1"><w:p><w:r><w:t>First footnote.</w:t></w:r></w:p></w:footnote><w:footnote w:id="50"><w:p><w:r><w:t>Fallback footnote.</w:t></w:r></w:p></w:footnote></w:footnotes>"#,
),
])
}
fn note_ref_number_format_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:bookmarkStart w:id="7" w:name="FootOne"/><w:r><w:footnoteReference w:id="1"/></w:r><w:bookmarkEnd w:id="7"/></w:p><w:p><w:bookmarkStart w:id="8" w:name="LaterNote"/><w:r><w:footnoteReference w:id="2"/></w:r><w:bookmarkEnd w:id="8"/></w:p><w:p><w:fldSimple w:instr=" NOTEREF LaterNote \* roman "><w:r><w:t>stale roman note</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" NOTEREF FootOne \* OrdText \* Upper "><w:r><w:t>stale ordinal note</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn ref_note_switch_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/><Override PartName="/word/footnotes.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.footnotes+xml"/><Override PartName="/word/endnotes.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.endnotes+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/_rels/document.xml.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rIdFoot" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/footnotes" Target="footnotes.xml"/><Relationship Id="rIdEnd" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/endnotes" Target="endnotes.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:del><w:r><w:footnoteReference w:id="99"/></w:r></w:del><w:p><w:r><w:t>Target footnote</w:t></w:r><w:bookmarkStart w:id="7" w:name="FootOne"/><w:r><w:footnoteReference w:id="1"/></w:r><w:bookmarkEnd w:id="7"/></w:p><w:p><w:r><w:t>Second footnote</w:t></w:r><w:r><w:footnoteReference w:id="2"/></w:r></w:p><w:p><w:fldSimple w:instr=" REF FootOne \f "><w:r><w:t>stale foot ref mark</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" FootOne \f "><w:r><w:t>stale direct foot ref mark</w:t></w:r></w:fldSimple></w:p><w:p><w:bookmarkStart w:id="9" w:name="EndOne"/><w:r><w:endnoteReference w:id="3"/></w:r><w:bookmarkEnd w:id="9"/></w:p><w:p><w:fldSimple w:instr=" REF EndOne \h \f \* MERGEFORMAT "><w:r><w:t>stale end ref mark</w:t></w:r></w:fldSimple></w:p><w:p><w:r><w:fldChar w:fldCharType="begin"/></w:r><w:r><w:instrText> REF FootOne \f </w:instrText></w:r><w:r><w:fldChar w:fldCharType="separate"/></w:r><w:r><w:t>stale complex foot ref mark</w:t></w:r><w:r><w:fldChar w:fldCharType="end"/></w:r></w:p><w:p><w:fldSimple w:instr=" REF FootOne \f \* roman "><w:r><w:t>stale roman foot ref mark</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
(
"word/footnotes.xml",
r#"<w:footnotes xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:footnote w:type="separator" w:id="-1"><w:p><w:r><w:separator/></w:r></w:p></w:footnote><w:footnote w:id="1"><w:p><w:r><w:t>First footnote.</w:t></w:r></w:p></w:footnote><w:footnote w:id="2"><w:p><w:r><w:t>Second footnote.</w:t></w:r></w:p></w:footnote></w:footnotes>"#,
),
(
"word/endnotes.xml",
r#"<w:endnotes xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:endnote w:id="3"><w:p><w:r><w:t>First endnote.</w:t></w:r></w:p></w:endnote></w:endnotes>"#,
),
])
}
fn ref_comment_reference_mark_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:bookmarkStart w:id="7" w:name="CommentOne"/><w:r><w:commentReference w:id="0"/></w:r><w:bookmarkEnd w:id="7"/></w:p><w:p><w:bookmarkStart w:id="8" w:name="CommentTwo"/><w:r><w:commentReference w:id="1"/></w:r><w:bookmarkEnd w:id="8"/></w:p><w:p><w:fldSimple w:instr=" REF CommentOne \f "><w:r><w:t>stale comment one</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" CommentTwo \f \* ROMAN "><w:r><w:t>stale comment two</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn ref_comment_range_reference_mark_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:bookmarkStart w:id="7" w:name="CommentedRange"/><w:commentRangeStart w:id="0"/><w:r><w:t>Commented text</w:t></w:r><w:commentRangeEnd w:id="0"/><w:bookmarkEnd w:id="7"/><w:r><w:commentReference w:id="0"/></w:r></w:p><w:p><w:fldSimple w:instr=" REF CommentedRange \f "><w:r><w:t>stale range comment</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn numbered_ref_switch_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/><Override PartName="/word/numbering.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.numbering+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:pPr><w:numPr><w:ilvl w:val="0"/><w:numId w:val=" 42 "/></w:numPr></w:pPr><w:bookmarkStart w:id="7" w:name="Clause"/><w:r><w:t>Numbered clause</w:t></w:r><w:bookmarkEnd w:id="7"/></w:p><w:p><w:fldSimple w:instr=" REF Clause \n "><w:r><w:t>stale number</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" REF Clause \n \p "><w:r><w:t>stale number relative</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" REF Clause \n\p "><w:r><w:t>stale compact number relative</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" Clause \n "><w:r><w:t>stale direct number</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" Clause \n\t "><w:r><w:t>stale compact direct numeric</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
(
"word/numbering.xml",
r#"<w:numbering xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:abstractNum w:abstractNumId="9"><w:lvl w:ilvl="0"><w:start w:val=" 3 "/><w:numFmt w:val="decimal"/><w:lvlText w:val=" "/></w:lvl></w:abstractNum><w:num w:numId="42"><w:abstractNumId w:val=" 9 "/></w:num></w:numbering>"#,
),
])
}
fn alternate_content_numbered_ref_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/><Override PartName="/word/numbering.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.numbering+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"><w:body><mc:AlternateContent><mc:Choice Requires="wps"><w:p><w:pPr><w:numPr><w:ilvl w:val="0"/><w:numId w:val="45"/></w:numPr></w:pPr><w:r><w:t>Choice preface</w:t></w:r></w:p></mc:Choice><mc:Fallback><w:p><w:pPr><w:numPr><w:ilvl w:val="0"/><w:numId w:val="45"/></w:numPr></w:pPr><w:r><w:t>Fallback preface</w:t></w:r></w:p></mc:Fallback></mc:AlternateContent><w:p><w:pPr><w:numPr><w:ilvl w:val="0"/><w:numId w:val="45"/></w:numPr></w:pPr><w:bookmarkStart w:id="7" w:name="AltClause"/><w:r><w:t>Target clause</w:t></w:r><w:bookmarkEnd w:id="7"/></w:p><w:p><w:fldSimple w:instr=" REF AltClause \n "><w:r><w:t>stale alt number</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
(
"word/numbering.xml",
r#"<w:numbering xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:abstractNum w:abstractNumId="10"><w:lvl w:ilvl="0"><w:start w:val="1"/><w:numFmt w:val="decimal"/><w:lvlText w:val="%1."/></w:lvl></w:abstractNum><w:num w:numId="45"><w:abstractNumId w:val="10"/></w:num></w:numbering>"#,
),
])
}
fn numbering_alternate_content_ref_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/><Override PartName="/word/numbering.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.numbering+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:pPr><w:numPr><w:ilvl w:val="0"/><w:numId w:val="46"/></w:numPr></w:pPr><w:bookmarkStart w:id="7" w:name="NumberingChoice"/><w:r><w:t>Selected numbering clause</w:t></w:r><w:bookmarkEnd w:id="7"/></w:p><w:p><w:fldSimple w:instr=" REF NumberingChoice \n "><w:r><w:t>stale numbering alternate</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
(
"word/numbering.xml",
r#"<w:numbering xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"><mc:AlternateContent><mc:Choice Requires="w14"><w:abstractNum w:abstractNumId="20"><w:lvl w:ilvl="0"><w:start w:val="5"/><w:numFmt w:val="decimal"/><w:lvlText w:val="%1."/></w:lvl></w:abstractNum><w:num w:numId="46"><w:abstractNumId w:val="20"/></w:num></mc:Choice><mc:Fallback><w:abstractNum w:abstractNumId="21"><w:lvl w:ilvl="0"><w:start w:val="9"/><w:numFmt w:val="upperRoman"/><w:lvlText w:val="%1."/></w:lvl></w:abstractNum><w:num w:numId="46"><w:abstractNumId w:val="21"/></w:num></mc:Fallback></mc:AlternateContent></w:numbering>"#,
),
])
}
fn ref_numbering_property_revision_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/><Override PartName="/word/numbering.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.numbering+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:pPr><w:pPrChange><w:pPr><w:numPr><w:ilvl w:val="0"/><w:numId w:val="92"/></w:numPr></w:pPr></w:pPrChange></w:pPr><w:bookmarkStart w:id="7" w:name="OldClause"/><w:r><w:t>Former numbered clause</w:t></w:r><w:bookmarkEnd w:id="7"/></w:p><w:p><w:pPr><w:numPr><w:ilvl w:val="0"/><w:numId w:val="92"/></w:numPr></w:pPr><w:bookmarkStart w:id="8" w:name="CurrentClause"/><w:r><w:t>Current numbered clause</w:t></w:r><w:bookmarkEnd w:id="8"/></w:p><w:p><w:pPr><w:pPrChange><w:pPr><w:numPr><w:ilvl w:val="0"/><w:numId w:val="92"/></w:numPr></w:pPr></w:pPrChange></w:pPr><w:fldSimple w:instr=" REF OldClause \n "><w:r><w:t>cached old number</w:t></w:r></w:fldSimple><w:r><w:t> </w:t></w:r><w:fldSimple w:instr=" REF CurrentClause \n "><w:r><w:t>stale current number</w:t></w:r></w:fldSimple><w:r><w:t> </w:t></w:r><w:fldSimple w:instr=" REF CurrentClause \r "><w:r><w:t>cached relative old context</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
(
"word/numbering.xml",
r#"<w:numbering xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:abstractNum w:abstractNumId="16"><w:lvl w:ilvl="0"><w:start w:val="1"/><w:numFmt w:val="decimal"/><w:lvlText w:val="%1."/></w:lvl></w:abstractNum><w:num w:numId="92"><w:abstractNumId w:val="16"/></w:num></w:numbering>"#,
),
])
}
fn numbered_ref_suppress_text_switch_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/><Override PartName="/word/numbering.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.numbering+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:pPr><w:numPr><w:ilvl w:val="0"/><w:numId w:val="77"/></w:numPr></w:pPr><w:bookmarkStart w:id="9" w:name="SectionClause"/><w:r><w:t>Section clause</w:t></w:r><w:bookmarkEnd w:id="9"/></w:p><w:p><w:fldSimple w:instr=" REF SectionClause \n \t "><w:r><w:t>stale numeric text</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" REF SectionClause \n \t \p "><w:r><w:t>stale numeric relative</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" SectionClause \n \t "><w:r><w:t>stale direct numeric text</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
(
"word/numbering.xml",
r#"<w:numbering xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:abstractNum w:abstractNumId="11"><w:lvl w:ilvl="0"><w:start w:val="1"/><w:numFmt w:val="decimal"/><w:lvlText w:val="Section %1.01,"/></w:lvl></w:abstractNum><w:num w:numId="77"><w:abstractNumId w:val="11"/></w:num></w:numbering>"#,
),
])
}
fn full_context_ref_switch_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/><Override PartName="/word/numbering.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.numbering+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:pPr><w:numPr><w:ilvl w:val="0"/><w:numId w:val="88"/></w:numPr></w:pPr><w:r><w:t>Top clause</w:t></w:r></w:p><w:p><w:pPr><w:numPr><w:ilvl w:val="1"/><w:numId w:val="88"/></w:numPr></w:pPr><w:r><w:t>Child clause</w:t></w:r></w:p><w:p><w:pPr><w:numPr><w:ilvl w:val="2"/><w:numId w:val="88"/></w:numPr></w:pPr><w:bookmarkStart w:id="12" w:name="DeepClause"/><w:r><w:t>Deep clause</w:t></w:r><w:bookmarkEnd w:id="12"/></w:p><w:p><w:fldSimple w:instr=" REF DeepClause \w "><w:r><w:t>stale full context</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" REF DeepClause \w \p "><w:r><w:t>stale full relative</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" DeepClause \w "><w:r><w:t>stale direct full</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
(
"word/numbering.xml",
r#"<w:numbering xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:abstractNum w:abstractNumId="12"><w:lvl w:ilvl="0"><w:start w:val="1"/><w:numFmt w:val="decimal"/><w:lvlText w:val="%1."/></w:lvl><w:lvl w:ilvl="1"><w:start w:val="1"/><w:numFmt w:val="lowerLetter"/><w:lvlText w:val="%2."/></w:lvl><w:lvl w:ilvl="2"><w:start w:val="1"/><w:numFmt w:val="lowerRoman"/><w:lvlText w:val="%3."/></w:lvl></w:abstractNum><w:num w:numId="88"><w:abstractNumId w:val="12"/></w:num></w:numbering>"#,
),
])
}
fn full_context_ref_suppress_text_switch_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/><Override PartName="/word/numbering.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.numbering+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:pPr><w:numPr><w:ilvl w:val="0"/><w:numId w:val="89"/></w:numPr></w:pPr><w:r><w:t>Top clause</w:t></w:r></w:p><w:p><w:pPr><w:numPr><w:ilvl w:val="1"/><w:numId w:val="89"/></w:numPr></w:pPr><w:r><w:t>Child clause</w:t></w:r></w:p><w:p><w:pPr><w:numPr><w:ilvl w:val="2"/><w:numId w:val="89"/></w:numPr></w:pPr><w:bookmarkStart w:id="13" w:name="DeepClause"/><w:r><w:t>Deep clause</w:t></w:r><w:bookmarkEnd w:id="13"/></w:p><w:p><w:fldSimple w:instr=" REF DeepClause \w \t "><w:r><w:t>stale full numeric text</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" REF DeepClause \w \t \p "><w:r><w:t>stale full numeric relative</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" DeepClause \w \t "><w:r><w:t>stale direct full numeric</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
(
"word/numbering.xml",
r#"<w:numbering xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:abstractNum w:abstractNumId="13"><w:lvl w:ilvl="0"><w:start w:val="1"/><w:numFmt w:val="decimal"/><w:lvlText w:val="Section %1."/></w:lvl><w:lvl w:ilvl="1"><w:start w:val="1"/><w:numFmt w:val="lowerLetter"/><w:lvlText w:val="Article %2."/></w:lvl><w:lvl w:ilvl="2"><w:start w:val="1"/><w:numFmt w:val="lowerRoman"/><w:lvlText w:val="Part %3."/></w:lvl></w:abstractNum><w:num w:numId="89"><w:abstractNumId w:val="13"/></w:num></w:numbering>"#,
),
])
}
fn relative_context_ref_switch_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/><Override PartName="/word/numbering.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.numbering+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:pPr><w:numPr><w:ilvl w:val="0"/><w:numId w:val="90"/></w:numPr></w:pPr><w:r><w:t>Top 4</w:t></w:r></w:p><w:p><w:pPr><w:numPr><w:ilvl w:val="1"/><w:numId w:val="90"/></w:numPr></w:pPr><w:r><w:t>Child 4.3</w:t></w:r></w:p><w:p><w:pPr><w:numPr><w:ilvl w:val="2"/><w:numId w:val="90"/></w:numPr></w:pPr><w:fldSimple w:instr=" REF LaterClause \r "><w:r><w:t>stale relative context</w:t></w:r></w:fldSimple><w:r><w:t> </w:t></w:r><w:fldSimple w:instr=" REF LaterClause \r \p "><w:r><w:t>stale relative context position</w:t></w:r></w:fldSimple><w:r><w:t> </w:t></w:r><w:fldSimple w:instr=" LaterClause \r \t "><w:r><w:t>stale direct relative context</w:t></w:r></w:fldSimple></w:p><w:p><w:pPr><w:numPr><w:ilvl w:val="1"/><w:numId w:val="90"/></w:numPr></w:pPr><w:r><w:t>Child 4.4</w:t></w:r></w:p><w:p><w:pPr><w:numPr><w:ilvl w:val="1"/><w:numId w:val="90"/></w:numPr></w:pPr><w:r><w:t>Child 4.5</w:t></w:r></w:p><w:p><w:pPr><w:numPr><w:ilvl w:val="2"/><w:numId w:val="90"/></w:numPr></w:pPr><w:r><w:t>Target sibling 4.5.1</w:t></w:r></w:p><w:p><w:pPr><w:numPr><w:ilvl w:val="2"/><w:numId w:val="90"/></w:numPr></w:pPr><w:bookmarkStart w:id="14" w:name="LaterClause"/><w:r><w:t>Target 4.5.2</w:t></w:r><w:bookmarkEnd w:id="14"/></w:p></w:body></w:document>"#,
),
(
"word/numbering.xml",
r#"<w:numbering xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:abstractNum w:abstractNumId="14"><w:lvl w:ilvl="0"><w:start w:val="4"/><w:numFmt w:val="decimal"/><w:lvlText w:val="%1."/></w:lvl><w:lvl w:ilvl="1"><w:start w:val="3"/><w:numFmt w:val="decimal"/><w:lvlText w:val="%2."/></w:lvl><w:lvl w:ilvl="2"><w:start w:val="1"/><w:numFmt w:val="decimal"/><w:lvlText w:val="%3."/></w:lvl></w:abstractNum><w:num w:numId="90"><w:abstractNumId w:val="14"/></w:num></w:numbering>"#,
),
])
}
fn relative_ref_switch_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:fldSimple w:instr=" REF LaterBookmark \p "><w:r><w:t>stale below</w:t></w:r></w:fldSimple></w:p><w:p><w:bookmarkStart w:id="8" w:name="LaterBookmark"/><w:r><w:t>Later target</w:t></w:r><w:bookmarkEnd w:id="8"/></w:p><w:p><w:bookmarkStart w:id="7" w:name="Figure1"/><w:r><w:t>Figure 1</w:t></w:r><w:bookmarkEnd w:id="7"/></w:p><w:p><w:fldSimple w:instr=" REF Figure1 \p "><w:r><w:t>stale above</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn relative_ref_alternate_content_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"><w:body><mc:AlternateContent><mc:Choice Requires="wps"><w:p/></mc:Choice><mc:Fallback><w:p><w:fldSimple w:instr=" REF LaterBookmark \p "><w:r><w:t>fallback relative</w:t></w:r></w:fldSimple></w:p></mc:Fallback></mc:AlternateContent><w:p><w:bookmarkStart w:id="8" w:name="LaterBookmark"/><w:r><w:t>Later target</w:t></w:r><w:bookmarkEnd w:id="8"/></w:p><w:p><w:fldSimple w:instr=" REF LaterBookmark \p "><w:r><w:t>stale visible above</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn page_ref_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:bookmarkStart w:id="7" w:name="Figure1"/><w:r><w:t>Figure 1</w:t></w:r><w:bookmarkEnd w:id="7"/></w:p><w:p><w:bookmarkStart w:id="9" w:name="TableOne"/><w:r><w:t>Table 1</w:t></w:r><w:bookmarkEnd w:id="9"/></w:p><w:p><w:fldSimple w:instr=" PAGEREF Figure1 \h "><w:r><w:t>3</w:t></w:r></w:fldSimple></w:p><w:p><w:r><w:fldChar w:fldCharType="begin"/></w:r><w:r><w:instrText> PAGEREF "TableOne" \p </w:instrText></w:r><w:r><w:fldChar w:fldCharType="separate"/></w:r><w:r><w:t>above</w:t></w:r><w:r><w:fldChar w:fldCharType="end"/></w:r></w:p></w:body></w:document>"#,
),
])
}
fn page_ref_gap_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:bookmarkStart w:id="7" w:name="PlainText"/><w:r><w:t>Plain target</w:t></w:r><w:bookmarkEnd w:id="7"/></w:p><w:p><w:fldSimple w:instr=" PAGEREF PlainText \h "><w:r><w:t>cached page ref</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" PAGEREF MissingPage \h "><w:r><w:t>cached missing page ref</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn page_ref_manual_break_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:r><w:br w:type="page"/></w:r></w:p><w:p><w:bookmarkStart w:id="7" w:name="Figure1"/><w:r><w:t>Figure 1</w:t></w:r><w:bookmarkEnd w:id="7"/><w:r><w:br w:type="page"/></w:r></w:p><w:p><w:fldSimple w:instr=" PAGEREF Figure1 \h "><w:r><w:t>99</w:t></w:r></w:fldSimple></w:p><w:p><w:r><w:fldChar w:fldCharType="begin"/></w:r><w:r><w:instrText> PAGEREF "Figure1" \* MERGEFORMAT </w:instrText></w:r><w:r><w:fldChar w:fldCharType="separate"/></w:r><w:r><w:t>old page</w:t></w:r><w:r><w:fldChar w:fldCharType="end"/></w:r></w:p><w:p><w:fldSimple w:instr=" PAGEREF Figure1 \p "><w:r><w:t>above</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn page_ref_leading_break_relative_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:r><w:br w:type="page"/></w:r></w:p><w:p><w:bookmarkStart w:id="7" w:name="Figure1"/><w:r><w:t>Figure 1</w:t></w:r><w:bookmarkEnd w:id="7"/></w:p><w:p><w:fldSimple w:instr=" PAGEREF Figure1 \p "><w:r><w:t>stale relative</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn ref_inside_comment_range_reference_mark_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:commentRangeStart w:id="0"/><w:r><w:t>Comment starts </w:t></w:r><w:bookmarkStart w:id="7" w:name="InsideComment"/><w:r><w:t>inside comment</w:t></w:r><w:bookmarkEnd w:id="7"/><w:r><w:t> comment ends</w:t></w:r><w:commentRangeEnd w:id="0"/><w:r><w:commentReference w:id="0"/></w:r></w:p><w:p><w:fldSimple w:instr=" REF InsideComment \f "><w:r><w:t>stale inside comment</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn page_ref_format_switch_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:r><w:br w:type="page"/></w:r></w:p><w:p><w:bookmarkStart w:id="7" w:name="Figure1"/><w:r><w:t>Figure 1</w:t></w:r><w:bookmarkEnd w:id="7"/></w:p><w:p><w:fldSimple w:instr=" PAGEREF Figure1 \* ROMAN "><w:r><w:t>stale upper roman</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" PAGEREF Figure1 \*roman "><w:r><w:t>stale lower roman</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" PAGEREF Figure1 \* alphabetic "><w:r><w:t>stale alphabetic</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" PAGEREF Figure1 \*ALPHABETIC "><w:r><w:t>stale upper alphabetic</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" PAGEREF Figure1 \* Ordinal "><w:r><w:t>stale ordinal</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" PAGEREF Figure1 \* CardText "><w:r><w:t>stale cardtext</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" PAGEREF Figure1 \* CardText \* Upper "><w:r><w:t>stale uppercase cardtext</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" PAGEREF Figure1 \* OrdText "><w:r><w:t>stale ordtext</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" PAGEREF Figure1 \* Arabic "><w:r><w:t>stale arabic</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" PAGEREF Figure1 \* ArabicDash "><w:r><w:t>stale arabic dash</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn page_ref_mixed_case_format_switch_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:r><w:br w:type="page"/></w:r></w:p><w:p><w:bookmarkStart w:id="7" w:name="Figure1"/><w:r><w:t>Figure 1</w:t></w:r><w:bookmarkEnd w:id="7"/></w:p><w:p><w:fldSimple w:instr=" PAGEREF Figure1 \* ArAbIc "><w:r><w:t>stale mixed arabic</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn page_ref_after_visible_manual_break_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:r><w:t>Cover text can auto-paginate before the hard break.</w:t><w:br w:type="page"/></w:r></w:p><w:p><w:bookmarkStart w:id="7" w:name="Figure1"/><w:r><w:t>Figure 1</w:t></w:r><w:bookmarkEnd w:id="7"/></w:p><w:p><w:fldSimple w:instr=" PAGEREF Figure1 \h "><w:r><w:t>99</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn page_ref_symbol_before_manual_break_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:r><w:sym w:font="Symbol" w:char="F0B7"/><w:br w:type="page"/></w:r></w:p><w:p><w:bookmarkStart w:id="7" w:name="FigureSymbol"/><w:r><w:t>Figure symbol</w:t></w:r><w:bookmarkEnd w:id="7"/></w:p><w:p><w:fldSimple w:instr=" PAGEREF FigureSymbol \h "><w:r><w:t>99</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn page_ref_note_mark_before_manual_break_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:r><w:footnoteReference w:id="1"/><w:br w:type="page"/></w:r></w:p><w:p><w:bookmarkStart w:id="7" w:name="FigureNote"/><w:r><w:t>Figure note</w:t></w:r><w:bookmarkEnd w:id="7"/></w:p><w:p><w:fldSimple w:instr=" PAGEREF FigureNote \h "><w:r><w:t>99</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn page_ref_comment_mark_before_manual_break_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:r><w:commentReference w:id="1"/><w:br w:type="page"/></w:r></w:p><w:p><w:bookmarkStart w:id="7" w:name="FigureComment"/><w:r><w:t>Figure comment</w:t></w:r><w:bookmarkEnd w:id="7"/></w:p><w:p><w:fldSimple w:instr=" PAGEREF FigureComment \h "><w:r><w:t>99</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn page_ref_computed_field_markers_before_manual_break_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:fldSimple w:instr=" SET SimpleHidden "Plain" "><w:r><w:footnoteReference w:id="1"/></w:r></w:fldSimple></w:p><w:p><w:r><w:fldChar w:fldCharType="begin"/></w:r><w:r><w:instrText> SET ComplexHidden "Plain" </w:instrText></w:r><w:r><w:fldChar w:fldCharType="separate"/></w:r><w:r><w:commentReference w:id="2"/></w:r><w:r><w:t>stale hidden field text</w:t></w:r><w:r><w:fldChar w:fldCharType="end"/></w:r></w:p><w:p><w:r><w:br w:type="page"/></w:r></w:p><w:p><w:bookmarkStart w:id="7" w:name="ComputedHiddenTarget"/><w:r><w:t>Computed hidden target</w:t></w:r><w:bookmarkEnd w:id="7"/></w:p><w:p><w:fldSimple w:instr=" PAGEREF ComputedHiddenTarget \h "><w:r><w:t>cached hidden page ref</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn page_ref_empty_document_info_before_manual_break_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/><Override PartName="/docProps/core.xml" ContentType="application/vnd.openxmlformats-package.core-properties+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/><Relationship Id="rIdCore" Type="http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties" Target="docProps/core.xml"/></Relationships>"#,
),
(
"docProps/core.xml",
r#"<cp:coreProperties xmlns:cp="http://schemas.openxmlformats.org/package/2006/metadata/core-properties" xmlns:dc="http://purl.org/dc/elements/1.1/"><dc:title/></cp:coreProperties>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:fldSimple w:instr=" TITLE "><w:r><w:t>stale page title</w:t></w:r></w:fldSimple></w:p><w:p><w:r><w:br w:type="page"/></w:r></w:p><w:p><w:bookmarkStart w:id="7" w:name="AfterEmptyTitle"/><w:r><w:t>After empty title</w:t></w:r><w:bookmarkEnd w:id="7"/></w:p><w:p><w:fldSimple w:instr=" PAGEREF AfterEmptyTitle \h "><w:r><w:t>cached after title page</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn page_ref_empty_revision_number_before_manual_break_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/><Override PartName="/docProps/core.xml" ContentType="application/vnd.openxmlformats-package.core-properties+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/><Relationship Id="rIdCore" Type="http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties" Target="docProps/core.xml"/></Relationships>"#,
),
(
"docProps/core.xml",
r#"<cp:coreProperties xmlns:cp="http://schemas.openxmlformats.org/package/2006/metadata/core-properties"><cp:revision/></cp:coreProperties>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:fldSimple w:instr=" REVNUM "><w:r><w:t>stale page revision</w:t></w:r></w:fldSimple></w:p><w:p><w:r><w:br w:type="page"/></w:r></w:p><w:p><w:bookmarkStart w:id="7" w:name="AfterEmptyRevision"/><w:r><w:t>After empty revision</w:t></w:r><w:bookmarkEnd w:id="7"/></w:p><w:p><w:fldSimple w:instr=" PAGEREF AfterEmptyRevision \h "><w:r><w:t>cached after revision page</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn page_ref_empty_legacy_form_before_manual_break_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:fldSimple w:instr=" FORMDROPDOWN "><w:ffData><w:ddList><w:result w:val="0"/><w:listEntry w:val=""/></w:ddList></w:ffData><w:r><w:t>stale page option</w:t></w:r></w:fldSimple></w:p><w:p><w:r><w:br w:type="page"/></w:r></w:p><w:p><w:bookmarkStart w:id="7" w:name="AfterEmptyForm"/><w:r><w:t>After empty form</w:t></w:r><w:bookmarkEnd w:id="7"/></w:p><w:p><w:fldSimple w:instr=" PAGEREF AfterEmptyForm \h "><w:r><w:t>cached after form page</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn page_ref_bookmark_merge_control_before_manual_break_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:fldSimple w:instr=" NEXTIF Gate = "Ready" "><w:r><w:t>stale page merge control</w:t></w:r></w:fldSimple></w:p><w:p><w:r><w:br w:type="page"/></w:r></w:p><w:p><w:bookmarkStart w:id="7" w:name="Gate"/><w:bookmarkStart w:id="8" w:name="AfterBookmarkMerge"/><w:r><w:t>Ready</w:t></w:r><w:bookmarkEnd w:id="8"/><w:bookmarkEnd w:id="7"/></w:p><w:p><w:fldSimple w:instr=" PAGEREF AfterBookmarkMerge \h "><w:r><w:t>cached after bookmark merge page</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn page_ref_bookmark_if_before_manual_break_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:fldSimple w:instr=" IF Gate = "Ready" "" "" "><w:r><w:t>stale page if</w:t></w:r></w:fldSimple></w:p><w:p><w:r><w:br w:type="page"/></w:r></w:p><w:p><w:bookmarkStart w:id="7" w:name="Gate"/><w:bookmarkStart w:id="8" w:name="AfterBookmarkIf"/><w:r><w:t>Ready</w:t></w:r><w:bookmarkEnd w:id="8"/><w:bookmarkEnd w:id="7"/></w:p><w:p><w:fldSimple w:instr=" PAGEREF AfterBookmarkIf \h "><w:r><w:t>cached after bookmark if page</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn page_ref_bookmark_formula_rendered_break_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:fldSimple w:instr=" = InvoiceSubtotal + 8 "><w:r><w:br w:type="page"/></w:r><w:r><w:t>stale page formula</w:t></w:r></w:fldSimple></w:p><w:p><w:r><w:lastRenderedPageBreak/></w:r></w:p><w:p><w:bookmarkStart w:id="7" w:name="InvoiceSubtotal"/><w:bookmarkStart w:id="8" w:name="AfterBookmarkFormula"/><w:r><w:t>42</w:t></w:r><w:bookmarkEnd w:id="8"/><w:bookmarkEnd w:id="7"/></w:p><w:p><w:fldSimple w:instr=" PAGEREF AfterBookmarkFormula \h "><w:r><w:t>cached after bookmark formula page</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn page_ref_empty_ref_before_manual_break_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:bookmarkStart w:id="1" w:name="EmptyTarget"/><w:bookmarkEnd w:id="1"/></w:p><w:p><w:fldSimple w:instr=" REF EmptyTarget "><w:r><w:t>stale empty ref before break</w:t></w:r></w:fldSimple></w:p><w:p><w:r><w:br w:type="page"/></w:r></w:p><w:p><w:bookmarkStart w:id="7" w:name="AfterEmptyRef"/><w:r><w:t>After empty ref</w:t></w:r><w:bookmarkEnd w:id="7"/></w:p><w:p><w:fldSimple w:instr=" PAGEREF AfterEmptyRef \h "><w:r><w:t>cached after empty ref page</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn page_ref_empty_direct_bookmark_before_manual_break_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:bookmarkStart w:id="1" w:name="EmptyTarget"/><w:bookmarkEnd w:id="1"/></w:p><w:p><w:fldSimple w:instr=" EmptyTarget "><w:r><w:t>stale empty direct ref before break</w:t></w:r></w:fldSimple></w:p><w:p><w:r><w:br w:type="page"/></w:r></w:p><w:p><w:bookmarkStart w:id="7" w:name="AfterDirectRef"/><w:r><w:t>After direct ref</w:t></w:r><w:bookmarkEnd w:id="7"/></w:p><w:p><w:fldSimple w:instr=" PAGEREF AfterDirectRef \h "><w:r><w:t>cached after direct ref page</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn page_ref_known_field_name_bookmark_before_manual_break_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:bookmarkStart w:id="1" w:name="TOC"/><w:bookmarkEnd w:id="1"/></w:p><w:p><w:fldSimple w:instr=" TOC "><w:r><w:t>stale toc before break</w:t></w:r></w:fldSimple></w:p><w:p><w:r><w:br w:type="page"/></w:r></w:p><w:p><w:bookmarkStart w:id="7" w:name="AfterKnownField"/><w:r><w:t>After known field</w:t></w:r><w:bookmarkEnd w:id="7"/></w:p><w:p><w:fldSimple w:instr=" PAGEREF AfterKnownField \h "><w:r><w:t>cached after known field page</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn page_ref_rendered_break_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:r><w:t>Page one text can be long enough to paginate.</w:t></w:r></w:p><w:p><w:r><w:lastRenderedPageBreak/><w:t>Page two lead.</w:t></w:r></w:p><w:p><w:bookmarkStart w:id="7" w:name="FigureTwo"/><w:r><w:t>Figure 2</w:t></w:r><w:bookmarkEnd w:id="7"/></w:p><w:p><w:fldSimple w:instr=" PAGEREF FigureTwo \h "><w:r><w:t>99</w:t></w:r></w:fldSimple></w:p><w:p><w:r><w:fldChar w:fldCharType="begin"/></w:r><w:r><w:instrText> PAGEREF "FigureTwo" \* CHARFORMAT </w:instrText></w:r><w:r><w:fldChar w:fldCharType="separate"/></w:r><w:r><w:t>old rendered page</w:t></w:r><w:r><w:fldChar w:fldCharType="end"/></w:r></w:p><w:p><w:fldSimple w:instr=" PAGEREF FigureTwo \p "><w:r><w:t>below</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn page_ref_rendered_break_page_one_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:bookmarkStart w:id="7" w:name="Cover"/><w:r><w:t>Cover title</w:t></w:r><w:bookmarkEnd w:id="7"/></w:p><w:p><w:r><w:lastRenderedPageBreak/><w:t>Page two lead.</w:t></w:r></w:p><w:p><w:fldSimple w:instr=" PAGEREF Cover \h "><w:r><w:t>99</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn page_ref_rendered_break_relative_below_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:r><w:t>Page one text.</w:t></w:r></w:p><w:p><w:r><w:lastRenderedPageBreak/><w:t>Page two lead.</w:t></w:r></w:p><w:p><w:fldSimple w:instr=" PAGEREF FigureLater \p "><w:r><w:t>above</w:t></w:r></w:fldSimple></w:p><w:p><w:bookmarkStart w:id="7" w:name="FigureLater"/><w:r><w:t>Figure later</w:t></w:r><w:bookmarkEnd w:id="7"/></w:p></w:body></w:document>"#,
),
])
}
fn page_ref_rendered_then_manual_break_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:r><w:t>Page one text.</w:t></w:r></w:p><w:p><w:fldSimple w:instr=" PAGEREF PageThree \p "><w:r><w:t>stale distant relative</w:t></w:r></w:fldSimple></w:p><w:p><w:r><w:lastRenderedPageBreak/><w:t>Page two lead.</w:t><w:br w:type="page"/></w:r></w:p><w:p><w:bookmarkStart w:id="7" w:name="PageThree"/><w:r><w:t>Page three target</w:t></w:r><w:bookmarkEnd w:id="7"/></w:p><w:p><w:fldSimple w:instr=" PAGEREF PageThree \h "><w:r><w:t>99</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" PAGEREF PageThree \p "><w:r><w:t>old relative</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" PAGE \* Arabic "><w:r><w:t>stale current page</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn page_ref_section_break_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:pPr><w:sectPr><w:type w:val="nextPage"/></w:sectPr></w:pPr></w:p><w:p><w:bookmarkStart w:id="7" w:name="NextSection"/><w:r><w:t>Next section target</w:t></w:r><w:bookmarkEnd w:id="7"/></w:p><w:p><w:fldSimple w:instr=" PAGE \* Arabic "><w:r><w:t>stale next current</w:t></w:r></w:fldSimple></w:p><w:p><w:r><w:lastRenderedPageBreak/><w:t>Page three lead.</w:t></w:r></w:p><w:p><w:pPr><w:sectPr><w:type w:val=" evenPage "/></w:sectPr></w:pPr></w:p><w:p><w:bookmarkStart w:id="8" w:name="EvenSection"/><w:r><w:t>Even section target</w:t></w:r><w:bookmarkEnd w:id="8"/></w:p><w:p><w:fldSimple w:instr=" PAGE \* Arabic "><w:r><w:t>stale even current</w:t></w:r></w:fldSimple></w:p><w:p><w:pPr><w:sectPr><w:type w:val="oddPage"/></w:sectPr></w:pPr></w:p><w:p><w:bookmarkStart w:id="9" w:name="OddSection"/><w:r><w:t>Odd section target</w:t></w:r><w:bookmarkEnd w:id="9"/></w:p><w:p><w:fldSimple w:instr=" PAGE \* Arabic "><w:r><w:t>stale odd current</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" PAGEREF NextSection \h "><w:r><w:t>stale next</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" PAGEREF EvenSection \* roman "><w:r><w:t>stale even</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" PAGEREF OddSection \p "><w:r><w:t>stale odd relative</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn page_ref_content_paragraph_section_break_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:pPr><w:sectPr><w:type w:val="nextPage"/></w:sectPr></w:pPr><w:bookmarkStart w:id="7" w:name="BeforeSectionBreak"/><w:r><w:t>Before break</w:t></w:r><w:r><w:fldChar w:fldCharType="begin"/></w:r><w:r><w:instrText> PAGE </w:instrText></w:r><w:r><w:fldChar w:fldCharType="separate"/></w:r><w:r><w:t>stale same-paragraph page</w:t></w:r><w:r><w:fldChar w:fldCharType="end"/></w:r><w:bookmarkEnd w:id="7"/></w:p><w:p><w:r><w:t>After break</w:t></w:r></w:p><w:p><w:fldSimple w:instr=" PAGEREF BeforeSectionBreak \h "><w:r><w:t>stale before break</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn page_ref_content_paragraph_section_format_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:pPr><w:sectPr><w:pgNumType w:fmt="bullet"/></w:sectPr></w:pPr><w:bookmarkStart w:id="7" w:name="BeforeFormatBreak"/><w:r><w:t>Before format break</w:t></w:r><w:bookmarkEnd w:id="7"/></w:p><w:p><w:bookmarkStart w:id="8" w:name="AfterFormatBreak"/><w:r><w:t>After format break</w:t></w:r><w:bookmarkEnd w:id="8"/></w:p><w:p><w:fldSimple w:instr=" PAGEREF BeforeFormatBreak \p "><w:r><w:t>stale before</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" PAGEREF AfterFormatBreak \p "><w:r><w:t>stale after</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
#[cfg(feature = "render")]
fn page_ref_complex_content_paragraph_section_format_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:pPr><w:sectPr><w:pgNumType w:fmt="bullet"/></w:sectPr></w:pPr><w:bookmarkStart w:id="7" w:name="BeforeFormatBreak"/><w:r><w:t>Before format break</w:t></w:r><w:bookmarkEnd w:id="7"/></w:p><w:p><w:bookmarkStart w:id="8" w:name="AfterFormatBreak"/><w:r><w:t>After format break</w:t></w:r><w:bookmarkEnd w:id="8"/></w:p><w:p><w:r><w:fldChar w:fldCharType="begin"/></w:r><w:r><w:instrText> PAGEREF AfterFormatBreak \p </w:instrText></w:r><w:r><w:fldChar w:fldCharType="separate"/></w:r><w:r><w:t>stale complex after</w:t></w:r><w:r><w:fldChar w:fldCharType="end"/></w:r></w:p></w:body></w:document>"#,
),
])
}
fn page_ref_default_section_break_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:pPr><w:sectPr/></w:pPr></w:p><w:p><w:bookmarkStart w:id="7" w:name="DefaultSection"/><w:r><w:t>Default section target</w:t></w:r><w:bookmarkEnd w:id="7"/></w:p><w:p><w:fldSimple w:instr=" PAGEREF DefaultSection \h "><w:r><w:t>stale default</w:t></w:r></w:fldSimple></w:p><w:sectPr/></w:body></w:document>"#,
),
])
}
fn page_ref_page_break_before_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:pPr><w:pageBreakBefore/></w:pPr><w:bookmarkStart w:id="7" w:name="BreakBefore"/><w:r><w:t>Break-before target</w:t></w:r><w:bookmarkEnd w:id="7"/></w:p><w:p><w:r><w:t>Visible intro before another break-before paragraph.</w:t></w:r></w:p><w:p><w:pPr><w:pageBreakBefore/></w:pPr><w:bookmarkStart w:id="8" w:name="BreakAfterIntro"/><w:r><w:t>Break-before target after intro</w:t></w:r><w:bookmarkEnd w:id="8"/></w:p><w:p><w:r><w:lastRenderedPageBreak/><w:t>Page after rendered marker.</w:t></w:r></w:p><w:p><w:pPr><w:pageBreakBefore/></w:pPr><w:bookmarkStart w:id="9" w:name="RenderedBreakBefore"/><w:r><w:t>Rendered break-before target</w:t></w:r><w:bookmarkEnd w:id="9"/></w:p><w:p><w:fldSimple w:instr=" PAGEREF BreakBefore \h "><w:r><w:t>stale break-before</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" PAGEREF BreakAfterIntro \h "><w:r><w:t>stale after-intro break-before</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" PAGEREF RenderedBreakBefore \* Ordinal "><w:r><w:t>stale rendered break-before</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" PAGEREF RenderedBreakBefore \p "><w:r><w:t>stale relative</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn page_section_property_revision_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:r><w:t>Intro page one.</w:t></w:r></w:p><w:p><w:pPr><w:pPrChange><w:pPr><w:pageBreakBefore/></w:pPr></w:pPrChange></w:pPr><w:fldSimple w:instr=" PAGE \* Arabic "><w:r><w:t>cached old page break page</w:t></w:r></w:fldSimple></w:p><w:p><w:pPr><w:pPrChange><w:pPr><w:sectPr><w:type w:val="nextPage"/></w:sectPr></w:pPr></w:pPrChange></w:pPr></w:p><w:p><w:fldSimple w:instr=" SECTION "><w:r><w:t>cached old section</w:t></w:r></w:fldSimple></w:p><w:p><w:pPr><w:pageBreakBefore/></w:pPr><w:bookmarkStart w:id="7" w:name="CurrentBreak"/><w:r><w:t>Current break target</w:t></w:r><w:bookmarkEnd w:id="7"/></w:p><w:p><w:r><w:lastRenderedPageBreak/><w:t>Rendered hint after current break.</w:t></w:r></w:p><w:p><w:fldSimple w:instr=" PAGEREF CurrentBreak \h "><w:r><w:t>stale current break</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn page_ref_disabled_page_break_before_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:r><w:t>Page one text.</w:t></w:r></w:p><w:p><w:r><w:lastRenderedPageBreak/><w:t>Page two lead.</w:t></w:r></w:p><w:p><w:pPr><w:pageBreakBefore w:val=" Off "/></w:pPr><w:bookmarkStart w:id="7" w:name="NoForcedBreak"/><w:r><w:t>No forced break target</w:t></w:r><w:bookmarkEnd w:id="7"/></w:p><w:p><w:fldSimple w:instr=" PAGEREF NoForcedBreak \h "><w:r><w:t>stale disabled break</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn page_ref_section_page_number_restart_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:r><w:br w:type="page"/></w:r></w:p><w:p><w:pPr><w:sectPr><w:type w:val="nextPage"/><w:pgNumType w:start=" 7 "/></w:sectPr></w:pPr></w:p><w:p><w:bookmarkStart w:id="7" w:name="Restarted"/><w:r><w:t>Restarted target</w:t></w:r><w:bookmarkEnd w:id="7"/></w:p><w:p><w:r><w:lastRenderedPageBreak/><w:t>Restarted next page lead.</w:t></w:r></w:p><w:p><w:bookmarkStart w:id="8" w:name="RestartedNext"/><w:r><w:t>Restarted next target</w:t></w:r><w:bookmarkEnd w:id="8"/></w:p><w:p><w:fldSimple w:instr=" PAGEREF Restarted \h "><w:r><w:t>stale restart</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" PAGEREF RestartedNext \* ROMAN "><w:r><w:t>stale restart roman</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" PAGEREF RestartedNext \h\p "><w:r><w:t>stale compact restart relative</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn page_ref_visible_intro_section_page_number_restart_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:r><w:t>Intro text can auto-paginate before the restart.</w:t></w:r></w:p><w:p><w:pPr><w:sectPr><w:type w:val="nextPage"/><w:pgNumType w:start="7" w:fmt=" "/></w:sectPr></w:pPr></w:p><w:p><w:bookmarkStart w:id="7" w:name="RestartedAfterIntro"/><w:r><w:t>Restarted target</w:t></w:r><w:bookmarkEnd w:id="7"/></w:p><w:p><w:fldSimple w:instr=" PAGEREF RestartedAfterIntro \h "><w:r><w:t>stale restarted page</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" PAGEREF RestartedAfterIntro \p "><w:r><w:t>stale restarted relative</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn page_ref_section_page_number_format_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:pPr><w:sectPr><w:type w:val="nextPage"/><w:pgNumType w:start="3" w:fmt=" lowerRoman "/></w:sectPr></w:pPr></w:p><w:p><w:bookmarkStart w:id="7" w:name="RomanSection"/><w:r><w:t>Roman section target</w:t></w:r><w:bookmarkEnd w:id="7"/></w:p><w:p><w:fldSimple w:instr=" PAGE \* Arabic "><w:r><w:t>stale roman current</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" PAGEREF RomanSection \h "><w:r><w:t>stale roman</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" PAGEREF RomanSection \* Arabic "><w:r><w:t>stale arabic override</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" PAGEREF RomanSection \p "><w:r><w:t>stale roman relative</w:t></w:r></w:fldSimple></w:p><w:p><w:pPr><w:sectPr><w:type w:val="nextPage"/><w:pgNumType w:start="4" w:fmt="decimalZero"/></w:sectPr></w:pPr></w:p><w:p><w:r><w:lastRenderedPageBreak/><w:t>Decimal zero page lead.</w:t></w:r></w:p><w:p><w:bookmarkStart w:id="8" w:name="DecimalZeroSection"/><w:r><w:t>Decimal zero target</w:t></w:r><w:bookmarkEnd w:id="8"/></w:p><w:p><w:fldSimple w:instr=" PAGE "><w:r><w:t>stale decimal current</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" PAGEREF DecimalZeroSection \h "><w:r><w:t>stale decimal zero</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" PAGEREF DecimalZeroSection \* Arabic "><w:r><w:t>stale decimal arabic</w:t></w:r></w:fldSimple></w:p><w:p><w:pPr><w:sectPr><w:type w:val="nextPage"/><w:pgNumType w:start="5" w:fmt="numberInDash"/></w:sectPr></w:pPr></w:p><w:p><w:bookmarkStart w:id="9" w:name="DashedSection"/><w:r><w:t>Dashed target</w:t></w:r><w:bookmarkEnd w:id="9"/></w:p><w:p><w:fldSimple w:instr=" PAGE "><w:r><w:t>stale dashed current</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" PAGEREF DashedSection \h "><w:r><w:t>stale dashed</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" PAGEREF DashedSection \* Arabic "><w:r><w:t>stale dashed arabic</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn page_ref_textual_section_page_number_format_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:pPr><w:sectPr><w:type w:val="nextPage"/><w:pgNumType w:start="2" w:fmt="lowerLetter"/></w:sectPr></w:pPr></w:p><w:p><w:bookmarkStart w:id="7" w:name="LowerLetterSection"/><w:r><w:t>Lower letter target</w:t></w:r><w:bookmarkEnd w:id="7"/></w:p><w:p><w:fldSimple w:instr=" PAGEREF LowerLetterSection \h "><w:r><w:t>stale lower letter</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" PAGEREF LowerLetterSection \* Arabic "><w:r><w:t>stale lower letter arabic</w:t></w:r></w:fldSimple></w:p><w:p><w:pPr><w:sectPr><w:type w:val="nextPage"/><w:pgNumType w:start="3" w:fmt="upperLetter"/></w:sectPr></w:pPr></w:p><w:p><w:r><w:lastRenderedPageBreak/><w:t>Upper letter page lead.</w:t></w:r></w:p><w:p><w:bookmarkStart w:id="8" w:name="UpperLetterSection"/><w:r><w:t>Upper letter target</w:t></w:r><w:bookmarkEnd w:id="8"/></w:p><w:p><w:fldSimple w:instr=" PAGEREF UpperLetterSection \h "><w:r><w:t>stale upper letter</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" PAGEREF UpperLetterSection \* Arabic "><w:r><w:t>stale upper letter arabic</w:t></w:r></w:fldSimple></w:p><w:p><w:pPr><w:sectPr><w:type w:val="nextPage"/><w:pgNumType w:start="6" w:fmt="upperRoman"/></w:sectPr></w:pPr></w:p><w:p><w:bookmarkStart w:id="9" w:name="UpperRomanSection"/><w:r><w:t>Upper roman target</w:t></w:r><w:bookmarkEnd w:id="9"/></w:p><w:p><w:fldSimple w:instr=" PAGEREF UpperRomanSection \h "><w:r><w:t>stale upper roman</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" PAGEREF UpperRomanSection \* Arabic "><w:r><w:t>stale upper roman arabic</w:t></w:r></w:fldSimple></w:p><w:p><w:pPr><w:sectPr><w:type w:val="nextPage"/><w:pgNumType w:start="4" w:fmt="cardinalText"/></w:sectPr></w:pPr></w:p><w:p><w:r><w:lastRenderedPageBreak/><w:t>Cardinal page lead.</w:t></w:r></w:p><w:p><w:bookmarkStart w:id="10" w:name="CardinalTextSection"/><w:r><w:t>Cardinal text target</w:t></w:r><w:bookmarkEnd w:id="10"/></w:p><w:p><w:fldSimple w:instr=" PAGEREF CardinalTextSection \h "><w:r><w:t>stale cardinal text</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" PAGEREF CardinalTextSection \* Arabic "><w:r><w:t>stale cardinal text arabic</w:t></w:r></w:fldSimple></w:p><w:p><w:pPr><w:sectPr><w:type w:val="nextPage"/><w:pgNumType w:start="5" w:fmt="ordinalText"/></w:sectPr></w:pPr></w:p><w:p><w:bookmarkStart w:id="11" w:name="OrdinalTextSection"/><w:r><w:t>Ordinal text target</w:t></w:r><w:bookmarkEnd w:id="11"/></w:p><w:p><w:fldSimple w:instr=" PAGEREF OrdinalTextSection \h "><w:r><w:t>stale ordinal text</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" PAGEREF OrdinalTextSection \* Arabic "><w:r><w:t>stale ordinal text arabic</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn page_ref_relative_unsupported_section_page_number_format_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:pPr><w:sectPr><w:type w:val="nextPage"/><w:pgNumType w:start="2" w:fmt="chicago"/></w:sectPr></w:pPr></w:p><w:p><w:bookmarkStart w:id="7" w:name=" UnsupportedFmt "/><w:r><w:t>Unsupported format target</w:t></w:r><w:bookmarkEnd w:id="7"/></w:p><w:p><w:r><w:lastRenderedPageBreak/><w:t>Later page lead.</w:t></w:r></w:p><w:p><w:fldSimple w:instr=" PAGEREF UnsupportedFmt \p "><w:r><w:t>stale relative</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn page_ref_relative_unsupported_section_format_override_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:pPr><w:sectPr><w:type w:val="nextPage"/><w:pgNumType w:start="2" w:fmt="chicago"/></w:sectPr></w:pPr></w:p><w:p><w:bookmarkStart w:id="7" w:name=" UnsupportedFmt "/><w:r><w:t>Unsupported format target</w:t></w:r><w:bookmarkEnd w:id="7"/></w:p><w:p><w:r><w:lastRenderedPageBreak/><w:t>Later page lead.</w:t></w:r></w:p><w:p><w:fldSimple w:instr=" PAGEREF UnsupportedFmt \p \* Arabic "><w:r><w:t>stale relative override</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn page_ref_relative_unsupported_even_odd_section_formats_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:pPr><w:sectPr><w:type w:val="evenPage"/><w:pgNumType w:fmt="chicago"/></w:sectPr></w:pPr></w:p><w:p><w:bookmarkStart w:id="7" w:name="EvenUnsupportedFmt"/><w:r><w:t>Even unsupported format target</w:t></w:r><w:bookmarkEnd w:id="7"/></w:p><w:p><w:r><w:lastRenderedPageBreak/><w:t>After even target.</w:t></w:r></w:p><w:p><w:fldSimple w:instr=" PAGEREF EvenUnsupportedFmt \p "><w:r><w:t>stale even relative</w:t></w:r></w:fldSimple></w:p><w:p><w:r><w:lastRenderedPageBreak/></w:r></w:p><w:p><w:pPr><w:sectPr><w:type w:val="oddPage"/><w:pgNumType w:fmt="chicago"/></w:sectPr></w:pPr></w:p><w:p><w:bookmarkStart w:id="8" w:name="OddUnsupportedFmt"/><w:r><w:t>Odd unsupported format target</w:t></w:r><w:bookmarkEnd w:id="8"/></w:p><w:p><w:r><w:lastRenderedPageBreak/><w:t>After odd target.</w:t></w:r></w:p><w:p><w:fldSimple w:instr=" PAGEREF OddUnsupportedFmt \p "><w:r><w:t>stale odd relative</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn page_ref_unsupported_section_format_override_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:pPr><w:sectPr><w:type w:val="nextPage"/><w:pgNumType w:start="2" w:fmt="chicago"/></w:sectPr></w:pPr></w:p><w:p><w:bookmarkStart w:id="7" w:name=" UnsupportedFmt "/><w:r><w:t>Unsupported format target</w:t></w:r><w:bookmarkEnd w:id="7"/></w:p><w:p><w:fldSimple w:instr=" PAGEREF UnsupportedFmt \h \* Arabic "><w:r><w:t>stale override</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn page_ref_decimal_full_width_section_page_number_format_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:pPr><w:sectPr><w:type w:val="nextPage"/><w:pgNumType w:start="12" w:fmt="decimalFullWidth"/></w:sectPr></w:pPr></w:p><w:p><w:bookmarkStart w:id="10" w:name="FullWidthSection"/><w:r><w:t>Full-width target</w:t></w:r><w:bookmarkEnd w:id="10"/></w:p><w:p><w:fldSimple w:instr=" PAGEREF FullWidthSection \h "><w:r><w:t>stale fullwidth</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" PAGEREF FullWidthSection \* Arabic "><w:r><w:t>stale fullwidth arabic</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn page_ref_decimal_enclosed_circle_section_page_number_format_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:pPr><w:sectPr><w:type w:val="nextPage"/><w:pgNumType w:start="12" w:fmt="decimalEnclosedCircle"/></w:sectPr></w:pPr></w:p><w:p><w:bookmarkStart w:id="11" w:name="CircleSection"/><w:r><w:t>Circle target</w:t></w:r><w:bookmarkEnd w:id="11"/></w:p><w:p><w:fldSimple w:instr=" PAGEREF CircleSection \h "><w:r><w:t>stale circle</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" PAGEREF CircleSection \* Arabic "><w:r><w:t>stale circle arabic</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn page_ref_decimal_enclosed_punctuation_section_page_number_format_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:pPr><w:sectPr><w:type w:val="nextPage"/><w:pgNumType w:start="12" w:fmt="decimalEnclosedFullstop"/></w:sectPr></w:pPr></w:p><w:p><w:bookmarkStart w:id="12" w:name="FullstopSection"/><w:r><w:t>Fullstop target</w:t></w:r><w:bookmarkEnd w:id="12"/></w:p><w:p><w:fldSimple w:instr=" PAGEREF FullstopSection \h "><w:r><w:t>stale fullstop</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" PAGEREF FullstopSection \* Arabic "><w:r><w:t>stale fullstop arabic</w:t></w:r></w:fldSimple></w:p><w:p><w:pPr><w:sectPr><w:type w:val="nextPage"/><w:pgNumType w:start="11" w:fmt="decimalEnclosedParen"/></w:sectPr></w:pPr></w:p><w:p><w:r><w:lastRenderedPageBreak/><w:t>Paren page lead.</w:t></w:r></w:p><w:p><w:bookmarkStart w:id="13" w:name="ParenSection"/><w:r><w:t>Paren target</w:t></w:r><w:bookmarkEnd w:id="13"/></w:p><w:p><w:fldSimple w:instr=" PAGEREF ParenSection \h "><w:r><w:t>stale paren</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" PAGEREF ParenSection \* Arabic "><w:r><w:t>stale paren arabic</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn page_ref_decimal_width_variant_section_page_number_format_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:pPr><w:sectPr><w:type w:val="nextPage"/><w:pgNumType w:start="12" w:fmt="decimalHalfWidth"/></w:sectPr></w:pPr></w:p><w:p><w:bookmarkStart w:id="14" w:name="HalfWidthSection"/><w:r><w:t>Half-width target</w:t></w:r><w:bookmarkEnd w:id="14"/></w:p><w:p><w:fldSimple w:instr=" PAGEREF HalfWidthSection \h "><w:r><w:t>stale halfwidth</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" PAGEREF HalfWidthSection \* ArabicDash "><w:r><w:t>stale halfwidth dash</w:t></w:r></w:fldSimple></w:p><w:p><w:pPr><w:sectPr><w:type w:val="nextPage"/><w:pgNumType w:start="12" w:fmt="decimalFullWidth2"/></w:sectPr></w:pPr></w:p><w:p><w:r><w:lastRenderedPageBreak/><w:t>Full-width alternate page lead.</w:t></w:r></w:p><w:p><w:bookmarkStart w:id="15" w:name="FullWidthAltSection"/><w:r><w:t>Full-width alternate target</w:t></w:r><w:bookmarkEnd w:id="15"/></w:p><w:p><w:fldSimple w:instr=" PAGEREF FullWidthAltSection \h "><w:r><w:t>stale fullwidth alt</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" PAGEREF FullWidthAltSection \* Arabic "><w:r><w:t>stale fullwidth alt arabic</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn page_ref_korean_section_page_number_format_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:pPr><w:sectPr><w:type w:val="nextPage"/><w:pgNumType w:start="1" w:fmt="ganada"/></w:sectPr></w:pPr></w:p><w:p><w:bookmarkStart w:id="16" w:name="GanadaSection"/><w:r><w:t>Ganada target</w:t></w:r><w:bookmarkEnd w:id="16"/></w:p><w:p><w:fldSimple w:instr=" PAGEREF GanadaSection \h "><w:r><w:t>stale ganada</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" PAGEREF GanadaSection \* Arabic "><w:r><w:t>stale ganada arabic</w:t></w:r></w:fldSimple></w:p><w:p><w:pPr><w:sectPr><w:type w:val="nextPage"/><w:pgNumType w:start="1" w:fmt="chosung"/></w:sectPr></w:pPr></w:p><w:p><w:r><w:lastRenderedPageBreak/><w:t>Chosung page lead.</w:t></w:r></w:p><w:p><w:bookmarkStart w:id="17" w:name="ChosungSection"/><w:r><w:t>Chosung target</w:t></w:r><w:bookmarkEnd w:id="17"/></w:p><w:p><w:fldSimple w:instr=" PAGEREF ChosungSection \h "><w:r><w:t>stale chosung</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" PAGEREF ChosungSection \* Arabic "><w:r><w:t>stale chosung arabic</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn page_ref_korean_numeric_section_page_number_format_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:pPr><w:sectPr><w:type w:val="nextPage"/><w:pgNumType w:start="1" w:fmt="koreanDigital"/></w:sectPr></w:pPr></w:p><w:p><w:bookmarkStart w:id="18" w:name="KoreanDigitalSection"/><w:r><w:t>Korean digital target</w:t></w:r><w:bookmarkEnd w:id="18"/></w:p><w:p><w:fldSimple w:instr=" PAGEREF KoreanDigitalSection \h "><w:r><w:t>stale korean digital</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" PAGEREF KoreanDigitalSection \* Arabic "><w:r><w:t>stale korean digital arabic</w:t></w:r></w:fldSimple></w:p><w:p><w:pPr><w:sectPr><w:type w:val="nextPage"/><w:pgNumType w:start="1" w:fmt="koreanCounting"/></w:sectPr></w:pPr></w:p><w:p><w:r><w:lastRenderedPageBreak/><w:t>Korean counting page lead.</w:t></w:r></w:p><w:p><w:bookmarkStart w:id="19" w:name="KoreanCountingSection"/><w:r><w:t>Korean counting target</w:t></w:r><w:bookmarkEnd w:id="19"/></w:p><w:p><w:fldSimple w:instr=" PAGEREF KoreanCountingSection \h "><w:r><w:t>stale korean counting</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" PAGEREF KoreanCountingSection \* Arabic "><w:r><w:t>stale korean counting arabic</w:t></w:r></w:fldSimple></w:p><w:p><w:pPr><w:sectPr><w:type w:val="nextPage"/><w:pgNumType w:start="9" w:fmt="koreanLegal"/></w:sectPr></w:pPr></w:p><w:p><w:r><w:lastRenderedPageBreak/><w:t>Korean legal page lead.</w:t></w:r></w:p><w:p><w:bookmarkStart w:id="20" w:name="KoreanLegalSection"/><w:r><w:t>Korean legal target</w:t></w:r><w:bookmarkEnd w:id="20"/></w:p><w:p><w:fldSimple w:instr=" PAGEREF KoreanLegalSection \h "><w:r><w:t>stale korean legal</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" PAGEREF KoreanLegalSection \* Arabic "><w:r><w:t>stale korean legal arabic</w:t></w:r></w:fldSimple></w:p><w:p><w:pPr><w:sectPr><w:type w:val="nextPage"/><w:pgNumType w:start="1" w:fmt="koreanDigital2"/></w:sectPr></w:pPr></w:p><w:p><w:r><w:lastRenderedPageBreak/><w:t>Korean digital2 page lead.</w:t></w:r></w:p><w:p><w:bookmarkStart w:id="21" w:name="KoreanDigital2Section"/><w:r><w:t>Korean digital2 target</w:t></w:r><w:bookmarkEnd w:id="21"/></w:p><w:p><w:fldSimple w:instr=" PAGEREF KoreanDigital2Section \h "><w:r><w:t>stale korean digital2</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" PAGEREF KoreanDigital2Section \* Arabic "><w:r><w:t>stale korean digital2 arabic</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn page_ref_final_section_page_number_format_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:r><w:br w:type="page"/></w:r></w:p><w:p><w:bookmarkStart w:id="7" w:name="FinalSection"/><w:r><w:t>Final-section target</w:t></w:r><w:bookmarkEnd w:id="7"/></w:p><w:p><w:fldSimple w:instr=" PAGE \* Arabic "><w:r><w:t>stale final current</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" PAGEREF FinalSection \h "><w:r><w:t>stale final roman</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" PAGEREF FinalSection \* Arabic "><w:r><w:t>stale final arabic</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" PAGEREF FinalSection \p "><w:r><w:t>stale final relative</w:t></w:r></w:fldSimple></w:p><w:sectPr><w:pgNumType w:start="5" w:fmt="lowerRoman"/></w:sectPr></w:body></w:document>"#,
),
])
}
fn page_ref_final_section_alternate_content_page_number_format_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"><w:body><w:p><w:r><w:br w:type="page"/></w:r></w:p><w:p><w:bookmarkStart w:id="7" w:name="FinalSection"/><w:r><w:t>Final-section target</w:t></w:r><w:bookmarkEnd w:id="7"/></w:p><w:p><w:fldSimple w:instr=" PAGE \* Arabic "><w:r><w:t>stale alternate final current</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" PAGEREF FinalSection \h "><w:r><w:t>stale alternate final roman</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" PAGEREF FinalSection \* Arabic "><w:r><w:t>stale alternate final arabic</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" PAGEREF FinalSection \p "><w:r><w:t>stale alternate final relative</w:t></w:r></w:fldSimple></w:p><w:sectPr><mc:AlternateContent><mc:Choice Requires="w14"><w:pgNumType w:start="5" w:fmt="lowerRoman"/></mc:Choice><mc:Fallback><w:pgNumType w:start="12" w:fmt="upperRoman"/></mc:Fallback></mc:AlternateContent></w:sectPr></w:body></w:document>"#,
),
])
}
fn final_section_alternate_content_page_setup_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"><w:body><w:p><w:r><w:t>Body</w:t></w:r></w:p><w:sectPr><mc:AlternateContent><mc:Choice Requires="w14"><w:pgSz w:w="15840" w:h="12240" w:orient="landscape"/><w:pgMar w:left="720" w:right="1080" w:top="1440" w:bottom="1800"/></mc:Choice><mc:Fallback><w:pgSz w:w="12240" w:h="15840"/><w:pgMar w:left="1440" w:right="1440" w:top="1440" w:bottom="1440"/></mc:Fallback></mc:AlternateContent></w:sectPr></w:body></w:document>"#,
),
])
}
fn final_section_alternate_content_section_setup_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"><w:body><w:p><w:r><w:t>Body</w:t></w:r></w:p><w:sectPr><mc:AlternateContent><mc:Choice Requires="w14"><w:cols w:num="2"/><w:textDirection w:val="tbRl"/><w:docGrid w:type="lines" w:linePitch="360" w:charSpace="120"/><w:titlePg/></mc:Choice><mc:Fallback><w:cols w:num="5"/><w:textDirection w:val="lrTb"/><w:docGrid w:type="snapToChars" w:linePitch="720" w:charSpace="240"/></mc:Fallback></mc:AlternateContent></w:sectPr></w:body></w:document>"#,
),
])
}
fn page_ref_final_section_old_paragraph_revision_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:pPr><w:pPrChange><w:pPr><w:sectPr><w:pgNumType w:start="99"/></w:sectPr></w:pPr></w:pPrChange></w:pPr></w:p><w:p><w:r><w:br w:type="page"/></w:r></w:p><w:p><w:bookmarkStart w:id="7" w:name="FinalSection"/><w:r><w:t>Final-section target</w:t></w:r><w:bookmarkEnd w:id="7"/></w:p><w:p><w:fldSimple w:instr=" PAGE \* Arabic "><w:r><w:t>stale old revision final current</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" PAGEREF FinalSection \h "><w:r><w:t>stale old revision final roman</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" PAGEREF FinalSection \* Arabic "><w:r><w:t>stale old revision final arabic</w:t></w:r></w:fldSimple></w:p><w:sectPr><w:pgNumType w:start="5" w:fmt="lowerRoman"/></w:sectPr></w:body></w:document>"#,
),
])
}
fn page_ref_final_section_ignores_deleted_paragraph_section_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"><w:body><mc:AlternateContent><mc:Choice Requires="wps"><w:p/></mc:Choice><mc:Fallback><w:p><w:pPr><w:sectPr><w:pgNumType w:start="88"/></w:sectPr></w:pPr></w:p></mc:Fallback></mc:AlternateContent><w:del><w:p><w:pPr><w:sectPr><w:pgNumType w:start="99"/></w:sectPr></w:pPr></w:p></w:del><w:p><w:r><w:br w:type="page"/></w:r></w:p><w:p><w:bookmarkStart w:id="7" w:name="FinalSection"/><w:r><w:t>Final-section target</w:t></w:r><w:bookmarkEnd w:id="7"/></w:p><w:p><w:fldSimple w:instr=" PAGEREF FinalSection \h "><w:r><w:t>stale final roman</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" PAGEREF FinalSection \* Arabic "><w:r><w:t>stale final arabic</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" PAGEREF FinalSection \p "><w:r><w:t>stale final relative</w:t></w:r></w:fldSimple></w:p><w:sectPr><w:pgNumType w:start="5" w:fmt="upperRoman"/></w:sectPr></w:body></w:document>"#,
),
])
}
fn page_ref_visible_manual_break_before_rendered_hint_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:r><w:t>Cover text can auto-paginate before the hard break.</w:t><w:br w:type="page"/></w:r></w:p><w:p><w:bookmarkStart w:id="7" w:name="AmbiguousTarget"/><w:r><w:t>Ambiguous target</w:t></w:r><w:bookmarkEnd w:id="7"/></w:p><w:p><w:r><w:lastRenderedPageBreak/><w:t>Later rendered hint.</w:t></w:r></w:p><w:p><w:fldSimple w:instr=" PAGEREF AmbiguousTarget \h "><w:r><w:t>99</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn page_ref_deleted_rendered_break_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:del><w:r><w:lastRenderedPageBreak/></w:r></w:del></w:p><w:p><w:bookmarkStart w:id="7" w:name="Figure1"/><w:r><w:t>Figure 1</w:t></w:r><w:bookmarkEnd w:id="7"/></w:p><w:p><w:fldSimple w:instr=" PAGEREF Figure1 \h "><w:r><w:t>99</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn page_ref_leading_break_precedes_rendered_hint_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:r><w:br w:type="page"/></w:r></w:p><w:p><w:bookmarkStart w:id="7" w:name="Figure1"/><w:r><w:t>Figure 1</w:t></w:r><w:bookmarkEnd w:id="7"/></w:p><w:p><w:r><w:lastRenderedPageBreak/><w:t>Later rendered hint.</w:t></w:r></w:p><w:p><w:fldSimple w:instr=" PAGEREF Figure1 \h "><w:r><w:t>99</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn page_ref_rendered_break_no_cached_result_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:r><w:t>Page one text.</w:t></w:r></w:p><w:p><w:r><w:lastRenderedPageBreak/><w:t>Page two lead.</w:t></w:r></w:p><w:p><w:bookmarkStart w:id="7" w:name="FigureTwo"/><w:r><w:t>Figure 2</w:t></w:r><w:bookmarkEnd w:id="7"/></w:p><w:p><w:fldSimple w:instr=" PAGEREF FigureTwo \h "></w:fldSimple></w:p><w:p><w:r><w:fldChar w:fldCharType="begin"/></w:r><w:r><w:instrText> PAGEREF "FigureTwo" \* MERGEFORMAT </w:instrText></w:r><w:r><w:fldChar w:fldCharType="separate"/></w:r><w:r><w:fldChar w:fldCharType="end"/></w:r></w:p></w:body></w:document>"#,
),
])
}
fn page_ref_rendered_break_wrapped_complex_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:r><w:t>Page one text.</w:t></w:r></w:p><w:p><w:r><w:lastRenderedPageBreak/><w:t>Page two lead.</w:t></w:r></w:p><w:p><w:bookmarkStart w:id="7" w:name="FigureTwo"/><w:r><w:t>Figure 2</w:t></w:r><w:bookmarkEnd w:id="7"/></w:p><w:p><w:ins><w:r><w:fldChar w:fldCharType="begin"/></w:r><w:r><w:instrText> PAGEREF "FigureTwo" \* MERGEFORMAT </w:instrText></w:r><w:r><w:fldChar w:fldCharType="separate"/></w:r><w:r><w:t>old wrapped page</w:t></w:r><w:r><w:fldChar w:fldCharType="end"/></w:r></w:ins></w:p></w:body></w:document>"#,
),
])
}
fn page_ref_alternate_content_rendered_break_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"><w:body><w:p><w:r><w:t>Page one text.</w:t></w:r></w:p><w:p><w:r><mc:AlternateContent><mc:Choice Requires="wps"><w:lastRenderedPageBreak/></mc:Choice><mc:Fallback><w:lastRenderedPageBreak/></mc:Fallback></mc:AlternateContent><w:t>Page two lead.</w:t></w:r></w:p><w:p><w:bookmarkStart w:id="7" w:name="AltPage"/><w:r><w:t>Alternate target</w:t></w:r><w:bookmarkEnd w:id="7"/></w:p><w:p><w:fldSimple w:instr=" PAGEREF AltPage \h "><w:r><w:t>stale alternate page</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn toc_heading_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/styles.xml",
r#"<w:styles xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:style w:type="paragraph" w:styleId="Heading1"><w:name w:val="heading 1"/></w:style></w:styles>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:pPr><w:pStyle w:val="Heading1"/></w:pPr><w:r><w:t>Executive Summary</w:t></w:r></w:p><w:p><w:pPr><w:outlineLvl w:val=" 1 "/></w:pPr><w:r><w:t>Risks</w:t></w:r></w:p><w:p><w:pPr><w:outlineLvl w:val="3"/></w:pPr><w:r><w:t>Excluded Detail</w:t></w:r></w:p><w:p><w:fldSimple w:instr=" TOC \o "1-2" "><w:r><w:t>stale toc</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn toc_heading_simple_field_source_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/styles.xml",
r#"<w:styles xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:style w:type="paragraph" w:styleId="Heading1"><w:name w:val="heading 1"/></w:style></w:styles>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:pPr><w:pStyle w:val="Heading1"/></w:pPr><w:r><w:t>Executive </w:t></w:r><w:fldSimple w:instr=" QUOTE "Risk" "><w:r><w:t>stale heading quote</w:t></w:r></w:fldSimple><w:r><w:t> Review</w:t></w:r></w:p><w:p><w:fldSimple w:instr=" TOC \o "1-1" "><w:r><w:t>stale simple-field heading toc</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn toc_heading_legacy_form_source_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/styles.xml",
r#"<w:styles xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:style w:type="paragraph" w:styleId="Heading1"><w:name w:val="heading 1"/></w:style></w:styles>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:fldSimple w:instr=" FORMDROPDOWN "><w:ffData><w:ddList><w:result w:val="1"/><w:listEntry w:val="1"/><w:listEntry w:val="99"/></w:ddList></w:ffData><w:r><w:t>stale prior form</w:t></w:r></w:fldSimple></w:p><w:p><w:pPr><w:pStyle w:val="Heading1"/></w:pPr><w:r><w:t>Choice </w:t></w:r><w:fldSimple w:instr=" FORMDROPDOWN "><w:ffData><w:ddList><w:result w:val="1"/><w:listEntry w:val="3"/><w:listEntry w:val="7"/></w:ddList></w:ffData><w:r><w:t>stale source form</w:t></w:r></w:fldSimple><w:r><w:t> ready</w:t></w:r></w:p><w:p><w:fldSimple w:instr=" TOC \o "1-1" "><w:r><w:t>stale legacy form toc source</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" TOC \o "1-1" \* Upper "><w:r><w:t>stale upper legacy form toc source</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn toc_heading_numbering_field_source_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/styles.xml",
r#"<w:styles xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:style w:type="paragraph" w:styleId="Heading1"><w:name w:val="heading 1"/></w:style></w:styles>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:pPr><w:pStyle w:val="Heading1"/></w:pPr><w:r><w:t>Clause </w:t></w:r><w:fldSimple w:instr=" AUTONUM "><w:r><w:t>99</w:t></w:r></w:fldSimple><w:r><w:t> Overview</w:t></w:r></w:p><w:p><w:fldSimple w:instr=" TOC \o "1-1" "><w:r><w:t>stale numbering-source toc</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn toc_heading_listnum_field_source_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/styles.xml",
r#"<w:styles xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:style w:type="paragraph" w:styleId="Heading1"><w:name w:val="heading 1"/></w:style></w:styles>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:pPr><w:pStyle w:val="Heading1"/></w:pPr><w:r><w:t>Clause </w:t></w:r><w:fldSimple w:instr=" LISTNUM NumberDefault "><w:r><w:t>99</w:t></w:r></w:fldSimple><w:r><w:t> Overview</w:t></w:r></w:p><w:p><w:fldSimple w:instr=" TOC \o "1-1" "><w:r><w:t>stale listnum-source toc</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn toc_heading_formula_field_source_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/styles.xml",
r#"<w:styles xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:style w:type="paragraph" w:styleId="Heading1"><w:name w:val="heading 1"/></w:style></w:styles>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:pPr><w:pStyle w:val="Heading1"/></w:pPr><w:r><w:t>Total </w:t></w:r><w:fldSimple w:instr=" = 6 * 7 "><w:r><w:t>99</w:t></w:r></w:fldSimple><w:r><w:t> Due</w:t></w:r></w:p><w:p><w:fldSimple w:instr=" TOC \o "1-1" "><w:r><w:t>stale formula-source toc</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn toc_heading_complex_field_source_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/styles.xml",
r#"<w:styles xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:style w:type="paragraph" w:styleId="Heading1"><w:name w:val="heading 1"/></w:style></w:styles>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:pPr><w:pStyle w:val="Heading1"/></w:pPr><w:r><w:t>Executive </w:t></w:r><w:r><w:fldChar w:fldCharType="begin"/></w:r><w:r><w:instrText> QUOTE "Risk" </w:instrText></w:r><w:r><w:fldChar w:fldCharType="separate"/></w:r><w:r><w:t>stale heading quote</w:t></w:r><w:r><w:fldChar w:fldCharType="end"/></w:r><w:r><w:t> Review</w:t></w:r></w:p><w:p><w:fldSimple w:instr=" TOC \o "1-1" "><w:r><w:t>stale complex-field heading toc</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn toc_heading_set_field_source_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/styles.xml",
r#"<w:styles xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:style w:type="paragraph" w:styleId="Heading1"><w:name w:val="heading 1"/></w:style></w:styles>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:pPr><w:pStyle w:val="Heading1"/></w:pPr><w:r><w:t>Executive </w:t></w:r><w:r><w:fldChar w:fldCharType="begin"/></w:r><w:r><w:instrText> SET Marker "Ready" </w:instrText></w:r><w:r><w:fldChar w:fldCharType="separate"/></w:r><w:r><w:t>stale heading set</w:t></w:r><w:r><w:fldChar w:fldCharType="end"/></w:r><w:r><w:t> Review</w:t></w:r></w:p><w:p><w:fldSimple w:instr=" TOC \o "1-1" "><w:r><w:t>stale set-source toc</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn toc_heading_ref_field_source_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/styles.xml",
r#"<w:styles xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:style w:type="paragraph" w:styleId="Heading1"><w:name w:val="heading 1"/></w:style></w:styles>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:bookmarkStart w:id="1" w:name="ChapTitle"/><w:r><w:t>Live Chapter</w:t></w:r><w:bookmarkEnd w:id="1"/></w:p><w:p><w:pPr><w:pStyle w:val="Heading1"/></w:pPr><w:r><w:t>Section </w:t></w:r><w:r><w:fldChar w:fldCharType="begin"/></w:r><w:r><w:instrText> REF ChapTitle </w:instrText></w:r><w:r><w:fldChar w:fldCharType="separate"/></w:r><w:r><w:t>stale ref</w:t></w:r><w:r><w:fldChar w:fldCharType="end"/></w:r></w:p><w:p><w:fldSimple w:instr=" TOC \o "1-1" "><w:r><w:t>stale toc</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn toc_heading_note_ref_field_source_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/><Override PartName="/word/styles.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml"/><Override PartName="/word/footnotes.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.footnotes+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/_rels/document.xml.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rIdFoot" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/footnotes" Target="footnotes.xml"/></Relationships>"#,
),
(
"word/styles.xml",
r#"<w:styles xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:style w:type="paragraph" w:styleId="Heading1"><w:name w:val="heading 1"/></w:style></w:styles>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:bookmarkStart w:id="1" w:name="FootOne"/><w:r><w:footnoteReference w:id="1"/></w:r><w:bookmarkEnd w:id="1"/></w:p><w:p><w:pPr><w:pStyle w:val="Heading1"/></w:pPr><w:r><w:t>Section </w:t></w:r><w:fldSimple w:instr=" NOTEREF FootOne "><w:r><w:t>stale heading note</w:t></w:r></w:fldSimple><w:r><w:t> / </w:t></w:r><w:fldSimple w:instr=" NOTEREF FootOne \p "><w:r><w:t>stale heading relative note</w:t></w:r></w:fldSimple><w:r><w:t> Review</w:t></w:r></w:p><w:p><w:fldSimple w:instr=" TOC \o "1-1" "><w:r><w:t>stale note-ref toc</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
(
"word/footnotes.xml",
r#"<w:footnotes xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:footnote w:type="separator" w:id="-1"><w:p><w:r><w:separator/></w:r></w:p></w:footnote><w:footnote w:id="1"><w:p><w:r><w:t>First footnote.</w:t></w:r></w:p></w:footnote></w:footnotes>"#,
),
])
}
fn toc_heading_ref_note_mark_field_source_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/><Override PartName="/word/styles.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml"/><Override PartName="/word/footnotes.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.footnotes+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/_rels/document.xml.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rIdFoot" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/footnotes" Target="footnotes.xml"/></Relationships>"#,
),
(
"word/styles.xml",
r#"<w:styles xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:style w:type="paragraph" w:styleId="Heading1"><w:name w:val="heading 1"/></w:style></w:styles>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:bookmarkStart w:id="1" w:name="FootOne"/><w:r><w:footnoteReference w:id="1"/></w:r><w:bookmarkEnd w:id="1"/></w:p><w:p><w:pPr><w:pStyle w:val="Heading1"/></w:pPr><w:r><w:t>Section </w:t></w:r><w:fldSimple w:instr=" REF FootOne \f "><w:r><w:t>stale heading ref note</w:t></w:r></w:fldSimple><w:r><w:t> Review</w:t></w:r></w:p><w:p><w:fldSimple w:instr=" TOC \o "1-1" "><w:r><w:t>stale ref-note toc</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
(
"word/footnotes.xml",
r#"<w:footnotes xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:footnote w:type="separator" w:id="-1"><w:p><w:r><w:separator/></w:r></w:p></w:footnote><w:footnote w:id="1"><w:p><w:r><w:t>First footnote.</w:t></w:r></w:p></w:footnote></w:footnotes>"#,
),
])
}
fn toc_heading_mixed_ref_note_mark_source_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/><Override PartName="/word/styles.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml"/><Override PartName="/word/footnotes.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.footnotes+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/_rels/document.xml.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rIdFoot" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/footnotes" Target="footnotes.xml"/></Relationships>"#,
),
(
"word/styles.xml",
r#"<w:styles xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:style w:type="paragraph" w:styleId="Heading1"><w:name w:val="heading 1"/></w:style></w:styles>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:bookmarkStart w:id="1" w:name="FootOne"/><w:r><w:footnoteReference w:id="1"/></w:r><w:bookmarkEnd w:id="1"/></w:p><w:p><w:bookmarkStart w:id="2" w:name="ChapTitle"/><w:r><w:t>Live Chapter</w:t></w:r><w:bookmarkEnd w:id="2"/></w:p><w:p><w:pPr><w:pStyle w:val="Heading1"/></w:pPr><w:r><w:t>Section </w:t></w:r><w:fldSimple w:instr=" REF ChapTitle "><w:r><w:t>stale heading ref</w:t></w:r></w:fldSimple><w:r><w:t> </w:t></w:r><w:r><w:footnoteReference w:id="2"/></w:r><w:r><w:t> </w:t></w:r><w:fldSimple w:instr=" REF FootOne \f "><w:r><w:t>stale heading ref note</w:t></w:r></w:fldSimple><w:r><w:t> Review</w:t></w:r></w:p><w:p><w:fldSimple w:instr=" TOC \o "1-1" "><w:r><w:t>stale mixed-ref toc</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
(
"word/footnotes.xml",
r#"<w:footnotes xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:footnote w:type="separator" w:id="-1"><w:p><w:r><w:separator/></w:r></w:p></w:footnote><w:footnote w:id="1"><w:p><w:r><w:t>First footnote.</w:t></w:r></w:p></w:footnote><w:footnote w:id="2"><w:p><w:r><w:t>Second footnote.</w:t></w:r></w:p></w:footnote></w:footnotes>"#,
),
])
}
fn toc_heading_document_info_field_source_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/><Override PartName="/docProps/core.xml" ContentType="application/vnd.openxmlformats-package.core-properties+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/><Relationship Id="rIdCore" Type="http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties" Target="docProps/core.xml"/></Relationships>"#,
),
(
"docProps/core.xml",
r#"<cp:coreProperties xmlns:cp="http://schemas.openxmlformats.org/package/2006/metadata/core-properties" xmlns:dc="http://purl.org/dc/elements/1.1/"><dc:title>Quarter Plan</dc:title></cp:coreProperties>"#,
),
(
"word/styles.xml",
r#"<w:styles xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:style w:type="paragraph" w:styleId="Heading1"><w:name w:val="heading 1"/></w:style></w:styles>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:pPr><w:pStyle w:val="Heading1"/></w:pPr><w:r><w:t>Topic </w:t></w:r><w:fldSimple w:instr=" TITLE "><w:r><w:t>stale toc title</w:t></w:r></w:fldSimple><w:r><w:t> Review</w:t></w:r></w:p><w:p><w:fldSimple w:instr=" TOC \o "1-1" "><w:r><w:t>stale document-info toc source</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn toc_heading_section_field_source_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/><Override PartName="/word/styles.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/styles.xml",
r#"<w:styles xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:style w:type="paragraph" w:styleId="Heading1"><w:name w:val="heading 1"/></w:style></w:styles>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:pPr><w:pStyle w:val="Heading1"/></w:pPr><w:r><w:t>Section </w:t></w:r><w:fldSimple w:instr=" SECTION "><w:r><w:t>99</w:t></w:r></w:fldSimple><w:r><w:t> Review</w:t></w:r></w:p><w:p><w:fldSimple w:instr=" TOC \o "1-1" "><w:r><w:t>stale section toc source</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn toc_heading_known_field_name_bookmark_source_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/styles.xml",
r#"<w:styles xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:style w:type="paragraph" w:styleId="Heading1"><w:name w:val="heading 1"/></w:style></w:styles>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:bookmarkStart w:id="7" w:name="PAGEREF"/><w:r><w:t>bookmark target</w:t></w:r><w:bookmarkEnd w:id="7"/></w:p><w:p><w:pPr><w:pStyle w:val="Heading1"/></w:pPr><w:r><w:t>Heading </w:t></w:r><w:fldSimple w:instr=" PAGEREF "><w:r><w:t>known field source</w:t></w:r></w:fldSimple><w:r><w:t> ready</w:t></w:r></w:p><w:p><w:fldSimple w:instr=" TOC \o "1-1" "><w:r><w:t>stale known field source toc</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn toc_heading_bookmark_comparison_field_source_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/styles.xml",
r#"<w:styles xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:style w:type="paragraph" w:styleId="Heading1"><w:name w:val="heading 1"/></w:style></w:styles>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:bookmarkStart w:id="7" w:name="InvoiceTier"/><w:r><w:t>Gold</w:t></w:r><w:bookmarkEnd w:id="7"/></w:p><w:p><w:bookmarkStart w:id="8" w:name="InvoiceTotal"/><w:r><w:t>42</w:t></w:r><w:bookmarkEnd w:id="8"/></w:p><w:p><w:pPr><w:pStyle w:val="Heading1"/></w:pPr><w:r><w:t>Status </w:t></w:r><w:fldSimple w:instr=" IF InvoiceTier = "Gold" "ship" "hold" "><w:r><w:t>stale source if</w:t></w:r></w:fldSimple><w:r><w:t> </w:t></w:r><w:fldSimple w:instr=" COMPARE InvoiceTotal >= 40 "><w:r><w:t>stale source compare</w:t></w:r></w:fldSimple><w:fldSimple w:instr=" NEXTIF InvoiceTier = "Gold" "><w:r><w:t>stale source nextif</w:t></w:r></w:fldSimple><w:fldSimple w:instr=" SKIPIF InvoiceTotal < 40 "><w:r><w:t>stale source skipif</w:t></w:r></w:fldSimple><w:r><w:t> ready</w:t></w:r></w:p><w:p><w:fldSimple w:instr=" TOC \o "1-1" "><w:r><w:t>stale bookmark-comparison-source toc</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn toc_heading_set_ref_field_source_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/styles.xml",
r#"<w:styles xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:style w:type="paragraph" w:styleId="Heading1"><w:name w:val="heading 1"/></w:style></w:styles>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:pPr><w:pStyle w:val="Heading1"/></w:pPr><w:r><w:t>Status </w:t></w:r><w:fldSimple w:instr=" SET Marker "Ready" "><w:r><w:t>stale set</w:t></w:r></w:fldSimple><w:fldSimple w:instr=" REF Marker "><w:r><w:t>stale ref</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" TOC \o "1-1" "><w:r><w:t>stale set-ref-source toc</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn toc_heading_prior_set_ref_field_source_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/styles.xml",
r#"<w:styles xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:style w:type="paragraph" w:styleId="Heading1"><w:name w:val="heading 1"/></w:style></w:styles>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:fldSimple w:instr=" SET Marker "Ready" "><w:r><w:t>stale prior set</w:t></w:r></w:fldSimple></w:p><w:p><w:pPr><w:pStyle w:val="Heading1"/></w:pPr><w:r><w:t>Status </w:t></w:r><w:fldSimple w:instr=" REF Marker "><w:r><w:t>stale ref</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" TOC \o "1-1" "><w:r><w:t>stale prior-set-ref-source toc</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn toc_property_revision_heading_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/styles.xml",
r#"<w:styles xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:style w:type="paragraph" w:styleId="Heading1"><w:name w:val="heading 1"/></w:style></w:styles>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:pPr><w:pPrChange w:id="9" w:author="Reviewer"><w:pPr><w:pStyle w:val="Heading1"/></w:pPr></w:pPrChange></w:pPr><w:r><w:t>Former heading only</w:t></w:r></w:p><w:p><w:pPr><w:pStyle w:val="Heading1"/></w:pPr><w:r><w:t>Current Heading</w:t></w:r></w:p><w:p><w:fldSimple w:instr=" TOC \o "1-1" "><w:r><w:t>stale current toc</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn complex_toc_heading_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/styles.xml",
r#"<w:styles xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:style w:type="paragraph" w:styleId="Heading1"><w:name w:val="heading 1"/></w:style></w:styles>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:pPr><w:pStyle w:val="Heading1"/></w:pPr><w:r><w:t>Executive Summary</w:t></w:r></w:p><w:p><w:pPr><w:outlineLvl w:val="1"/></w:pPr><w:r><w:t>Risks</w:t></w:r></w:p><w:p><w:r><w:fldChar w:fldCharType="begin"/></w:r><w:r><w:instrText> TOC \o "1-2" \* Upper </w:instrText></w:r><w:r><w:fldChar w:fldCharType="separate"/></w:r><w:r><w:t>stale complex toc</w:t></w:r><w:r><w:fldChar w:fldCharType="end"/></w:r></w:p></w:body></w:document>"#,
),
])
}
fn toc_heading_inline_break_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/styles.xml",
r#"<w:styles xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:style w:type="paragraph" w:styleId="Heading1"><w:name w:val="heading 1"/></w:style></w:styles>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:pPr><w:pStyle w:val="Heading1"/></w:pPr><w:r><w:t>Executive</w:t><w:tab/><w:t>Summary</w:t><w:br/><w:t>Detail</w:t><w:noBreakHyphen/><w:t>Follow-up</w:t></w:r></w:p><w:p><w:fldSimple w:instr=" TOC \o "1-1" "><w:r><w:t>stale inline toc</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn toc_heading_hidden_result_markers_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/styles.xml",
r#"<w:styles xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:style w:type="paragraph" w:styleId="Heading1"><w:name w:val="heading 1"/></w:style></w:styles>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:pPr><w:pStyle w:val="Heading1"/></w:pPr><w:r><w:t>Executive </w:t></w:r><w:r><w:fldChar w:fldCharType="begin"/></w:r><w:r><w:instrText> SEQ Figure </w:instrText></w:r><w:r><w:fldChar w:fldCharType="separate"/></w:r><w:r><w:tab/><w:br/><w:noBreakHyphen/><w:softHyphen/><w:t>stale hidden seq result</w:t></w:r><w:r><w:fldChar w:fldCharType="end"/></w:r></w:p><w:p><w:fldSimple w:instr=" TOC \o "1-1" "><w:r><w:t>stale outer toc</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn toc_heading_symbol_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/styles.xml",
r#"<w:styles xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:style w:type="paragraph" w:styleId="Heading1"><w:name w:val="heading 1"/></w:style></w:styles>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:pPr><w:pStyle w:val="Heading1"/></w:pPr><w:r><w:t>Risk </w:t><w:sym w:font="Symbol" w:char="F0B7"/><w:t> Control</w:t></w:r></w:p><w:p><w:fldSimple w:instr=" TOC \o "1-1" "><w:r><w:t>stale symbol toc</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn toc_non_empty_symbol_source_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/styles.xml",
r#"<w:styles xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:style w:type="paragraph" w:styleId="Heading1"><w:name w:val="heading 1"/></w:style></w:styles>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:pPr><w:pStyle w:val="Heading1"/></w:pPr><w:r><w:t>Risk </w:t><w:sym w:font="Symbol" w:char="F0B7"></w:sym><w:t> Control</w:t></w:r></w:p><w:p><w:r><w:t>Figure </w:t></w:r><w:fldSimple w:instr=" SEQ Figure "><w:r><w:t>9</w:t></w:r></w:fldSimple><w:r><w:t>: Risk </w:t><w:sym w:font="Symbol" w:char="F0B7"></w:sym><w:t> Control</w:t></w:r></w:p><w:p><w:fldSimple w:instr=" TOC \o "1-1" "><w:r><w:t>stale non-empty symbol heading toc</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" TOC \c Figure "><w:r><w:t>stale non-empty symbol caption toc</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" TOC \a Figure "><w:r><w:t>stale non-empty symbol caption text toc</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn bare_toc_heading_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/styles.xml",
r#"<w:styles xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:style w:type="paragraph" w:styleId="Heading1"><w:name w:val="heading 1"/></w:style></w:styles>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:pPr><w:pStyle w:val="Heading1"/></w:pPr><w:r><w:t>Executive Summary</w:t></w:r></w:p><w:p><w:pPr><w:outlineLvl w:val="1"/></w:pPr><w:r><w:t>Risks</w:t></w:r></w:p><w:p><w:pPr><w:outlineLvl w:val="2"/></w:pPr><w:r><w:t>Mitigation</w:t></w:r></w:p><w:p><w:pPr><w:outlineLvl w:val="3"/></w:pPr><w:r><w:t>Excluded Detail</w:t></w:r></w:p><w:p><w:fldSimple w:instr=" TOC "><w:r><w:t>stale bare toc</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn default_neutral_toc_heading_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/styles.xml",
r#"<w:styles xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:style w:type="paragraph" w:styleId="Heading1"><w:name w:val="heading 1"/></w:style></w:styles>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:pPr><w:pStyle w:val="Heading1"/></w:pPr><w:r><w:t>Executive Summary</w:t></w:r></w:p><w:p><w:pPr><w:outlineLvl w:val="1"/></w:pPr><w:r><w:t>Risks</w:t></w:r></w:p><w:p><w:pPr><w:outlineLvl w:val="2"/></w:pPr><w:r><w:t>Mitigation</w:t></w:r></w:p><w:p><w:pPr><w:outlineLvl w:val="3"/></w:pPr><w:r><w:t>Excluded Detail</w:t></w:r></w:p><w:p><w:fldSimple w:instr=" TOC \h \z "><w:r><w:t>stale neutral default toc</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" TOC \n "1-3" "><w:r><w:t>stale no-page default toc</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" TOC \p "-" "><w:r><w:t>stale separator default toc</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" TOC \s chapter \d "-" "><w:r><w:t>stale sequence default toc</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" TOC \* Upper "><w:r><w:t>stale upper default toc</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" TOC \* MERGEFORMAT "><w:r><w:t>stale mergeformat default toc</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn advanced_toc_switch_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/styles.xml",
r#"<w:styles xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:style w:type="paragraph" w:styleId="Heading1"><w:name w:val="heading 1"/></w:style></w:styles>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:pPr><w:pStyle w:val="Heading1"/></w:pPr><w:r><w:t>Executive Summary</w:t></w:r></w:p><w:p><w:fldSimple w:instr=" TOC \o "1-2" \t "CustomHeading,1" "><w:r><w:t>stale advanced toc</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn toc_custom_style_switch_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/styles.xml",
r#"<w:styles xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:style w:type="paragraph" w:styleId="Heading1"><w:name w:val="heading 1"/></w:style><w:style w:type="paragraph" w:styleId="CustomCallout"><w:name w:val="CustomHeading"/></w:style></w:styles>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:pPr><w:pStyle w:val="Heading1"/></w:pPr><w:r><w:t>Executive Summary</w:t></w:r></w:p><w:p><w:pPr><w:pStyle w:val="CustomCallout"/></w:pPr><w:r><w:t>Custom Finding</w:t></w:r></w:p><w:p><w:fldSimple w:instr=" TOC \o "1-1" \t "CustomHeading,2" "><w:r><w:t>stale custom toc</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn toc_quoted_custom_style_switch_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/styles.xml",
r#"<w:styles xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:style w:type="paragraph" w:styleId="Heading1"><w:name w:val="heading 1"/></w:style><w:style w:type="paragraph" w:styleId="CustomCallout"><w:name w:val="Custom Heading"/></w:style></w:styles>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:pPr><w:pStyle w:val="Heading1"/></w:pPr><w:r><w:t>Executive Summary</w:t></w:r></w:p><w:p><w:pPr><w:pStyle w:val="CustomCallout"/></w:pPr><w:r><w:t>Custom Finding</w:t></w:r></w:p><w:p><w:fldSimple w:instr=" TOC \o "1-1" \t "Custom Heading,2" "><w:r><w:t>stale quoted custom toc</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn toc_unquoted_multi_token_custom_style_switch_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/styles.xml",
r#"<w:styles xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:style w:type="paragraph" w:styleId="Heading1"><w:name w:val="heading 1"/></w:style><w:style w:type="paragraph" w:styleId="CustomCallout"><w:name w:val="Custom Heading"/></w:style></w:styles>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:pPr><w:pStyle w:val="Heading1"/></w:pPr><w:r><w:t>Executive Summary</w:t></w:r></w:p><w:p><w:pPr><w:pStyle w:val="CustomCallout"/></w:pPr><w:r><w:t>Custom Finding</w:t></w:r></w:p><w:p><w:fldSimple w:instr=" TOC \o "1-1" \t Custom Heading,2 \* Upper "><w:r><w:t>stale unquoted custom toc</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn toc_tc_field_switch_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:fldSimple w:instr=" TC "Manual Entry" \f m \l 2 "><w:r><w:t>stale manual tc</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" TC "Other Entry" \f x \l 1 "><w:r><w:t>stale other tc</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" TOC \f m "><w:r><w:t>stale tc toc</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn toc_tc_format_tail_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:fldSimple w:instr=" TC "manual entry" \f m \l 2 \* Upper "><w:r><w:t>stale formatted tc</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" TC "other entry" \f x \l 1 \* Caps "><w:r><w:t>stale other formatted tc</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" TOC \f m "><w:r><w:t>stale formatted tc toc</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn toc_tc_unquoted_multi_token_text_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:fldSimple w:instr=" TC Manual Appendix Entry \f m \l 2 "><w:r><w:t>cached unquoted tc</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" TOC \f m "><w:r><w:t>stale unquoted tc toc</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn toc_deleted_tc_field_switch_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:del><w:p><w:fldSimple w:instr=" TC "Deleted Entry" \f m \l 1 "/></w:p></w:del><w:moveFrom><w:p><w:fldSimple w:instr=" TC "Moved Entry" \f m \l 1 "/></w:p></w:moveFrom><w:p><w:fldSimple w:instr=" TC "Visible Entry" \f m \l 1 "><w:r><w:t>stale visible marker</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" TOC \f m "><w:r><w:t>stale deleted tc toc</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn toc_alternate_content_heading_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/styles.xml",
r#"<w:styles xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:style w:type="paragraph" w:styleId="Heading1"><w:name w:val="heading 1"/></w:style></w:styles>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="wps"><w:body><mc:AlternateContent><mc:Choice Requires="wps"><w:p><w:pPr><w:pStyle w:val="Heading1"/></w:pPr><w:r><w:t>Choice </w:t><mc:AlternateContent><mc:Choice Requires="wps"><w:t>Inline</w:t></mc:Choice><mc:Fallback><w:t>Fallback Inline</w:t></mc:Fallback></mc:AlternateContent></w:r></w:p></mc:Choice><mc:Fallback><w:p><w:pPr><w:pStyle w:val="Heading1"/></w:pPr><w:r><w:t>Fallback Heading</w:t></w:r></w:p></mc:Fallback></mc:AlternateContent><w:p><w:fldSimple w:instr=" TOC \o "1-1" "><w:r><w:t>stale alternate toc</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn toc_styles_alternate_content_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/styles.xml",
r#"<w:styles xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"><mc:AlternateContent><mc:Choice Requires="w14"><w:style w:type="paragraph" w:styleId="ChoiceHeading"><w:name w:val="heading 1"/></w:style></mc:Choice><mc:Fallback><w:style w:type="paragraph" w:styleId="FallbackHeading"><w:name w:val="heading 1"/></w:style></mc:Fallback></mc:AlternateContent></w:styles>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:pPr><w:pStyle w:val="ChoiceHeading"/></w:pPr><w:r><w:t>Choice Heading</w:t></w:r></w:p><w:p><w:pPr><w:pStyle w:val="FallbackHeading"/></w:pPr><w:r><w:t>Fallback Ghost</w:t></w:r></w:p><w:p><w:fldSimple w:instr=" TOC \o "1-1" "><w:r><w:t>stale styles toc</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn invalid_toc_entry_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:fldSimple w:instr=" TC \l 2 "><w:r><w:t>cached invalid tc</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn toc_sequence_caption_switch_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:r><w:t>Figure </w:t></w:r><w:fldSimple w:instr=" SEQ Figure "><w:r><w:t>1</w:t></w:r></w:fldSimple><w:r><w:t>: Mercury</w:t></w:r></w:p><w:p><w:r><w:t>Table </w:t></w:r><w:fldSimple w:instr=" SEQ Table "><w:r><w:t>1</w:t></w:r></w:fldSimple><w:r><w:t>: Invoices</w:t></w:r></w:p><w:p><w:fldSimple w:instr=" TOC \c "Figure" "><w:r><w:t>stale figures toc</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn toc_dirty_sequence_caption_switch_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:r><w:t>Figure </w:t></w:r><w:fldSimple w:instr=" SEQ Figure "><w:r><w:t>9</w:t></w:r></w:fldSimple><w:r><w:t>: Mercury</w:t></w:r></w:p><w:p><w:r><w:t>Figure </w:t></w:r><w:fldSimple w:instr=" SEQ Figure "><w:r><w:t>99</w:t></w:r></w:fldSimple><w:r><w:t>: Venus</w:t></w:r></w:p><w:p><w:fldSimple w:instr=" TOC \c Figure "><w:r><w:t>stale dirty figures toc</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn toc_dirty_complex_sequence_caption_switch_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:r><w:t>Figure </w:t></w:r><w:r><w:fldChar w:fldCharType="begin"/></w:r><w:r><w:instrText> SEQ Figure </w:instrText></w:r><w:r><w:fldChar w:fldCharType="separate"/></w:r><w:r><w:t>9</w:t></w:r><w:r><w:fldChar w:fldCharType="end"/></w:r><w:r><w:t>: Mercury</w:t></w:r></w:p><w:p><w:r><w:t>Figure </w:t></w:r><w:r><w:fldChar w:fldCharType="begin"/></w:r><w:r><w:instrText> SEQ Figure </w:instrText></w:r><w:r><w:fldChar w:fldCharType="separate"/></w:r><w:r><w:t>99</w:t></w:r><w:r><w:fldChar w:fldCharType="end"/></w:r><w:r><w:t>: Venus</w:t></w:r></w:p><w:p><w:fldSimple w:instr=" TOC \c Figure "><w:r><w:t>stale dirty complex figures toc</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn toc_sequence_caption_text_switch_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:r><w:t>Figure </w:t></w:r><w:fldSimple w:instr=" SEQ Figure "><w:r><w:t>8</w:t></w:r></w:fldSimple><w:r><w:t>: Mercury</w:t></w:r></w:p><w:p><w:r><w:t>Table </w:t></w:r><w:fldSimple w:instr=" SEQ Table "><w:r><w:t>2</w:t></w:r></w:fldSimple><w:r><w:t>: Invoices</w:t></w:r></w:p><w:p><w:fldSimple w:instr=" TOC \a Figure "><w:r><w:t>stale caption-text toc</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn toc_sequence_heading_reset_caption_switch_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/styles.xml",
r#"<w:styles xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:style w:type="paragraph" w:styleId="Heading1"><w:name w:val="heading 1"/></w:style></w:styles>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:pPr><w:pStyle w:val="Heading1"/></w:pPr><w:r><w:t>Chapter One</w:t></w:r></w:p><w:p><w:r><w:t>Figure </w:t></w:r><w:fldSimple w:instr=" SEQ Figure \s 1 "><w:r><w:t>9</w:t></w:r></w:fldSimple><w:r><w:t>: Mercury</w:t></w:r></w:p><w:p><w:pPr><w:pStyle w:val="Heading1"/></w:pPr><w:r><w:t>Chapter Two</w:t></w:r></w:p><w:p><w:r><w:t>Figure </w:t></w:r><w:fldSimple w:instr=" SEQ Figure \s1 "><w:r><w:t>99</w:t></w:r></w:fldSimple><w:r><w:t>: Venus</w:t></w:r></w:p><w:p><w:fldSimple w:instr=" TOC \c Figure "><w:r><w:t>stale heading-reset figures toc</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" TOC \a Figure "><w:r><w:t>stale heading-reset captions toc</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn toc_neutral_switch_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/styles.xml",
r#"<w:styles xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:style w:type="paragraph" w:styleId="Heading1"><w:name w:val="heading 1"/></w:style></w:styles>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:pPr><w:pStyle w:val="Heading1"/></w:pPr><w:r><w:t>Executive Summary</w:t></w:r></w:p><w:p><w:pPr><w:outlineLvl w:val="1"/></w:pPr><w:r><w:t>Risks</w:t></w:r></w:p><w:p><w:fldSimple w:instr=" TOC \o "1-2" \h \z \w \x "><w:r><w:t>stale neutral toc</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn toc_general_format_switch_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/styles.xml",
r#"<w:styles xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:style w:type="paragraph" w:styleId="Heading1"><w:name w:val="heading 1"/></w:style></w:styles>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:pPr><w:pStyle w:val="Heading1"/></w:pPr><w:r><w:t>executive summary</w:t></w:r></w:p><w:p><w:pPr><w:outlineLvl w:val="1"/></w:pPr><w:r><w:t>risk review</w:t></w:r></w:p><w:p><w:fldSimple w:instr=" TOC \o "1-2" \* Upper "><w:r><w:t>stale upper toc</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" TOC \o "1-2" \* Caps "><w:r><w:t>stale caps toc</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" TOC \o "1-2" \* MERGEFORMAT "><w:r><w:t>stale mergeformat toc</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" TOC \o "1-2" \* MERGEFORMATINET "><w:r><w:t>stale web-format toc</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn toc_no_page_numbers_switch_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/styles.xml",
r#"<w:styles xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:style w:type="paragraph" w:styleId="Heading1"><w:name w:val="heading 1"/></w:style></w:styles>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:pPr><w:pStyle w:val="Heading1"/></w:pPr><w:r><w:t>Executive Summary</w:t></w:r></w:p><w:p><w:pPr><w:outlineLvl w:val="1"/></w:pPr><w:r><w:t>Risks</w:t></w:r></w:p><w:p><w:fldSimple w:instr=" TOC \o "1-2" \n "1-2" "><w:r><w:t>stale no-page toc</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn toc_entry_page_separator_switch_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/styles.xml",
r#"<w:styles xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:style w:type="paragraph" w:styleId="Heading1"><w:name w:val="heading 1"/></w:style></w:styles>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:pPr><w:pStyle w:val="Heading1"/></w:pPr><w:r><w:t>Executive Summary</w:t></w:r></w:p><w:p><w:pPr><w:outlineLvl w:val="1"/></w:pPr><w:r><w:t>Risks</w:t></w:r></w:p><w:p><w:fldSimple w:instr=" TOC \o "1-2" \p "-" "><w:r><w:t>stale separator toc</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn toc_sequence_page_separator_switch_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/styles.xml",
r#"<w:styles xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:style w:type="paragraph" w:styleId="Heading1"><w:name w:val="heading 1"/></w:style></w:styles>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:pPr><w:pStyle w:val="Heading1"/></w:pPr><w:r><w:t>Executive Summary</w:t></w:r></w:p><w:p><w:pPr><w:outlineLvl w:val="1"/></w:pPr><w:r><w:t>Risks</w:t></w:r></w:p><w:p><w:fldSimple w:instr=" TOC \o "1-2" \s chapter \d "-" "><w:r><w:t>stale sequence separator toc</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn toc_outline_level_switch_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/styles.xml",
r#"<w:styles xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:style w:type="paragraph" w:styleId="Heading1"><w:name w:val="heading 1"/></w:style></w:styles>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:pPr><w:pStyle w:val="Heading1"/></w:pPr><w:r><w:t>Style Heading</w:t></w:r></w:p><w:p><w:pPr><w:outlineLvl w:val="0"/></w:pPr><w:r><w:t>Outline Heading</w:t></w:r></w:p><w:p><w:fldSimple w:instr=" TOC \u "><w:r><w:t>stale outline toc</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn toc_heading_and_outline_switch_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/styles.xml",
r#"<w:styles xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:style w:type="paragraph" w:styleId="Heading1"><w:name w:val="heading 1"/></w:style></w:styles>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:pPr><w:pStyle w:val="Heading1"/></w:pPr><w:r><w:t>Style Heading</w:t></w:r></w:p><w:p><w:pPr><w:outlineLvl w:val="0"/></w:pPr><w:r><w:t>Outline Heading</w:t></w:r></w:p><w:p><w:fldSimple w:instr=" TOC \o "1-2" \u "><w:r><w:t>stale combined toc</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn toc_bookmark_scope_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/styles.xml",
r#"<w:styles xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:style w:type="paragraph" w:styleId="Heading1"><w:name w:val="heading 1"/></w:style><w:style w:type="paragraph" w:styleId="Heading2"><w:name w:val="heading 2"/></w:style></w:styles>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:pPr><w:pStyle w:val="Heading1"/></w:pPr><w:r><w:t>Outside Heading</w:t></w:r></w:p><w:p><w:bookmarkStart w:id="7" w:name="ScopedToc"/><w:pPr><w:pStyle w:val="Heading1"/></w:pPr><w:r><w:t>Scoped Heading</w:t></w:r></w:p><w:p><w:pPr><w:pStyle w:val="Heading2"/></w:pPr><w:r><w:t>Scoped Detail</w:t></w:r><w:bookmarkEnd w:id="7"/></w:p><w:p><w:pPr><w:pStyle w:val="Heading1"/></w:pPr><w:r><w:t>Trailing Heading</w:t></w:r></w:p><w:p><w:fldSimple w:instr=" TOC \o "1-2" \b ScopedToc "><w:r><w:t>stale scoped toc</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn toc_bookmark_scoped_tc_field_switch_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:fldSimple w:instr=" TC "Outside Manual" \f m \l 1 "><w:r><w:t>stale outside tc</w:t></w:r></w:fldSimple></w:p><w:p><w:bookmarkStart w:id="7" w:name="ScopedToc"/><w:fldSimple w:instr=" TC "Scoped Manual" \f m \l 2 "><w:r><w:t>stale scoped tc</w:t></w:r></w:fldSimple><w:bookmarkEnd w:id="7"/></w:p><w:p><w:fldSimple w:instr=" TOC \b ScopedToc \f m "><w:r><w:t>stale scoped tc toc</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn toc_bookmark_only_scope_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/styles.xml",
r#"<w:styles xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:style w:type="paragraph" w:styleId="Heading1"><w:name w:val="heading 1"/></w:style><w:style w:type="paragraph" w:styleId="Heading2"><w:name w:val="heading 2"/></w:style><w:style w:type="paragraph" w:styleId="Heading4"><w:name w:val="heading 4"/></w:style></w:styles>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:pPr><w:pStyle w:val="Heading1"/></w:pPr><w:r><w:t>Outside Heading</w:t></w:r></w:p><w:p><w:bookmarkStart w:id="7" w:name="ScopedToc"/><w:pPr><w:pStyle w:val="Heading1"/></w:pPr><w:r><w:t>Scoped Heading</w:t></w:r></w:p><w:p><w:pPr><w:pStyle w:val="Heading2"/></w:pPr><w:r><w:t>Scoped Detail</w:t></w:r><w:bookmarkEnd w:id="7"/></w:p><w:p><w:pPr><w:pStyle w:val="Heading4"/></w:pPr><w:r><w:t>Scoped Deep Heading</w:t></w:r></w:p><w:p><w:fldSimple w:instr=" TOC \b ScopedToc "><w:r><w:t>stale bookmark-only toc</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn compact_toc_operand_switch_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/styles.xml",
r#"<w:styles xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:style w:type="paragraph" w:styleId="Heading1"><w:name w:val="heading 1"/></w:style><w:style w:type="paragraph" w:styleId="Heading2"><w:name w:val="heading 2"/></w:style></w:styles>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:pPr><w:pStyle w:val="Heading1"/></w:pPr><w:r><w:t>Outside Heading</w:t></w:r></w:p><w:p><w:bookmarkStart w:id="7" w:name="ScopedToc"/><w:pPr><w:pStyle w:val="Heading1"/></w:pPr><w:r><w:t>Scoped Heading</w:t></w:r></w:p><w:p><w:pPr><w:pStyle w:val="Heading2"/></w:pPr><w:r><w:t>Scoped Detail</w:t></w:r><w:bookmarkEnd w:id="7"/></w:p><w:p><w:fldSimple w:instr=" TC "Manual Entry" \fm \l2 "/></w:p><w:p><w:fldSimple w:instr=" TOC \fm \l2-3 "><w:r><w:t>stale compact tc toc</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" TOC \o"1-2" \bScopedToc \*Upper "><w:r><w:t>stale compact scoped toc</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn toc_outline_without_range_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/styles.xml",
r#"<w:styles xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:style w:type="paragraph" w:styleId="Heading1"><w:name w:val="heading 1"/></w:style><w:style w:type="paragraph" w:styleId="Heading4"><w:name w:val="heading 4"/></w:style></w:styles>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:pPr><w:pStyle w:val="Heading1"/></w:pPr><w:r><w:t>Executive Summary</w:t></w:r></w:p><w:p><w:pPr><w:pStyle w:val="Heading4"/></w:pPr><w:r><w:t>Appendix Detail</w:t></w:r></w:p><w:p><w:fldSimple w:instr=" TOC \o "><w:r><w:t>stale open-outline toc</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn missing_toc_bookmark_scope_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/styles.xml",
r#"<w:styles xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:style w:type="paragraph" w:styleId="Heading1"><w:name w:val="heading 1"/></w:style></w:styles>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:pPr><w:pStyle w:val="Heading1"/></w:pPr><w:r><w:t>Existing Heading</w:t></w:r></w:p><w:p><w:fldSimple w:instr=" TOC \o "1-1" \b MissingScope "><w:r><w:t>stale missing scope toc</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn toc_scope_gap_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:bookmarkStart w:id="7" w:name="PlainText"/><w:r><w:t>Plain target</w:t></w:r><w:bookmarkEnd w:id="7"/></w:p><w:p><w:fldSimple w:instr=" TOC \b PlainText "><w:r><w:t>cached empty toc</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" TOC \b MissingScope "><w:r><w:t>cached missing toc scope</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn unsupported_toc_switch_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:fldSimple w:instr=" TOC \q "><w:r><w:t>cached bad toc switch</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
fn unknown_field_gap_docx() -> Vec<u8> {
docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:fldSimple w:instr=" CUSTOM Field "><w:r><w:t>cached unknown field</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
])
}
#[test]
fn docx_fields_are_extracted() {
let doc = Document::open(&field_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 6);
assert_eq!(fields[0].kind, FieldKind::Page);
assert_eq!(fields[0].instruction, "PAGE");
assert_eq!(fields[0].result, "1");
assert_eq!(fields[1].kind, FieldKind::Toc);
assert_eq!(fields[1].instruction, "TOC \\o \"1-3\"");
assert_eq!(fields[2].kind, FieldKind::Ref);
assert_eq!(fields[3].kind, FieldKind::Hyperlink);
assert_eq!(fields[4].kind, FieldKind::Unknown("CUSTOM".to_string()));
assert_eq!(fields[5].kind, FieldKind::Filename);
assert_eq!(fields[5].instruction, "FILENAME \\p");
assert_eq!(fields[5].result, "report.docx");
}
#[test]
fn docx_unknown_field_gap_case_keeps_cached_text() {
let doc = Document::open(&unknown_field_gap_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 1);
assert_eq!(fields[0].kind, FieldKind::Unknown("CUSTOM".to_string()));
assert_eq!(fields[0].instruction, "CUSTOM Field");
assert_eq!(fields[0].result, "cached unknown field");
assert_eq!(fields[0].computed_result, None);
let report = doc.report();
assert_eq!(
report.features.unsupported_field_kinds,
vec![FieldKindCount {
kind: FieldKind::Unknown("CUSTOM".to_string()),
count: 1,
}]
);
assert_eq!(
report.features.unsupported_field_reasons,
vec![FieldEvaluationReasonCount {
reason: FieldEvaluationReason::UnknownField,
count: 1,
}]
);
let main_text = doc.main_text();
assert!(
main_text.contains("cached unknown field"),
"unknown field gap case should preserve cached result text: {main_text:?}"
);
}
#[test]
fn docx_complex_field_char_type_trims_ooxml_value() {
let doc = Document::open(&docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:r><w:fldChar w:fldCharType=" begin "/></w:r><w:r><w:instrText> PAGE </w:instrText></w:r><w:r><w:fldChar w:fldCharType=" separate "/></w:r><w:r><w:t>cached page</w:t></w:r><w:r><w:fldChar w:fldCharType=" end "/></w:r></w:p></w:body></w:document>"#,
),
]))
.expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 1);
assert_eq!(fields[0].instruction, "PAGE");
assert_eq!(fields[0].result, "cached page");
assert_eq!(fields[0].computed_result.as_deref(), Some("1"));
assert_eq!(doc.main_text(), "1");
assert_eq!(doc.report().features.fields, 1);
}
#[test]
fn docx_fields_follow_accepted_revision_view() {
let doc = Document::open(&revision_wrapped_field_docx()).expect("fixture opens");
assert_eq!(doc.main_text(), "direct name\ninserted name\nmoved-to name");
let fields = doc.fields();
let instructions: Vec<_> = fields
.iter()
.map(|field| field.instruction.as_str())
.collect();
assert_eq!(
instructions,
vec![
"MERGEFIELD DirectName",
"MERGEFIELD InsertedName",
"MERGEFIELD MovedToName"
]
);
assert!(fields
.iter()
.all(|field| field.kind == FieldKind::MergeField));
}
#[test]
fn docx_fields_use_single_alternate_content_branch() {
let doc = Document::open(&alternate_content_field_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 1);
assert_eq!(fields[0].kind, FieldKind::MergeField);
assert_eq!(fields[0].instruction, "MERGEFIELD AltClient");
assert_eq!(fields[0].result, "Choice Client");
assert_eq!(doc.report().features.fields, 1);
assert_eq!(doc.main_text(), "Choice Client");
}
#[test]
fn docx_body_text_uses_single_inline_alternate_content_branch() {
let doc = Document::open(&docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"><w:body><w:p><w:r><w:t>Before </w:t><mc:AlternateContent><mc:Choice Requires="wps"><w:t>Choice inline</w:t></mc:Choice><mc:Fallback><w:t>Fallback inline</w:t></mc:Fallback></mc:AlternateContent><w:t> after</w:t></w:r></w:p></w:body></w:document>"#,
),
]))
.expect("fixture opens");
assert_eq!(doc.main_text(), "Before Choice inline after");
}
#[test]
fn docx_paragraph_alternate_content_preserves_hyperlink_runs() {
let doc = Document::open(&docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/_rels/document.xml.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rIdChoice" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink" Target="https://example.com/choice" TargetMode="External"/><Relationship Id="rIdFallback" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink" Target="https://example.com/fallback" TargetMode="External"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"><w:body><w:p><mc:AlternateContent><mc:Choice Requires="wps"><w:hyperlink r:id="rIdChoice"><w:r><w:t>Choice link</w:t></w:r></w:hyperlink></mc:Choice><mc:Fallback><w:hyperlink r:id="rIdFallback"><w:r><w:t>Fallback link</w:t></w:r></w:hyperlink></mc:Fallback></mc:AlternateContent></w:p></w:body></w:document>"#,
),
]))
.expect("fixture opens");
assert_eq!(doc.main_text(), "Choice link");
let [Block::Paragraph(paragraph)] = &doc.model().blocks[..] else {
panic!("expected one paragraph");
};
let [run] = ¶graph.runs[..] else {
panic!("expected one hyperlink run");
};
assert!(matches!(
&run.field,
FieldRole::Hyperlink { url } if url == "https://example.com/choice"
));
assert_eq!(doc.report().features.hyperlinks, 1);
}
#[test]
fn docx_hyperlink_container_uses_computed_complex_field_text() {
let doc = Document::open(&docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/_rels/document.xml.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rIdLink" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink" Target="https://example.com/computed" TargetMode="External"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"><w:body><w:p><w:hyperlink r:id="rIdLink"><w:r><w:fldChar w:fldCharType="begin"/></w:r><w:r><w:instrText> QUOTE "Computed link" </w:instrText></w:r><w:r><w:fldChar w:fldCharType="separate"/></w:r><w:r><w:t>stale link</w:t></w:r><w:r><w:fldChar w:fldCharType="end"/></w:r></w:hyperlink></w:p></w:body></w:document>"#,
),
]))
.expect("fixture opens");
assert_eq!(doc.main_text(), "Computed link");
let [Block::Paragraph(paragraph)] = &doc.model().blocks[..] else {
panic!("expected one paragraph");
};
let [run] = ¶graph.runs[..] else {
panic!("expected one computed hyperlink run");
};
assert_eq!(run.text, "Computed link");
assert!(matches!(
&run.field,
FieldRole::Hyperlink { url } if url == "https://example.com/computed"
));
assert_eq!(doc.report().features.hyperlinks, 1);
}
#[test]
fn docx_simple_hyperlink_anchor_field_uses_bookmark_url() {
let doc = Document::open(&docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:bookmarkStart w:id="7" w:name="TargetBookmark"/><w:r><w:t>Target</w:t></w:r><w:bookmarkEnd w:id="7"/></w:p><w:p><w:fldSimple w:instr=" HYPERLINK \l "TargetBookmark" "><w:r><w:t>Jump</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
]))
.expect("fixture opens");
assert_eq!(doc.main_text(), "Target\nJump");
let [Block::Paragraph(_), Block::Paragraph(paragraph)] = &doc.model().blocks[..] else {
panic!("expected target and hyperlink paragraphs");
};
let [run] = ¶graph.runs[..] else {
panic!("expected one hyperlink run");
};
assert_eq!(run.text, "Jump");
assert!(matches!(
&run.field,
FieldRole::Hyperlink { url } if url == "#TargetBookmark"
));
assert_eq!(doc.report().features.hyperlinks, 1);
assert!(doc.report().features.unsupported_field_reasons.is_empty());
}
#[test]
fn docx_hyperlink_field_accepts_noop_switches() {
let doc = Document::open(&docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:fldSimple w:instr=" HYPERLINK "https://example.com/no-history" \n "><w:r><w:t>No history</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" HYPERLINK "https://example.com/no-frame" \m "><w:r><w:t>No frame</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" HYPERLINK "https://example.com/full" \m \n \o "tip" \t NewWindow "><w:r><w:t>Full link</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" HYPERLINK "https://example.com/bad" \n "extra" "><w:r><w:t>Bad tail</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
]))
.expect("fixture opens");
assert_eq!(doc.main_text(), "No history\nNo frame\nFull link\nBad tail");
let fields = doc.fields();
assert_eq!(fields.len(), 4);
assert!(fields
.iter()
.all(|field| field.kind == FieldKind::Hyperlink));
let report = doc.report();
assert_eq!(report.features.fields, 4);
assert_eq!(report.features.hyperlinks, 4);
assert_eq!(
report.features.unsupported_field_kinds,
vec![FieldKindCount {
kind: FieldKind::Hyperlink,
count: 1,
}]
);
assert_eq!(
report.features.unsupported_field_reasons,
vec![FieldEvaluationReasonCount {
reason: FieldEvaluationReason::UnsupportedSwitch,
count: 1,
}]
);
let [Block::Paragraph(no_history), Block::Paragraph(no_frame), Block::Paragraph(full_link), Block::Paragraph(bad_tail)] =
&doc.model().blocks[..]
else {
panic!("expected one paragraph per hyperlink field");
};
let [no_history_run] = &no_history.runs[..] else {
panic!("expected no-history hyperlink run");
};
let [no_frame_run] = &no_frame.runs[..] else {
panic!("expected no-frame hyperlink run");
};
let [full_link_run] = &full_link.runs[..] else {
panic!("expected full hyperlink run");
};
let [bad_tail_run] = &bad_tail.runs[..] else {
panic!("expected malformed hyperlink run");
};
assert!(matches!(
&no_history_run.field,
FieldRole::Hyperlink { url } if url == "https://example.com/no-history"
));
assert!(matches!(
&no_frame_run.field,
FieldRole::Hyperlink { url } if url == "https://example.com/no-frame"
));
assert!(matches!(
&full_link_run.field,
FieldRole::Hyperlink { url } if url == "https://example.com/full"
));
assert!(matches!(
&bad_tail_run.field,
FieldRole::Simple { instruction }
if instruction == r#"HYPERLINK "https://example.com/bad" \n "extra""#
));
assert_eq!(
bad_tail_run.field_unsupported_reason,
Some(FieldUnsupportedReason::UnsupportedSwitch)
);
}
#[test]
fn docx_page_fields_compute_trusted_current_page_numbers() {
let doc = Document::open(&page_field_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 5);
assert_eq!(fields[0].kind, FieldKind::Page);
assert_eq!(fields[0].instruction, "PAGE");
assert_eq!(fields[0].result, "stale restart decimal zero");
assert_eq!(fields[0].computed_result.as_deref(), Some("04"));
assert_eq!(fields[1].kind, FieldKind::Page);
assert_eq!(fields[1].instruction, "PAGE \\* Arabic");
assert_eq!(fields[1].result, "stale restart arabic");
assert_eq!(fields[1].computed_result.as_deref(), Some("4"));
assert_eq!(fields[2].kind, FieldKind::Page);
assert_eq!(fields[2].instruction, "PAGE \\* CardText \\* Upper");
assert_eq!(fields[2].result, "stale restart card upper");
assert_eq!(fields[2].computed_result.as_deref(), Some("FOUR"));
assert_eq!(fields[3].kind, FieldKind::Page);
assert_eq!(fields[3].instruction, "PAGE");
assert_eq!(fields[3].result, "cached ambiguous page");
assert_eq!(fields[3].computed_result, None);
assert_eq!(fields[4].kind, FieldKind::Page);
assert_eq!(fields[4].instruction, "PAGE \\* roman");
assert_eq!(fields[4].result, "stale rendered roman page");
assert_eq!(fields[4].computed_result.as_deref(), Some("v"));
let main_text = doc.main_text();
assert!(
main_text.contains("04")
&& main_text.contains("4")
&& main_text.contains("FOUR")
&& main_text.contains("cached ambiguous page")
&& main_text.contains("v"),
"computed trusted PAGE fields and cached ambiguous PAGE field should appear in main text: {main_text:?}"
);
assert!(
!main_text.contains("stale restart decimal zero")
&& !main_text.contains("stale restart arabic")
&& !main_text.contains("stale restart card upper")
&& !main_text.contains("stale rendered roman page"),
"computed PAGE fields should replace stale cached text: {main_text:?}"
);
let report = doc.report();
assert_eq!(
report.features.unsupported_field_kinds,
vec![FieldKindCount {
kind: FieldKind::Page,
count: 1,
}]
);
assert_eq!(
report.features.unsupported_field_reasons,
vec![FieldEvaluationReasonCount {
reason: FieldEvaluationReason::NoComputedResult,
count: 1,
}]
);
assert_eq!(
model_simple_field_reason_hints(&doc, |instruction| instruction == "PAGE"),
vec![(
"PAGE".to_string(),
Some(FieldUnsupportedReason::NoComputedResult),
)]
);
}
#[test]
fn docx_page_field_computes_restarted_section_display_page_after_visible_intro() {
let doc = Document::open(&page_field_visible_intro_section_page_number_restart_docx())
.expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 1);
assert_eq!(fields[0].kind, FieldKind::Page);
assert_eq!(fields[0].instruction, "PAGE");
assert_eq!(fields[0].result, "stale restarted current page");
assert_eq!(fields[0].computed_result.as_deref(), Some("7"));
let main_text = doc.main_text();
assert!(
main_text.contains("7") && !main_text.contains("stale restarted current page"),
"restarted section display page should compute for PAGE fields: {main_text:?}"
);
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
}
#[test]
fn docx_page_field_computes_continuous_section_page_number_restart() {
let doc = Document::open(&page_field_continuous_section_restart_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 1);
assert_eq!(fields[0].kind, FieldKind::Page);
assert_eq!(fields[0].instruction, "PAGE");
assert_eq!(fields[0].result, "stale continuous restart");
assert_eq!(fields[0].computed_result.as_deref(), Some("5"));
let main_text = doc.main_text();
assert!(
main_text.contains("5") && !main_text.contains("stale continuous restart"),
"continuous section pgNumType restart should compute for PAGE fields: {main_text:?}"
);
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
}
#[test]
fn docx_pageref_relative_untrusted_field_resolves_trusted_later_target() {
let doc = Document::open(&page_ref_relative_untrusted_field_trusted_target_docx())
.expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 1);
assert_eq!(fields[0].kind, FieldKind::PageRef);
assert_eq!(fields[0].instruction, "PAGEREF Later \\p");
assert_eq!(fields[0].result, "stale relative ref");
assert_eq!(fields[0].computed_result.as_deref(), Some("on page 2"));
}
#[test]
fn docx_page_field_computes_page_break_before_current_page_after_visible_intro() {
let doc = Document::open(&page_field_page_break_before_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 1);
assert_eq!(fields[0].kind, FieldKind::Page);
assert_eq!(fields[0].instruction, "PAGE \\* Arabic");
assert_eq!(fields[0].result, "stale break-before page");
assert_eq!(fields[0].computed_result.as_deref(), Some("2"));
let main_text = doc.main_text();
assert!(
main_text.contains("2") && !main_text.contains("stale break-before page"),
"pageBreakBefore PAGE fields should use the explicit paragraph break: {main_text:?}"
);
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
}
#[test]
fn docx_empty_section_type_defaults_to_next_page_for_page_accounting() {
let doc = Document::open(&empty_section_type_page_accounting_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 2);
assert_eq!(fields[0].kind, FieldKind::Page);
assert_eq!(fields[0].instruction, "PAGE");
assert_eq!(fields[0].result, "stale page");
assert_eq!(fields[0].computed_result.as_deref(), Some("2"));
assert_eq!(fields[1].kind, FieldKind::PageRef);
assert_eq!(fields[1].instruction, "PAGEREF DefaultTyped \\h");
assert_eq!(fields[1].result, "stale ref");
assert_eq!(fields[1].computed_result.as_deref(), Some("2"));
let main_text = doc.main_text();
assert!(
main_text.contains("2")
&& !main_text.contains("stale page")
&& !main_text.contains("stale ref"),
"empty section type should use the default next-page break: {main_text:?}"
);
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
}
#[test]
fn docx_disabled_page_break_before_does_not_set_paragraph_break_flag() {
let doc = Document::open(&disabled_page_break_before_docx()).expect("fixture opens");
let [Block::Paragraph(paragraph)] = &doc.model().blocks[..] else {
panic!("expected one paragraph");
};
assert!(!paragraph.props.page_break_before);
}
#[test]
fn docx_page_fields_follow_accepted_wrappers_and_single_alternate_branch() {
let doc = Document::open(&wrapped_page_field_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 2);
assert_eq!(fields[0].instruction, "PAGE \\* Arabic");
assert_eq!(fields[0].computed_result.as_deref(), Some("2"));
assert_eq!(fields[1].instruction, "PAGE \\* Ordinal");
assert_eq!(fields[1].computed_result.as_deref(), Some("3rd"));
let main_text = doc.main_text();
assert!(
main_text.contains("2") && main_text.contains("3rd"),
"computed PAGE fields should be materialized in accepted/current text: {main_text:?}"
);
assert!(
!main_text.contains("stale inserted page") && !main_text.contains("stale alternate page"),
"computed PAGE fields should replace stale cached text: {main_text:?}"
);
assert!(doc.report().features.unsupported_field_kinds.is_empty());
}
#[test]
fn docx_merge_fields_are_named_field_kind() {
let doc = Document::open(&merge_field_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 2);
assert_eq!(fields[0].kind, FieldKind::MergeField);
assert_eq!(
fields[0].instruction,
"MERGEFIELD client-name \\* MERGEFORMAT"
);
assert_eq!(fields[0].result, "Acme");
assert_eq!(fields[1].kind, FieldKind::MergeField);
assert_eq!(
fields[1].instruction,
"MERGEFIELD \"project-name\" \\* MERGEFORMAT"
);
assert_eq!(fields[1].result, "Roadmap");
}
#[test]
fn docx_merge_field_diagnostics_reject_missing_name_before_format_tail() {
let doc = Document::open(&docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:fldSimple w:instr=" MERGEFIELD ClientName \* MERGEFORMAT "><w:r><w:t>Acme</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" MERGEFIELD \* MERGEFORMAT ClientName "><w:r><w:t>cached missing merge name</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
]))
.expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 2);
assert_eq!(fields[0].kind, FieldKind::MergeField);
assert_eq!(
fields[0].instruction,
"MERGEFIELD ClientName \\* MERGEFORMAT"
);
assert_eq!(fields[1].kind, FieldKind::MergeField);
assert_eq!(
fields[1].instruction,
"MERGEFIELD \\* MERGEFORMAT ClientName"
);
let report = doc.report();
assert_eq!(
report.features.unsupported_field_kinds,
vec![FieldKindCount {
kind: FieldKind::MergeField,
count: 1,
}]
);
assert_eq!(
report.features.unsupported_field_reasons,
vec![FieldEvaluationReasonCount {
reason: FieldEvaluationReason::UnsupportedSwitch,
count: 1,
}]
);
assert_eq!(
model_simple_field_reason_hints(&doc, |instruction| {
instruction.starts_with("MERGEFIELD")
}),
vec![
("MERGEFIELD ClientName \\* MERGEFORMAT".to_string(), None),
(
"MERGEFIELD \\* MERGEFORMAT ClientName".to_string(),
Some(FieldUnsupportedReason::UnsupportedSwitch),
),
]
);
assert!(doc.main_text().contains("cached missing merge name"));
}
#[test]
fn docx_merge_field_diagnostics_validate_common_switch_tails() {
let doc = Document::open(&docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:fldSimple w:instr=" MERGEFIELD ClientName \b "Before " \f " After" \* MERGEFORMAT "><w:r><w:t>Client cached</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" MERGEFIELD Client Name \f suffix text "><w:r><w:t>Project cached</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" MERGEFIELD ClientName \b "><w:r><w:t>cached missing before text</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" MERGEFIELD ClientName \x "><w:r><w:t>cached unknown merge switch</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
]))
.expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 4);
assert!(fields
.iter()
.all(|field| field.kind == FieldKind::MergeField));
assert_eq!(
fields[0].instruction,
r#"MERGEFIELD ClientName \b "Before " \f " After" \* MERGEFORMAT"#
);
assert_eq!(fields[0].computed_result, None);
assert_eq!(
fields[1].instruction,
"MERGEFIELD Client Name \\f suffix text"
);
assert_eq!(fields[1].computed_result, None);
assert_eq!(fields[2].instruction, "MERGEFIELD ClientName \\b");
assert_eq!(fields[2].computed_result, None);
assert_eq!(fields[3].instruction, "MERGEFIELD ClientName \\x");
assert_eq!(fields[3].computed_result, None);
let report = doc.report();
assert_eq!(
report.features.unsupported_field_kinds,
vec![FieldKindCount {
kind: FieldKind::MergeField,
count: 2,
}]
);
assert_eq!(
report.features.unsupported_field_reasons,
vec![FieldEvaluationReasonCount {
reason: FieldEvaluationReason::UnsupportedSwitch,
count: 2,
}]
);
assert_eq!(
model_simple_field_reason_hints(&doc, |instruction| {
instruction.starts_with("MERGEFIELD")
}),
vec![
(
r#"MERGEFIELD ClientName \b "Before " \f " After" \* MERGEFORMAT"#.to_string(),
None,
),
("MERGEFIELD Client Name \\f suffix text".to_string(), None),
(
"MERGEFIELD ClientName \\b".to_string(),
Some(FieldUnsupportedReason::UnsupportedSwitch),
),
(
"MERGEFIELD ClientName \\x".to_string(),
Some(FieldUnsupportedReason::UnsupportedSwitch),
),
]
);
let main_text = doc.main_text();
assert!(
main_text.contains("Client cached")
&& main_text.contains("Project cached")
&& main_text.contains("cached missing before text")
&& main_text.contains("cached unknown merge switch"),
"MERGEFIELD diagnostics should preserve cached display text: {main_text:?}"
);
}
#[test]
fn docx_sequence_fields_compute_source_order_numbers() {
let doc = Document::open(&sequence_field_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 10);
assert_eq!(fields[0].kind, FieldKind::Sequence);
assert_eq!(fields[0].instruction, "SEQ Figure");
assert_eq!(fields[0].result, "stale figure one");
assert_eq!(fields[0].computed_result.as_deref(), Some("1"));
assert_eq!(fields[1].kind, FieldKind::Sequence);
assert_eq!(fields[1].instruction, "SEQ Figure");
assert_eq!(fields[1].computed_result.as_deref(), Some("2"));
assert_eq!(fields[2].kind, FieldKind::Sequence);
assert_eq!(fields[2].instruction, "SEQ Figure \\r 7");
assert_eq!(fields[2].computed_result.as_deref(), Some("7"));
assert_eq!(fields[3].kind, FieldKind::Sequence);
assert_eq!(fields[3].instruction, "SEQ Figure \\c");
assert_eq!(fields[3].computed_result.as_deref(), Some("7"));
assert_eq!(fields[4].kind, FieldKind::Sequence);
assert_eq!(fields[4].instruction, "SEQ Figure \\h");
assert_eq!(fields[4].computed_result.as_deref(), Some(""));
assert_eq!(fields[5].kind, FieldKind::Sequence);
assert_eq!(fields[5].instruction, "SEQ Figure");
assert_eq!(fields[5].computed_result.as_deref(), Some("9"));
assert_eq!(fields[6].kind, FieldKind::Sequence);
assert_eq!(fields[6].instruction, "SEQ Figure \\r -1");
assert_eq!(fields[6].result, "cached invalid reset");
assert_eq!(fields[6].computed_result, None);
assert_eq!(fields[7].kind, FieldKind::Sequence);
assert_eq!(fields[7].instruction, "SEQ Figure");
assert_eq!(fields[7].computed_result.as_deref(), Some("10"));
assert_eq!(fields[8].kind, FieldKind::Sequence);
assert_eq!(fields[8].instruction, "SEQ Appendix \\* roman");
assert_eq!(fields[8].computed_result.as_deref(), Some("i"));
assert_eq!(fields[9].kind, FieldKind::Sequence);
assert_eq!(fields[9].instruction, "SEQ Appendix \\r 31 \\* Hex");
assert_eq!(fields[9].computed_result.as_deref(), Some("1F"));
let report = doc.report();
assert_eq!(
report.features.unsupported_field_kinds,
vec![FieldKindCount {
kind: FieldKind::Sequence,
count: 1,
}]
);
assert_eq!(
report.features.unsupported_field_reasons,
vec![FieldEvaluationReasonCount {
reason: FieldEvaluationReason::UnsupportedSwitch,
count: 1,
}]
);
assert_eq!(
model_simple_field_reason_hints(&doc, |instruction| {
instruction.starts_with("SEQ Figure \\r -1")
}),
vec![(
"SEQ Figure \\r -1".to_string(),
Some(FieldUnsupportedReason::UnsupportedSwitch),
)]
);
let main_text = doc.main_text();
assert_eq!(
main_text
.lines()
.filter(|line| !line.is_empty())
.collect::<Vec<_>>(),
vec![
"1",
"2",
"7",
"7",
"9",
"cached invalid reset",
"10",
"i",
"1F",
]
);
assert!(
!main_text.contains("stale figure")
&& !main_text.contains("stale hidden figure")
&& !main_text.contains("stale appendix roman")
&& !main_text.contains("stale appendix hex"),
"computed SEQ field text should replace stale cached text: {main_text:?}"
);
}
#[test]
fn docx_sequence_heading_reset_computes_from_heading_scope() {
let doc = Document::open(&sequence_heading_reset_field_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 4);
assert_eq!(fields[0].kind, FieldKind::Sequence);
assert_eq!(fields[0].instruction, "SEQ Figure \\s 1");
assert_eq!(fields[0].result, "stale chapter one figure");
assert_eq!(fields[0].computed_result.as_deref(), Some("1"));
assert_eq!(fields[1].kind, FieldKind::Sequence);
assert_eq!(fields[1].instruction, "SEQ Figure");
assert_eq!(fields[1].result, "stale chapter one followup");
assert_eq!(fields[1].computed_result.as_deref(), Some("2"));
assert_eq!(fields[2].kind, FieldKind::Sequence);
assert_eq!(fields[2].instruction, "SEQ Figure \\s 1");
assert_eq!(fields[2].result, "stale chapter two figure");
assert_eq!(fields[2].computed_result.as_deref(), Some("1"));
assert_eq!(fields[3].kind, FieldKind::Sequence);
assert_eq!(fields[3].instruction, "SEQ Figure \\s1 \\* roman");
assert_eq!(fields[3].result, "stale chapter two roman");
assert_eq!(fields[3].computed_result.as_deref(), Some("ii"));
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
assert!(model_simple_field_reason_hints(&doc, |instruction| {
instruction.starts_with("SEQ Figure")
})
.is_empty());
assert_eq!(
doc.main_text()
.lines()
.filter(|line| !line.is_empty())
.collect::<Vec<_>>(),
vec!["Chapter One", "1", "2", "Chapter Two", "1", "ii"]
);
}
#[test]
fn docx_sequence_heading_reset_from_heading_paragraph_scope() {
let doc =
Document::open(&sequence_heading_paragraph_reset_field_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 3);
assert!(fields.iter().all(|field| field.kind == FieldKind::Sequence));
assert_eq!(fields[0].instruction, "SEQ Figure \\s 1");
assert_eq!(fields[0].result, "stale heading one figure");
assert_eq!(fields[0].computed_result.as_deref(), Some("1"));
assert_eq!(fields[1].instruction, "SEQ Figure \\s 1");
assert_eq!(fields[1].result, "stale chapter one followup");
assert_eq!(fields[1].computed_result.as_deref(), Some("2"));
assert_eq!(fields[2].instruction, "SEQ Figure \\s 1");
assert_eq!(fields[2].result, "stale heading two figure");
assert_eq!(fields[2].computed_result.as_deref(), Some("1"));
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
assert_eq!(
doc.main_text()
.lines()
.filter(|line| !line.is_empty())
.collect::<Vec<_>>(),
vec!["Chapter One Figure 1", "2", "Chapter Two Figure 1"]
);
}
#[test]
fn docx_sequence_heading_reset_ignores_old_paragraph_property_revisions() {
let doc = Document::open(&sequence_heading_property_revision_reset_field_docx())
.expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 3);
assert!(fields.iter().all(|field| field.kind == FieldKind::Sequence));
assert_eq!(fields[0].instruction, "SEQ Figure \\s 1");
assert_eq!(fields[0].computed_result.as_deref(), Some("1"));
assert_eq!(fields[1].instruction, "SEQ Figure \\s 1");
assert_eq!(fields[1].result, "stale after old heading");
assert_eq!(fields[1].computed_result.as_deref(), Some("2"));
assert_eq!(fields[2].instruction, "SEQ Figure \\s 1");
assert_eq!(fields[2].computed_result.as_deref(), Some("1"));
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
assert_eq!(
doc.main_text()
.lines()
.filter(|line| !line.is_empty())
.collect::<Vec<_>>(),
vec!["1", "Former heading only", "2", "Current Heading", "1"]
);
}
#[test]
fn docx_document_info_fields_are_named_cached_display_fields() {
let doc = Document::open(&document_info_field_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 7);
assert_eq!(fields[0].kind, FieldKind::DocumentInfo("DATE".to_string()));
assert_eq!(fields[0].instruction, "DATE \\@ \"yyyy-MM-dd\"");
assert_eq!(fields[0].result, "2026-06-24");
assert_eq!(fields[0].computed_result, None);
assert_eq!(fields[1].kind, FieldKind::DocumentInfo("TIME".to_string()));
assert_eq!(fields[1].instruction, "TIME \\@ \"HH:mm\"");
assert_eq!(fields[1].result, "14:35");
assert_eq!(fields[1].computed_result, None);
assert_eq!(
fields[2].kind,
FieldKind::DocumentInfo("AUTHOR".to_string())
);
assert_eq!(fields[2].result, "Hyunjo Jung");
assert_eq!(
fields[3].kind,
FieldKind::DocumentInfo("DOCPROPERTY".to_string())
);
assert_eq!(fields[3].result, "Example Co.");
assert_eq!(
fields[4].kind,
FieldKind::DocumentInfo("NUMPAGES".to_string())
);
assert_eq!(fields[4].result, "12");
assert_eq!(
fields[5].kind,
FieldKind::DocumentInfo("EDITTIME".to_string())
);
assert_eq!(fields[5].result, "42");
assert_eq!(
fields[6].kind,
FieldKind::DocumentInfo("DOCPROPERTY".to_string())
);
assert_eq!(fields[6].instruction, "DOCPROPERTY \"Broken Name ");
assert_eq!(fields[6].result, "cached broken property");
assert_eq!(fields[6].computed_result, None);
let report = doc.report();
assert_eq!(
report.features.unsupported_field_kinds,
vec![FieldKindCount {
kind: FieldKind::DocumentInfo("DOCPROPERTY".to_string()),
count: 1,
}]
);
assert_eq!(
report.features.unsupported_field_reasons,
vec![FieldEvaluationReasonCount {
reason: FieldEvaluationReason::UnsupportedSwitch,
count: 1,
}]
);
assert_eq!(
model_simple_field_reason_hints(&doc, |instruction| {
instruction.starts_with("DOCPROPERTY")
}),
vec![
("DOCPROPERTY \"Company\"".to_string(), None),
(
"DOCPROPERTY \"Broken Name ".to_string(),
Some(FieldUnsupportedReason::UnsupportedSwitch),
),
]
);
let main_text = doc.main_text();
assert!(
main_text.contains("2026-06-24")
&& main_text.contains("14:35")
&& main_text.contains("Hyunjo Jung")
&& main_text.contains("Example Co.")
&& main_text.contains("12")
&& main_text.contains("42")
&& main_text.contains("cached broken property"),
"document-info fields should preserve cached display text: {main_text:?}"
);
}
#[test]
fn docx_filename_field_diagnostics_reject_unknown_switch() {
let doc = Document::open(&docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:fldSimple w:instr=" FILENAME \p "><w:r><w:t>report.docx</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" FILENAME \x "><w:r><w:t>cached filename</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
]))
.expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 2);
assert!(fields.iter().all(|field| field.kind == FieldKind::Filename));
assert_eq!(fields[0].instruction, "FILENAME \\p");
assert_eq!(fields[1].instruction, "FILENAME \\x");
let report = doc.report();
assert_eq!(
report.features.unsupported_field_kinds,
vec![FieldKindCount {
kind: FieldKind::Filename,
count: 1,
}]
);
assert_eq!(
report.features.unsupported_field_reasons,
vec![FieldEvaluationReasonCount {
reason: FieldEvaluationReason::UnsupportedSwitch,
count: 1,
}]
);
assert_eq!(
model_simple_field_reason_hints(&doc, |instruction| {
instruction.starts_with("FILENAME")
}),
vec![
("FILENAME \\p".to_string(), None),
(
"FILENAME \\x".to_string(),
Some(FieldUnsupportedReason::UnsupportedSwitch),
),
]
);
assert!(doc.main_text().contains("cached filename"));
}
#[test]
fn docx_file_size_fields_compute_unit_switches_from_package_size() {
let fixture = file_size_switch_field_docx();
let expected_bytes = fixture.len().to_string();
let expected_kilobytes = ((fixture.len() + 500) / 1_000).to_string();
let expected_megabytes = ((fixture.len() + 500_000) / 1_000_000).to_string();
let doc = Document::open(&fixture).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 3);
for field in &fields {
assert_eq!(field.kind, FieldKind::DocumentInfo("FILESIZE".to_string()));
}
assert_eq!(fields[0].instruction, "FILESIZE");
assert_eq!(
fields[0].computed_result.as_deref(),
Some(expected_bytes.as_str())
);
assert_eq!(fields[1].instruction, "FILESIZE \\k");
assert_eq!(
fields[1].computed_result.as_deref(),
Some(expected_kilobytes.as_str())
);
assert_eq!(fields[2].instruction, "FILESIZE \\m");
assert_eq!(
fields[2].computed_result.as_deref(),
Some(expected_megabytes.as_str())
);
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
let main_text = doc.main_text();
assert!(
!main_text.contains("stale bytes")
&& !main_text.contains("stale kilobytes")
&& !main_text.contains("stale megabytes"),
"computed FILESIZE fields should replace stale cached text: {main_text:?}"
);
}
#[test]
fn docx_user_info_fields_compute_explicit_literal_overrides() {
let doc = Document::open(&user_info_field_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 9);
assert_eq!(
fields[0].kind,
FieldKind::DocumentInfo("USERNAME".to_string())
);
assert_eq!(fields[0].instruction, "USERNAME");
assert_eq!(fields[0].result, "cached user name");
assert_eq!(fields[0].computed_result, None);
assert_eq!(
fields[1].kind,
FieldKind::DocumentInfo("USERINITIALS".to_string())
);
assert_eq!(fields[1].instruction, "USERINITIALS");
assert_eq!(fields[1].result, "cached initials");
assert_eq!(fields[1].computed_result, None);
assert_eq!(
fields[2].kind,
FieldKind::DocumentInfo("USERADDRESS".to_string())
);
assert_eq!(fields[2].instruction, "USERADDRESS");
assert_eq!(fields[2].result, "cached address");
assert_eq!(fields[2].computed_result, None);
assert_eq!(
fields[3].instruction,
"USERNAME \"Casey Reviewer\" \\* Upper"
);
assert_eq!(fields[3].result, "stale override name");
assert_eq!(fields[3].computed_result.as_deref(), Some("CASEY REVIEWER"));
assert_eq!(fields[4].instruction, "USERINITIALS \"cr\" \\* Upper");
assert_eq!(fields[4].result, "stale override initials");
assert_eq!(fields[4].computed_result.as_deref(), Some("CR"));
assert_eq!(
fields[5].instruction,
"USERADDRESS \"Review desk, Seoul\" \\* Upper"
);
assert_eq!(fields[5].result, "stale override address");
assert_eq!(
fields[5].computed_result.as_deref(),
Some("REVIEW DESK, SEOUL")
);
assert_eq!(fields[6].instruction, "USERNAME Casey Reviewer \\* Upper");
assert_eq!(fields[6].result, "stale unquoted name");
assert_eq!(fields[6].computed_result.as_deref(), Some("CASEY REVIEWER"));
assert_eq!(
fields[7].instruction,
"USERINITIALS casey reviewer \\* Upper"
);
assert_eq!(fields[7].result, "stale unquoted initials");
assert_eq!(fields[7].computed_result.as_deref(), Some("CASEY REVIEWER"));
assert_eq!(
fields[8].instruction,
"USERADDRESS Review desk Seoul \\* Upper"
);
assert_eq!(fields[8].result, "stale unquoted address");
assert_eq!(
fields[8].computed_result.as_deref(),
Some("REVIEW DESK SEOUL")
);
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
let main_text = doc.main_text();
assert!(
main_text.contains("cached user name")
&& main_text.contains("cached initials")
&& main_text.contains("cached address")
&& main_text.contains("CASEY REVIEWER")
&& main_text.contains("CR")
&& main_text.contains("REVIEW DESK, SEOUL")
&& main_text.contains("REVIEW DESK SEOUL"),
"cached user-info fields and computed literal overrides should appear in main text: {main_text:?}"
);
assert!(
!main_text.contains("stale override name")
&& !main_text.contains("stale override initials")
&& !main_text.contains("stale override address")
&& !main_text.contains("stale unquoted name")
&& !main_text.contains("stale unquoted initials")
&& !main_text.contains("stale unquoted address"),
"computed user-info overrides should replace stale cached text: {main_text:?}"
);
}
#[test]
fn docx_document_info_user_override_accepts_compact_format_switch() {
let doc = Document::open(&user_info_compact_format_field_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 1);
assert_eq!(
fields[0].kind,
FieldKind::DocumentInfo("USERNAME".to_string())
);
assert_eq!(
fields[0].instruction,
"USERNAME \"Casey Reviewer\" \\*Upper"
);
assert_eq!(fields[0].result, "stale compact user");
assert_eq!(fields[0].computed_result.as_deref(), Some("CASEY REVIEWER"));
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
let main_text = doc.main_text();
assert!(
main_text.contains("CASEY REVIEWER") && !main_text.contains("stale compact user"),
"compact user-info format should replace stale cached text: {main_text:?}"
);
}
#[test]
fn docx_document_info_fields_compute_package_properties_when_available() {
let fixture = document_info_package_properties_field_docx();
let expected_file_size = fixture.len().to_string();
let doc = Document::open(&fixture).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 46);
assert_eq!(
doc.model()
.custom_properties
.get("Client Name")
.map(String::as_str),
Some("acme launch")
);
assert_eq!(fields[0].kind, FieldKind::DocumentInfo("TITLE".to_string()));
assert_eq!(fields[0].result, "stale title");
assert_eq!(fields[0].computed_result.as_deref(), Some("Quarter Plan"));
assert_eq!(
fields[1].kind,
FieldKind::DocumentInfo("AUTHOR".to_string())
);
assert_eq!(fields[1].computed_result.as_deref(), Some("Hyunjo Jung"));
assert_eq!(fields[2].kind, FieldKind::DocumentInfo("INFO".to_string()));
assert_eq!(fields[2].computed_result.as_deref(), Some("QUARTER PLAN"));
assert_eq!(
fields[3].kind,
FieldKind::DocumentInfo("DOCPROPERTY".to_string())
);
assert_eq!(fields[3].computed_result.as_deref(), Some("LAUNCH"));
assert_eq!(
fields[4].kind,
FieldKind::DocumentInfo("DOCPROPERTY".to_string())
);
assert_eq!(fields[4].computed_result.as_deref(), Some("Field coverage"));
assert_eq!(
fields[5].kind,
FieldKind::DocumentInfo("DOCPROPERTY".to_string())
);
assert_eq!(fields[5].computed_result.as_deref(), Some("rwml,fields"));
assert_eq!(
fields[6].kind,
FieldKind::DocumentInfo("DOCPROPERTY".to_string())
);
assert_eq!(fields[6].computed_result.as_deref(), Some("Operations"));
assert_eq!(fields[7].kind, FieldKind::DocumentInfo("INFO".to_string()));
assert_eq!(fields[7].computed_result.as_deref(), Some("Draft"));
assert_eq!(
fields[8].kind,
FieldKind::DocumentInfo("DOCPROPERTY".to_string())
);
assert_eq!(fields[8].computed_result.as_deref(), Some("1.2"));
assert_eq!(
fields[9].kind,
FieldKind::DocumentInfo("DOCPROPERTY".to_string())
);
assert_eq!(fields[9].computed_result.as_deref(), Some("Acme Launch"));
assert_eq!(
fields[10].kind,
FieldKind::DocumentInfo("DOCPROPERTY".to_string())
);
assert_eq!(fields[10].computed_result.as_deref(), Some("7"));
assert_eq!(
fields[11].kind,
FieldKind::DocumentInfo("DOCVARIABLE".to_string())
);
assert_eq!(fields[11].computed_result.as_deref(), Some("ALPHA-42"));
assert_eq!(
fields[12].kind,
FieldKind::DocumentInfo("CREATEDATE".to_string())
);
assert_eq!(
fields[12].computed_result.as_deref(),
Some("Monday, June 1, 2026")
);
assert_eq!(
fields[13].kind,
FieldKind::DocumentInfo("SAVEDATE".to_string())
);
assert_eq!(
fields[13].computed_result.as_deref(),
Some("Jun 02, 2026 03:04:05")
);
assert_eq!(
fields[14].kind,
FieldKind::DocumentInfo("PRINTDATE".to_string())
);
assert_eq!(
fields[14].computed_result.as_deref(),
Some("26-6-3 4:05 AM")
);
assert_eq!(
fields[15].kind,
FieldKind::DocumentInfo("NUMPAGES".to_string())
);
assert_eq!(fields[15].computed_result.as_deref(), Some("12"));
assert_eq!(
fields[16].kind,
FieldKind::DocumentInfo("NUMWORDS".to_string())
);
assert_eq!(fields[16].computed_result.as_deref(), Some("321"));
assert_eq!(
fields[17].kind,
FieldKind::DocumentInfo("NUMCHARS".to_string())
);
assert_eq!(fields[17].computed_result.as_deref(), Some("2048"));
assert_eq!(
fields[18].kind,
FieldKind::DocumentInfo("EDITTIME".to_string())
);
assert_eq!(fields[18].computed_result.as_deref(), Some("42"));
assert_eq!(
fields[19].kind,
FieldKind::DocumentInfo("TEMPLATE".to_string())
);
assert_eq!(fields[19].computed_result.as_deref(), Some("NORMAL.DOTM"));
assert_eq!(
fields[20].kind,
FieldKind::DocumentInfo("DOCPROPERTY".to_string())
);
assert_eq!(fields[20].computed_result.as_deref(), Some("12"));
assert_eq!(fields[21].kind, FieldKind::DocumentInfo("INFO".to_string()));
assert_eq!(fields[21].computed_result.as_deref(), Some("321"));
assert_eq!(
fields[22].kind,
FieldKind::DocumentInfo("DOCPROPERTY".to_string())
);
assert_eq!(fields[22].computed_result.as_deref(), Some("2500"));
assert_eq!(fields[23].kind, FieldKind::DocumentInfo("INFO".to_string()));
assert_eq!(fields[23].computed_result.as_deref(), Some("42"));
assert_eq!(
fields[24].kind,
FieldKind::DocumentInfo("DOCPROPERTY".to_string())
);
assert_eq!(fields[24].computed_result.as_deref(), Some("EXAMPLE CO"));
assert_eq!(fields[25].kind, FieldKind::DocumentInfo("INFO".to_string()));
assert_eq!(fields[25].computed_result.as_deref(), Some("Document Lead"));
assert_eq!(
fields[26].kind,
FieldKind::DocumentInfo("LASTSAVEDBY".to_string())
);
assert_eq!(fields[26].computed_result.as_deref(), Some("Reviewer"));
assert_eq!(
fields[27].kind,
FieldKind::DocumentInfo("CATEGORY".to_string())
);
assert_eq!(fields[27].computed_result.as_deref(), Some("OPERATIONS"));
assert_eq!(
fields[28].kind,
FieldKind::DocumentInfo("CONTENTSTATUS".to_string())
);
assert_eq!(fields[28].computed_result.as_deref(), Some("Draft"));
assert_eq!(
fields[29].kind,
FieldKind::DocumentInfo("VERSION".to_string())
);
assert_eq!(fields[29].computed_result.as_deref(), Some("1.2"));
assert_eq!(
fields[30].kind,
FieldKind::DocumentInfo("DOCPROPERTY".to_string())
);
assert_eq!(
fields[30].computed_result.as_deref(),
Some("https://docs.example/base/")
);
assert_eq!(fields[31].kind, FieldKind::DocumentInfo("INFO".to_string()));
assert_eq!(fields[31].computed_result.as_deref(), Some("4"));
assert_eq!(
fields[32].kind,
FieldKind::DocumentInfo("DOCPROPERTY".to_string())
);
assert_eq!(fields[32].computed_result.as_deref(), Some("true"));
assert_eq!(
fields[33].kind,
FieldKind::DocumentInfo("CREATOR".to_string())
);
assert_eq!(fields[33].computed_result.as_deref(), Some("HYUNJO JUNG"));
assert_eq!(
fields[34].kind,
FieldKind::DocumentInfo("DESCRIPTION".to_string())
);
assert_eq!(
fields[34].computed_result.as_deref(),
Some("FIELD COVERAGE")
);
assert_eq!(
fields[35].kind,
FieldKind::DocumentInfo("KEYWORD".to_string())
);
assert_eq!(fields[35].computed_result.as_deref(), Some("RWML,FIELDS"));
assert_eq!(
fields[36].kind,
FieldKind::DocumentInfo("LASTMODIFIEDBY".to_string())
);
assert_eq!(fields[36].computed_result.as_deref(), Some("REVIEWER"));
assert_eq!(
fields[37].kind,
FieldKind::DocumentInfo("APPLICATION".to_string())
);
assert_eq!(
fields[37].computed_result.as_deref(),
Some("RWML FIELD ENGINE")
);
assert_eq!(
fields[38].kind,
FieldKind::DocumentInfo("APPVERSION".to_string())
);
assert_eq!(fields[38].computed_result.as_deref(), Some("16.0000"));
assert_eq!(
fields[39].kind,
FieldKind::DocumentInfo("MANAGER".to_string())
);
assert_eq!(fields[39].computed_result.as_deref(), Some("DOCUMENT LEAD"));
assert_eq!(
fields[40].kind,
FieldKind::DocumentInfo("COMPANY".to_string())
);
assert_eq!(fields[40].computed_result.as_deref(), Some("EXAMPLE CO"));
assert_eq!(
fields[41].kind,
FieldKind::DocumentInfo("HYPERLINKBASE".to_string())
);
assert_eq!(
fields[41].computed_result.as_deref(),
Some("https://docs.example/base/")
);
assert_eq!(
fields[42].kind,
FieldKind::DocumentInfo("DOCSECURITY".to_string())
);
assert_eq!(fields[42].computed_result.as_deref(), Some("4"));
assert_eq!(
fields[43].kind,
FieldKind::DocumentInfo("LINKSUPTODATE".to_string())
);
assert_eq!(fields[43].computed_result.as_deref(), Some("true"));
assert_eq!(
fields[44].kind,
FieldKind::DocumentInfo("DOCPROPERTY".to_string())
);
assert_eq!(
fields[44].instruction,
r#"DOCPROPERTY "Review Date" \@ "MMM d, yyyy""#
);
assert_eq!(fields[44].result, "stale review date");
assert_eq!(fields[44].computed_result.as_deref(), Some("Jun 15, 2026"));
assert_eq!(
fields[45].kind,
FieldKind::DocumentInfo("FILESIZE".to_string())
);
assert_eq!(fields[45].instruction, "FILESIZE");
assert_eq!(fields[45].result, "stale file size");
assert_eq!(
fields[45].computed_result.as_deref(),
Some(expected_file_size.as_str())
);
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
let main_text = doc.main_text();
assert!(
main_text.contains("Quarter Plan")
&& main_text.contains("Hyunjo Jung")
&& main_text.contains("QUARTER PLAN")
&& main_text.contains("LAUNCH")
&& main_text.contains("Field coverage")
&& main_text.contains("rwml,fields")
&& main_text.contains("Operations")
&& main_text.contains("Draft")
&& main_text.contains("1.2")
&& main_text.contains("Acme Launch")
&& main_text.contains("7")
&& main_text.contains("ALPHA-42")
&& main_text.contains("Monday, June 1, 2026")
&& main_text.contains("Jun 02, 2026 03:04:05")
&& main_text.contains("26-6-3 4:05 AM")
&& main_text.contains("12")
&& main_text.contains("321")
&& main_text.contains("2048")
&& main_text.contains("42")
&& main_text.contains("NORMAL.DOTM")
&& main_text.contains("2500")
&& main_text.contains("EXAMPLE CO")
&& main_text.contains("Document Lead")
&& main_text.contains("Reviewer")
&& main_text.contains("OPERATIONS")
&& main_text.contains("https://docs.example/base/")
&& main_text.contains("true")
&& main_text.contains("HYUNJO JUNG")
&& main_text.contains("FIELD COVERAGE")
&& main_text.contains("RWML,FIELDS")
&& main_text.contains("REVIEWER")
&& main_text.contains("RWML FIELD ENGINE")
&& main_text.contains("16.0000")
&& main_text.contains("DOCUMENT LEAD")
&& main_text.matches("EXAMPLE CO").count() >= 2
&& main_text.matches("https://docs.example/base/").count() >= 2
&& main_text.matches("true").count() >= 2
&& main_text.contains("Jun 15, 2026")
&& main_text.contains(&expected_file_size),
"computed package property field text should appear in main text: {main_text:?}"
);
assert!(
!main_text.contains("stale title")
&& !main_text.contains("stale author")
&& !main_text.contains("stale info title")
&& !main_text.contains("stale subject")
&& !main_text.contains("stale comments")
&& !main_text.contains("stale keywords")
&& !main_text.contains("stale category")
&& !main_text.contains("stale content status")
&& !main_text.contains("stale version")
&& !main_text.contains("stale client")
&& !main_text.contains("stale score")
&& !main_text.contains("stale variable")
&& !main_text.contains("stale created date")
&& !main_text.contains("stale saved date")
&& !main_text.contains("stale print date")
&& !main_text.contains("stale pages")
&& !main_text.contains("stale words")
&& !main_text.contains("stale chars")
&& !main_text.contains("stale edit time")
&& !main_text.contains("stale template")
&& !main_text.contains("stale docproperty pages")
&& !main_text.contains("stale info words")
&& !main_text.contains("stale chars with spaces")
&& !main_text.contains("stale info total time")
&& !main_text.contains("stale company")
&& !main_text.contains("stale manager")
&& !main_text.contains("stale editor")
&& !main_text.contains("stale direct category")
&& !main_text.contains("stale direct content status")
&& !main_text.contains("stale direct version")
&& !main_text.contains("stale hyperlink base")
&& !main_text.contains("stale doc security")
&& !main_text.contains("stale links up to date")
&& !main_text.contains("stale creator alias")
&& !main_text.contains("stale description alias")
&& !main_text.contains("stale keyword alias")
&& !main_text.contains("stale modified alias")
&& !main_text.contains("stale application")
&& !main_text.contains("stale app version")
&& !main_text.contains("stale direct manager")
&& !main_text.contains("stale direct company")
&& !main_text.contains("stale direct hyperlink base")
&& !main_text.contains("stale direct doc security")
&& !main_text.contains("stale direct links up to date")
&& !main_text.contains("stale review date")
&& !main_text.contains("stale file size"),
"computed package property field text should replace stale cached text: {main_text:?}"
);
}
#[test]
fn docx_document_info_property_accepts_compact_format_switch() {
let doc = Document::open(&document_info_compact_property_format_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 1);
assert_eq!(
fields[0].kind,
FieldKind::DocumentInfo("DOCPROPERTY".to_string())
);
assert_eq!(fields[0].instruction, r#"DOCPROPERTY "Client Name" \*Caps"#);
assert_eq!(fields[0].result, "stale compact property");
assert_eq!(fields[0].computed_result.as_deref(), Some("Acme Launch"));
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
let main_text = doc.main_text();
assert!(
main_text.contains("Acme Launch") && !main_text.contains("stale compact property"),
"compact property format should replace stale cached text: {main_text:?}"
);
}
#[test]
fn docx_document_info_accepts_unquoted_multi_token_names() {
let doc =
Document::open(&document_info_unquoted_multi_token_names_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 2);
assert_eq!(
fields[0].kind,
FieldKind::DocumentInfo("DOCPROPERTY".to_string())
);
assert_eq!(fields[0].instruction, r#"DOCPROPERTY Client Name \* Caps"#);
assert_eq!(fields[0].result, "stale client");
assert_eq!(fields[0].computed_result.as_deref(), Some("Acme Launch"));
assert_eq!(
fields[1].kind,
FieldKind::DocumentInfo("DOCVARIABLE".to_string())
);
assert_eq!(fields[1].instruction, r#"DOCVARIABLE Client Code \* Upper"#);
assert_eq!(fields[1].result, "stale variable");
assert_eq!(fields[1].computed_result.as_deref(), Some("ALPHA-42"));
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
}
#[test]
fn docx_document_info_variable_accepts_compact_format_switch() {
let doc = Document::open(&document_info_compact_variable_format_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 1);
assert_eq!(
fields[0].kind,
FieldKind::DocumentInfo("DOCVARIABLE".to_string())
);
assert_eq!(fields[0].instruction, r#"DOCVARIABLE ClientCode \*Upper"#);
assert_eq!(fields[0].result, "stale compact variable");
assert_eq!(fields[0].computed_result.as_deref(), Some("ALPHA-42"));
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
let main_text = doc.main_text();
assert!(
main_text.contains("ALPHA-42") && !main_text.contains("stale compact variable"),
"compact variable format should replace stale cached text: {main_text:?}"
);
}
#[test]
fn docx_document_info_compact_date_format_switch_computes() {
let doc = Document::open(&document_info_compact_date_format_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 1);
assert_eq!(
fields[0].kind,
FieldKind::DocumentInfo("CREATEDATE".to_string())
);
assert_eq!(fields[0].instruction, r#"CREATEDATE \@"yyyy-MM-dd""#);
assert_eq!(fields[0].result, "stale compact date");
assert_eq!(fields[0].computed_result.as_deref(), Some("2026-06-01"));
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
let main_text = doc.main_text();
assert!(
main_text.contains("2026-06-01") && !main_text.contains("stale compact date"),
"compact date format should replace stale cached text: {main_text:?}"
);
}
#[test]
fn docx_document_info_date_picture_accepts_unquoted_literal_tokens() {
let doc = Document::open(&document_info_unquoted_date_picture_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 1);
assert_eq!(
fields[0].kind,
FieldKind::DocumentInfo("CREATEDATE".to_string())
);
assert_eq!(
fields[0].instruction,
r#"CREATEDATE \@ MMMM d, yyyy \* Upper"#
);
assert_eq!(fields[0].result, "stale unquoted date picture");
assert_eq!(fields[0].computed_result.as_deref(), Some("JUNE 1, 2026"));
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
let main_text = doc.main_text();
assert!(
main_text.contains("JUNE 1, 2026") && !main_text.contains("stale unquoted date picture"),
"unquoted multi-token date picture should replace stale cached text: {main_text:?}"
);
}
#[test]
fn docx_dynamic_fields_compute_formula_quote_if_compare_and_literal_set_ref() {
let doc = Document::open(&dynamic_field_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 24);
assert_eq!(fields[0].kind, FieldKind::Dynamic("=".to_string()));
assert_eq!(fields[0].instruction, "= (2 + 3) * 4");
assert_eq!(fields[0].result, "stale formula");
assert_eq!(fields[0].computed_result.as_deref(), Some("20"));
assert_eq!(fields[1].kind, FieldKind::Dynamic("=".to_string()));
assert_eq!(fields[1].instruction, r#"= 10 / 4 \# "0.00""#);
assert_eq!(fields[1].result, "stale formatted formula");
assert_eq!(fields[1].computed_result.as_deref(), Some("2.50"));
assert_eq!(fields[2].kind, FieldKind::Dynamic("IF".to_string()));
assert_eq!(fields[2].result, "stale true");
assert_eq!(fields[2].computed_result.as_deref(), Some("yes"));
assert_eq!(fields[3].kind, FieldKind::Dynamic("IF".to_string()));
assert_eq!(fields[3].result, "stale false");
assert_eq!(fields[3].computed_result.as_deref(), Some("no"));
assert_eq!(fields[4].kind, FieldKind::Dynamic("IF".to_string()));
assert_eq!(fields[4].result, "stale compact");
assert_eq!(fields[4].computed_result.as_deref(), Some("big"));
assert_eq!(fields[5].kind, FieldKind::Dynamic("COMPARE".to_string()));
assert_eq!(fields[5].result, "stale compare true");
assert_eq!(fields[5].computed_result.as_deref(), Some("1"));
assert_eq!(fields[6].kind, FieldKind::Dynamic("COMPARE".to_string()));
assert_eq!(fields[6].result, "stale compare wildcard");
assert_eq!(fields[6].computed_result.as_deref(), Some("1"));
assert_eq!(fields[7].kind, FieldKind::Dynamic("COMPARE".to_string()));
assert_eq!(fields[7].result, "stale compare false");
assert_eq!(fields[7].computed_result.as_deref(), Some("0"));
assert_eq!(fields[8].kind, FieldKind::Dynamic("QUOTE".to_string()));
assert_eq!(fields[8].result, "literal");
assert_eq!(fields[8].computed_result.as_deref(), Some("literal"));
assert_eq!(fields[9].kind, FieldKind::Dynamic("FILLIN".to_string()));
assert_eq!(fields[9].result, "Acme");
assert_eq!(fields[9].computed_result, None);
assert_eq!(fields[10].kind, FieldKind::Dynamic("ASK".to_string()));
assert_eq!(fields[10].instruction, "ASK ClientCode \"Client code?\"");
assert_eq!(fields[10].result, "cached ask");
assert_eq!(fields[10].computed_result, None);
assert_eq!(fields[11].kind, FieldKind::Dynamic("SET".to_string()));
assert_eq!(fields[11].instruction, "SET ClientName \"Acme\"");
assert_eq!(fields[11].result, "cached set");
assert_eq!(fields[11].computed_result.as_deref(), Some(""));
assert_eq!(fields[12].kind, FieldKind::Ref);
assert_eq!(fields[12].instruction, r#"REF ClientName \* Upper"#);
assert_eq!(fields[12].result, "stale set ref");
assert_eq!(fields[12].computed_result.as_deref(), Some("ACME"));
assert_eq!(fields[13].kind, FieldKind::Dynamic("SET".to_string()));
assert_eq!(
fields[13].instruction,
"SET ClientTier \"Gold\" \\* MERGEFORMAT"
);
assert_eq!(fields[13].result, "cached formatted set");
assert_eq!(fields[13].computed_result.as_deref(), Some(""));
assert_eq!(fields[14].kind, FieldKind::Ref);
assert_eq!(fields[14].instruction, "REF ClientTier");
assert_eq!(fields[14].result, "stale formatted set ref");
assert_eq!(fields[14].computed_result.as_deref(), Some("Gold"));
assert_eq!(fields[15].kind, FieldKind::Dynamic("SET".to_string()));
assert_eq!(fields[15].instruction, "SET ClientCode Client-42");
assert_eq!(fields[15].result, "cached unsupported set");
assert_eq!(fields[15].computed_result.as_deref(), Some(""));
assert_eq!(fields[16].kind, FieldKind::Dynamic("NEXT".to_string()));
assert_eq!(fields[16].instruction, "NEXT");
assert_eq!(fields[16].computed_result.as_deref(), Some(""));
assert_eq!(fields[17].kind, FieldKind::Dynamic("NEXTIF".to_string()));
assert_eq!(fields[17].instruction, "NEXTIF 1 = 1");
assert_eq!(fields[17].computed_result.as_deref(), Some(""));
assert_eq!(fields[18].kind, FieldKind::Dynamic("SKIPIF".to_string()));
assert_eq!(fields[18].instruction, "SKIPIF 1 = 0");
assert_eq!(fields[18].computed_result.as_deref(), Some(""));
assert_eq!(fields[19].kind, FieldKind::Dynamic("IF".to_string()));
assert_eq!(
fields[19].instruction,
"IF 1e2 = 100 \"scientific\" \"bad\""
);
assert_eq!(fields[19].result, "stale scientific if");
assert_eq!(fields[19].computed_result.as_deref(), Some("scientific"));
assert_eq!(fields[20].kind, FieldKind::Dynamic("COMPARE".to_string()));
assert_eq!(fields[20].instruction, "COMPARE 1e309 > 0");
assert_eq!(fields[20].result, "cached nonfinite compare");
assert_eq!(fields[20].computed_result, None);
assert_eq!(fields[21].kind, FieldKind::Dynamic("NEXTIF".to_string()));
assert_eq!(fields[21].instruction, "NEXTIF City = \"Tokyo\"");
assert_eq!(fields[21].result, "cached unsupported nextif");
assert_eq!(fields[21].computed_result, None);
assert_eq!(fields[22].kind, FieldKind::Dynamic("FILLIN".to_string()));
assert_eq!(fields[22].instruction, "FILLIN \"broken prompt ");
assert_eq!(fields[22].result, "cached broken fillin");
assert_eq!(fields[22].computed_result, None);
assert_eq!(fields[23].kind, FieldKind::Dynamic("NEXTIF".to_string()));
assert_eq!(fields[23].instruction, "NEXTIF 1 =");
assert_eq!(fields[23].result, "cached broken nextif");
assert_eq!(fields[23].computed_result, None);
let report = doc.report();
assert_eq!(
report.features.unsupported_field_kinds,
vec![
FieldKindCount {
kind: FieldKind::Dynamic("FILLIN".to_string()),
count: 2,
},
FieldKindCount {
kind: FieldKind::Dynamic("ASK".to_string()),
count: 1,
},
FieldKindCount {
kind: FieldKind::Dynamic("COMPARE".to_string()),
count: 1,
},
FieldKindCount {
kind: FieldKind::Dynamic("NEXTIF".to_string()),
count: 2,
},
]
);
assert_eq!(
report.features.unsupported_field_reasons,
vec![
FieldEvaluationReasonCount {
reason: FieldEvaluationReason::NoComputedResult,
count: 3,
},
FieldEvaluationReasonCount {
reason: FieldEvaluationReason::UnsupportedSwitch,
count: 3,
},
]
);
assert_eq!(
model_simple_field_reason_hints(&doc, |instruction| {
instruction.starts_with("FILLIN")
|| instruction.starts_with("ASK")
|| instruction.starts_with("COMPARE 1e309")
|| instruction.starts_with("NEXTIF")
}),
vec![
(
r#"FILLIN "Client?""#.to_string(),
Some(FieldUnsupportedReason::NoComputedResult),
),
(
r#"ASK ClientCode "Client code?""#.to_string(),
Some(FieldUnsupportedReason::NoComputedResult),
),
(
"COMPARE 1e309 > 0".to_string(),
Some(FieldUnsupportedReason::UnsupportedSwitch),
),
(
r#"NEXTIF City = "Tokyo""#.to_string(),
Some(FieldUnsupportedReason::NoComputedResult),
),
(
r#"FILLIN "broken prompt "#.to_string(),
Some(FieldUnsupportedReason::UnsupportedSwitch),
),
(
"NEXTIF 1 =".to_string(),
Some(FieldUnsupportedReason::UnsupportedSwitch),
),
]
);
let main_text = doc.main_text();
assert!(
main_text.contains("20")
&& main_text.contains("2.50")
&& main_text.contains("yes")
&& main_text.contains("no")
&& main_text.contains("big")
&& main_text.contains("1\n1\n0")
&& main_text.contains("literal")
&& main_text.contains("Acme")
&& main_text.contains("cached ask")
&& main_text.contains("ACME")
&& main_text.contains("Gold")
&& main_text.contains("scientific")
&& main_text.contains("cached nonfinite compare")
&& main_text.contains("cached unsupported nextif")
&& main_text.contains("cached broken fillin")
&& main_text.contains("cached broken nextif"),
"computed/cached dynamic field results should be materialized in main text: {main_text:?}"
);
assert!(
!main_text.contains("stale true")
&& !main_text.contains("stale false")
&& !main_text.contains("stale compact")
&& !main_text.contains("stale compare")
&& !main_text.contains("stale formula")
&& !main_text.contains("stale formatted formula")
&& !main_text.contains("stale scientific if")
&& !main_text.contains("cached set")
&& !main_text.contains("cached formatted set")
&& !main_text.contains("stale formatted set ref")
&& !main_text.contains("cached unsupported set")
&& !main_text.contains("cached next")
&& !main_text.contains("cached nextif")
&& !main_text.contains("cached skipif")
&& !main_text.contains("stale set ref"),
"computed formula/IF/COMPARE results should replace stale cached text: {main_text:?}"
);
}
#[test]
fn docx_if_compare_and_merge_controls_resolve_prior_set_bookmark_operands() {
let doc = Document::open(&set_backed_comparison_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 6);
assert_eq!(fields[0].kind, FieldKind::Dynamic("SET".to_string()));
assert_eq!(fields[0].instruction, "SET ClientTier \"Gold\"");
assert_eq!(fields[0].computed_result.as_deref(), Some(""));
assert_eq!(fields[1].kind, FieldKind::Dynamic("IF".to_string()));
assert_eq!(
fields[1].instruction,
"IF ClientTier = \"Gold\" \"ship\" \"hold\""
);
assert_eq!(fields[1].result, "stale set if");
assert_eq!(fields[1].computed_result.as_deref(), Some("ship"));
assert_eq!(fields[2].kind, FieldKind::Dynamic("COMPARE".to_string()));
assert_eq!(fields[2].instruction, "COMPARE ClientTier = \"Gold\"");
assert_eq!(fields[2].result, "stale set compare");
assert_eq!(fields[2].computed_result.as_deref(), Some("1"));
assert_eq!(fields[3].kind, FieldKind::Dynamic("IF".to_string()));
assert_eq!(fields[3].result, "cached missing if");
assert_eq!(fields[3].computed_result, None);
assert_eq!(fields[4].kind, FieldKind::Dynamic("NEXTIF".to_string()));
assert_eq!(fields[4].result, "cached nextif");
assert_eq!(fields[4].computed_result.as_deref(), Some(""));
assert_eq!(fields[5].kind, FieldKind::Dynamic("SKIPIF".to_string()));
assert_eq!(fields[5].result, "cached skipif");
assert_eq!(fields[5].computed_result.as_deref(), Some(""));
let main_text = doc.main_text();
assert!(
main_text.contains("ship")
&& main_text.contains("1")
&& main_text.contains("cached missing if")
&& !main_text.contains("cached nextif")
&& !main_text.contains("cached skipif")
&& !main_text.contains("stale set if")
&& !main_text.contains("stale set compare"),
"computed SET-backed comparison text should replace stale cached text: {main_text:?}"
);
}
#[test]
fn docx_if_compare_and_merge_controls_resolve_prior_numeric_set_bookmark_operands() {
let doc = Document::open(&set_backed_numeric_comparison_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 7);
assert_eq!(fields[0].kind, FieldKind::Dynamic("SET".to_string()));
assert_eq!(fields[0].instruction, "SET ClientTotal 42");
assert_eq!(fields[0].computed_result.as_deref(), Some(""));
assert_eq!(fields[1].kind, FieldKind::Dynamic("IF".to_string()));
assert_eq!(
fields[1].instruction,
r#"IF ClientTotal = 42 "match" "miss""#
);
assert_eq!(fields[1].result, "stale numeric if");
assert_eq!(fields[1].computed_result.as_deref(), Some("match"));
assert_eq!(fields[2].kind, FieldKind::Dynamic("COMPARE".to_string()));
assert_eq!(fields[2].instruction, "COMPARE ClientTotal >= 40");
assert_eq!(fields[2].result, "stale numeric compare");
assert_eq!(fields[2].computed_result.as_deref(), Some("1"));
assert_eq!(fields[3].kind, FieldKind::Dynamic("NEXTIF".to_string()));
assert_eq!(fields[3].instruction, "NEXTIF ClientTotal = 42");
assert_eq!(fields[3].result, "cached numeric nextif");
assert_eq!(fields[3].computed_result.as_deref(), Some(""));
assert_eq!(fields[4].kind, FieldKind::Dynamic("SKIPIF".to_string()));
assert_eq!(fields[4].instruction, "SKIPIF ClientTotal < 40");
assert_eq!(fields[4].result, "cached numeric skipif");
assert_eq!(fields[4].computed_result.as_deref(), Some(""));
assert_eq!(fields[5].kind, FieldKind::Dynamic("SET".to_string()));
assert_eq!(fields[5].instruction, r#"SET ClientTier "Gold""#);
assert_eq!(fields[5].computed_result.as_deref(), Some(""));
assert_eq!(fields[6].kind, FieldKind::Dynamic("COMPARE".to_string()));
assert_eq!(fields[6].instruction, r#"COMPARE ClientTier = "G*""#);
assert_eq!(fields[6].result, "stale text compare");
assert_eq!(fields[6].computed_result.as_deref(), Some("1"));
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
let main_text = doc.main_text();
assert!(
main_text.contains("match")
&& main_text.contains("1")
&& !main_text.contains("stale numeric if")
&& !main_text.contains("stale numeric compare")
&& !main_text.contains("cached numeric nextif")
&& !main_text.contains("cached numeric skipif")
&& !main_text.contains("stale text compare"),
"computed numeric SET-backed comparison text should replace stale cached text: {main_text:?}"
);
}
#[test]
fn docx_if_and_compare_resolve_document_bookmark_operands() {
let doc = Document::open(&bookmark_backed_comparison_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 7);
assert_eq!(fields[0].kind, FieldKind::Dynamic("IF".to_string()));
assert_eq!(
fields[0].instruction,
r#"IF InvoiceTier = "Gold" "ship" "hold""#
);
assert_eq!(fields[0].result, "stale bookmark if");
assert_eq!(fields[0].computed_result.as_deref(), Some("ship"));
assert_eq!(fields[1].kind, FieldKind::Dynamic("COMPARE".to_string()));
assert_eq!(fields[1].instruction, r#"COMPARE InvoiceTier = "G*""#);
assert_eq!(fields[1].result, "stale bookmark compare");
assert_eq!(fields[1].computed_result.as_deref(), Some("1"));
assert_eq!(fields[2].kind, FieldKind::Dynamic("IF".to_string()));
assert_eq!(
fields[2].instruction,
r#"IF InvoiceTotal >= 40 "match" "miss""#
);
assert_eq!(fields[2].result, "stale numeric bookmark if");
assert_eq!(fields[2].computed_result.as_deref(), Some("match"));
assert_eq!(fields[3].kind, FieldKind::Dynamic("COMPARE".to_string()));
assert_eq!(fields[3].instruction, "COMPARE InvoiceTotal < 40");
assert_eq!(fields[3].result, "stale numeric bookmark compare");
assert_eq!(fields[3].computed_result.as_deref(), Some("0"));
assert_eq!(fields[4].kind, FieldKind::Dynamic("IF".to_string()));
assert_eq!(
fields[4].instruction,
r#"IF MissingTier = "Gold" "ship" "hold""#
);
assert_eq!(fields[4].result, "cached missing bookmark if");
assert_eq!(fields[4].computed_result, None);
assert_eq!(fields[5].kind, FieldKind::Dynamic("NEXTIF".to_string()));
assert_eq!(fields[5].instruction, r#"NEXTIF InvoiceTier = "Gold""#);
assert_eq!(fields[5].result, "cached bookmark nextif");
assert_eq!(fields[5].computed_result.as_deref(), Some(""));
assert_eq!(fields[6].kind, FieldKind::Dynamic("SKIPIF".to_string()));
assert_eq!(fields[6].instruction, "SKIPIF InvoiceTotal < 40");
assert_eq!(fields[6].result, "cached bookmark skipif");
assert_eq!(fields[6].computed_result.as_deref(), Some(""));
let report = doc.report();
assert_eq!(
report.features.unsupported_field_kinds,
vec![FieldKindCount {
kind: FieldKind::Dynamic("IF".to_string()),
count: 1,
}]
);
assert_eq!(
report.features.unsupported_field_reasons,
vec![FieldEvaluationReasonCount {
reason: FieldEvaluationReason::NoComputedResult,
count: 1,
}]
);
let main_text = doc.main_text();
assert!(
main_text.contains("Gold\n42\nship\n1\nmatch\n0")
&& main_text.contains("cached missing bookmark if")
&& !main_text.contains("cached bookmark nextif")
&& !main_text.contains("cached bookmark skipif")
&& !main_text.contains("stale bookmark if")
&& !main_text.contains("stale bookmark compare")
&& !main_text.contains("stale numeric bookmark if")
&& !main_text.contains("stale numeric bookmark compare"),
"computed document-bookmark comparisons should replace stale cached text: {main_text:?}"
);
}
#[test]
fn docx_formula_fields_resolve_prior_numeric_set_bookmark_operands() {
let doc = Document::open(&set_backed_formula_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 6);
assert_eq!(fields[0].kind, FieldKind::Dynamic("SET".to_string()));
assert_eq!(fields[0].instruction, "SET ClientTotal 42");
assert_eq!(fields[0].computed_result.as_deref(), Some(""));
assert_eq!(fields[1].kind, FieldKind::Dynamic("=".to_string()));
assert_eq!(fields[1].instruction, "= ClientTotal + 8");
assert_eq!(fields[1].result, "stale set formula");
assert_eq!(fields[1].computed_result.as_deref(), Some("50"));
assert_eq!(fields[2].kind, FieldKind::Dynamic("=".to_string()));
assert_eq!(fields[2].instruction, "= SUM(ClientTotal; 8)");
assert_eq!(fields[2].result, "stale set formula function");
assert_eq!(fields[2].computed_result.as_deref(), Some("50"));
assert_eq!(fields[3].kind, FieldKind::Dynamic("=".to_string()));
assert_eq!(fields[3].instruction, "= MissingTotal + 8");
assert_eq!(fields[3].result, "cached missing formula");
assert_eq!(fields[3].computed_result, None);
assert_eq!(fields[4].kind, FieldKind::Dynamic("SET".to_string()));
assert_eq!(fields[4].instruction, "SET ClientTier \"Gold\"");
assert_eq!(fields[4].computed_result.as_deref(), Some(""));
assert_eq!(fields[5].kind, FieldKind::Dynamic("=".to_string()));
assert_eq!(fields[5].instruction, "= ClientTier + 1");
assert_eq!(fields[5].result, "cached text formula");
assert_eq!(fields[5].computed_result, None);
let main_text = doc.main_text();
assert!(
main_text.contains("50\n50")
&& main_text.contains("cached missing formula")
&& main_text.contains("cached text formula")
&& !main_text.contains("stale set formula"),
"computed SET-backed formula text should replace stale cached text: {main_text:?}"
);
}
#[test]
fn docx_formula_fields_resolve_numeric_document_bookmark_operands() {
let doc = Document::open(&bookmark_backed_formula_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 5);
assert_eq!(fields[0].kind, FieldKind::Dynamic("=".to_string()));
assert_eq!(fields[0].instruction, "= InvoiceSubtotal + 8");
assert_eq!(fields[0].result, "stale bookmark formula");
assert_eq!(fields[0].computed_result.as_deref(), Some("50"));
assert_eq!(fields[1].kind, FieldKind::Dynamic("=".to_string()));
assert_eq!(fields[1].instruction, "= SUM(InvoiceSubtotal; 8)");
assert_eq!(fields[1].result, "stale bookmark formula function");
assert_eq!(fields[1].computed_result.as_deref(), Some("50"));
assert_eq!(fields[2].kind, FieldKind::Dynamic("=".to_string()));
assert_eq!(fields[2].instruction, "= DEFINED(InvoiceSubtotal)");
assert_eq!(fields[2].result, "stale bookmark defined");
assert_eq!(fields[2].computed_result.as_deref(), Some("1"));
assert_eq!(fields[3].kind, FieldKind::Dynamic("=".to_string()));
assert_eq!(fields[3].instruction, "= InvoiceTier + 1");
assert_eq!(fields[3].result, "cached text bookmark formula");
assert_eq!(fields[3].computed_result, None);
assert_eq!(fields[4].kind, FieldKind::Dynamic("=".to_string()));
assert_eq!(fields[4].instruction, "= MissingSubtotal + 1");
assert_eq!(fields[4].result, "cached missing bookmark formula");
assert_eq!(fields[4].computed_result, None);
let report = doc.report();
assert_eq!(
report.features.unsupported_field_kinds,
vec![FieldKindCount {
kind: FieldKind::Dynamic("=".to_string()),
count: 2
}]
);
assert_eq!(
report.features.unsupported_field_reasons,
vec![FieldEvaluationReasonCount {
reason: FieldEvaluationReason::NoComputedResult,
count: 2
}]
);
let main_text = doc.main_text();
assert!(
main_text.contains("42\nGold\n50\n50\n1")
&& main_text.contains("cached text bookmark formula")
&& main_text.contains("cached missing bookmark formula")
&& !main_text.contains("stale bookmark formula")
&& !main_text.contains("stale bookmark formula function")
&& !main_text.contains("stale bookmark defined"),
"computed document-bookmark formula text should replace stale cached text: {main_text:?}"
);
}
#[test]
fn docx_formula_defined_resolves_prior_set_bookmark_names() {
let doc = Document::open(&set_backed_defined_formula_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 5);
assert_eq!(fields[0].kind, FieldKind::Dynamic("SET".to_string()));
assert_eq!(fields[0].instruction, r#"SET ClientTier "Gold""#);
assert_eq!(fields[0].computed_result.as_deref(), Some(""));
assert_eq!(fields[1].kind, FieldKind::Dynamic("=".to_string()));
assert_eq!(fields[1].instruction, r#"= DEFINED(ClientTier)"#);
assert_eq!(fields[1].result, "stale defined text set");
assert_eq!(fields[1].computed_result.as_deref(), Some("1"));
assert_eq!(fields[2].kind, FieldKind::Dynamic("=".to_string()));
assert_eq!(fields[2].instruction, r#"= IF(DEFINED(ClientTier), 7, 9)"#);
assert_eq!(fields[2].result, "stale defined branch");
assert_eq!(fields[2].computed_result.as_deref(), Some("7"));
assert_eq!(fields[3].kind, FieldKind::Dynamic("=".to_string()));
assert_eq!(fields[3].instruction, r#"= DEFINED(MissingTier)"#);
assert_eq!(fields[3].result, "stale missing defined");
assert_eq!(fields[3].computed_result.as_deref(), Some("0"));
assert_eq!(fields[4].kind, FieldKind::Dynamic("=".to_string()));
assert_eq!(fields[4].instruction, r#"= ClientTier + 1"#);
assert_eq!(fields[4].result, "cached text arithmetic");
assert_eq!(fields[4].computed_result, None);
let report = doc.report();
assert_eq!(
report.features.unsupported_field_kinds,
vec![FieldKindCount {
kind: FieldKind::Dynamic("=".to_string()),
count: 1
}]
);
assert_eq!(
report.features.unsupported_field_reasons,
vec![FieldEvaluationReasonCount {
reason: FieldEvaluationReason::NoComputedResult,
count: 1
}]
);
let main_text = doc.main_text();
assert!(
main_text.contains("1\n7\n0")
&& main_text.contains("cached text arithmetic")
&& !main_text.contains("stale defined text set")
&& !main_text.contains("stale defined branch")
&& !main_text.contains("stale missing defined")
&& !main_text.contains("cached text set"),
"DEFINED should detect prior bookmark names while text arithmetic stays cached: {main_text:?}"
);
}
#[test]
fn docx_formula_fields_resolve_bookmark_style_identifier_operands() {
let doc = Document::open(&set_backed_formula_identifier_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 4);
assert_eq!(fields[0].kind, FieldKind::Dynamic("SET".to_string()));
assert_eq!(fields[0].instruction, "SET Client_Total_2026 42");
assert_eq!(fields[0].computed_result.as_deref(), Some(""));
assert_eq!(fields[1].kind, FieldKind::Dynamic("=".to_string()));
assert_eq!(fields[1].instruction, "= Client_Total_2026 + 8");
assert_eq!(fields[1].result, "stale named formula");
assert_eq!(fields[1].computed_result.as_deref(), Some("50"));
assert_eq!(fields[2].kind, FieldKind::Dynamic("SET".to_string()));
assert_eq!(fields[2].instruction, "SET _HiddenTotal9 7");
assert_eq!(fields[2].computed_result.as_deref(), Some(""));
assert_eq!(fields[3].kind, FieldKind::Dynamic("=".to_string()));
assert_eq!(fields[3].instruction, "= _HiddenTotal9 * 2");
assert_eq!(fields[3].result, "stale hidden formula");
assert_eq!(fields[3].computed_result.as_deref(), Some("14"));
let main_text = doc.main_text();
assert!(
main_text.contains("50")
&& main_text.contains("14")
&& !main_text.contains("stale named formula")
&& !main_text.contains("stale hidden formula"),
"computed bookmark-style formula identifiers should replace stale cached text: {main_text:?}"
);
}
#[test]
fn docx_ref_fields_apply_number_formats_to_prior_numeric_set_bookmarks() {
let doc = Document::open(&set_backed_ref_number_format_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 7);
assert_eq!(fields[0].kind, FieldKind::Dynamic("SET".to_string()));
assert_eq!(fields[0].instruction, "SET ClientTotal 21");
assert_eq!(fields[0].computed_result.as_deref(), Some(""));
assert_eq!(fields[1].kind, FieldKind::Ref);
assert_eq!(fields[1].instruction, "REF ClientTotal \\* CardText");
assert_eq!(fields[1].result, "stale cardtext ref");
assert_eq!(fields[1].computed_result.as_deref(), Some("twenty-one"));
assert_eq!(fields[2].kind, FieldKind::Ref);
assert_eq!(fields[2].instruction, "REF ClientTotal \\* Ordinal");
assert_eq!(fields[2].result, "stale ordinal ref");
assert_eq!(fields[2].computed_result.as_deref(), Some("21st"));
assert_eq!(fields[3].kind, FieldKind::Ref);
assert_eq!(
fields[3].instruction,
"REF ClientTotal \\* CardText \\* Upper"
);
assert_eq!(fields[3].result, "stale uppercase cardtext ref");
assert_eq!(fields[3].computed_result.as_deref(), Some("TWENTY-ONE"));
assert_eq!(fields[4].kind, FieldKind::Dynamic("SET".to_string()));
assert_eq!(fields[4].instruction, "SET ClientTier \"Gold\"");
assert_eq!(fields[4].computed_result.as_deref(), Some(""));
assert_eq!(fields[5].kind, FieldKind::Ref);
assert_eq!(fields[5].instruction, "REF ClientTier \\* CardText");
assert_eq!(fields[5].result, "cached text ref");
assert_eq!(fields[5].computed_result, None);
assert_eq!(fields[6].kind, FieldKind::Ref);
assert_eq!(fields[6].instruction, "REF MissingTotal \\* CardText");
assert_eq!(fields[6].result, "cached missing ref");
assert_eq!(fields[6].computed_result, None);
let main_text = doc.main_text();
assert!(
main_text.contains("twenty-one")
&& main_text.contains("21st")
&& main_text.contains("TWENTY-ONE")
&& main_text.contains("cached text ref")
&& main_text.contains("cached missing ref")
&& !main_text.contains("stale cardtext ref")
&& !main_text.contains("stale ordinal ref")
&& !main_text.contains("stale uppercase cardtext ref"),
"computed SET-backed REF number formats should replace stale cached text: {main_text:?}"
);
}
#[test]
fn docx_malformed_if_reports_unsupported_switch_without_flagging_data_dependent_if() {
let doc = Document::open(&if_diagnostics_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 2);
assert_eq!(fields[0].kind, FieldKind::Dynamic("IF".to_string()));
assert_eq!(
fields[0].instruction,
r#"IF CustomerTier = "Gold" "ship" "hold""#
);
assert_eq!(fields[0].computed_result, None);
assert_eq!(fields[1].kind, FieldKind::Dynamic("IF".to_string()));
assert_eq!(fields[1].instruction, "IF 1 =");
assert_eq!(fields[1].computed_result, None);
let report = doc.report();
assert_eq!(
report.features.unsupported_field_kinds,
vec![FieldKindCount {
kind: FieldKind::Dynamic("IF".to_string()),
count: 2,
}]
);
assert_eq!(
report.features.unsupported_field_reasons,
vec![
FieldEvaluationReasonCount {
reason: FieldEvaluationReason::NoComputedResult,
count: 1,
},
FieldEvaluationReasonCount {
reason: FieldEvaluationReason::UnsupportedSwitch,
count: 1,
},
]
);
assert_eq!(
model_simple_field_reason_hints(&doc, |instruction| instruction.starts_with("IF")),
vec![
(
r#"IF CustomerTier = "Gold" "ship" "hold""#.to_string(),
Some(FieldUnsupportedReason::NoComputedResult),
),
(
"IF 1 =".to_string(),
Some(FieldUnsupportedReason::UnsupportedSwitch),
),
]
);
let main_text = doc.main_text();
assert!(
main_text.contains("cached data if") && main_text.contains("cached broken if"),
"uncomputed IF fields should preserve cached text: {main_text:?}"
);
}
#[test]
fn docx_malformed_compare_reports_unsupported_switch_without_flagging_data_compare() {
let doc = Document::open(&compare_diagnostics_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 3);
assert_eq!(fields[0].kind, FieldKind::Dynamic("COMPARE".to_string()));
assert_eq!(fields[0].instruction, r#"COMPARE CustomerTier = "Gold""#);
assert_eq!(fields[0].computed_result, None);
assert_eq!(fields[1].kind, FieldKind::Dynamic("COMPARE".to_string()));
assert_eq!(fields[1].instruction, "COMPARE 1e309 > 0");
assert_eq!(fields[1].computed_result, None);
assert_eq!(fields[2].kind, FieldKind::Dynamic("COMPARE".to_string()));
assert_eq!(fields[2].instruction, r#"COMPARE \o = "Gold""#);
assert_eq!(fields[2].computed_result, None);
let report = doc.report();
assert_eq!(
report.features.unsupported_field_kinds,
vec![FieldKindCount {
kind: FieldKind::Dynamic("COMPARE".to_string()),
count: 3,
}]
);
assert_eq!(
report.features.unsupported_field_reasons,
vec![
FieldEvaluationReasonCount {
reason: FieldEvaluationReason::NoComputedResult,
count: 1,
},
FieldEvaluationReasonCount {
reason: FieldEvaluationReason::UnsupportedSwitch,
count: 2,
},
]
);
assert_eq!(
model_simple_field_reason_hints(&doc, |instruction| instruction.starts_with("COMPARE")),
vec![
(
r#"COMPARE CustomerTier = "Gold""#.to_string(),
Some(FieldUnsupportedReason::NoComputedResult),
),
(
"COMPARE 1e309 > 0".to_string(),
Some(FieldUnsupportedReason::UnsupportedSwitch),
),
(
r#"COMPARE \o = "Gold""#.to_string(),
Some(FieldUnsupportedReason::UnsupportedSwitch),
),
]
);
let main_text = doc.main_text();
assert!(
main_text.contains("cached data compare")
&& main_text.contains("cached nonfinite compare")
&& main_text.contains("cached switch compare"),
"uncomputed COMPARE fields should preserve cached text: {main_text:?}"
);
}
#[test]
fn docx_malformed_formula_picture_reports_unsupported_switch_without_flagging_data_formula() {
let doc = Document::open(&formula_diagnostics_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 2);
assert_eq!(fields[0].kind, FieldKind::Dynamic("=".to_string()));
assert_eq!(fields[0].instruction, r#"= CustomerTotal \# "0.00""#);
assert_eq!(fields[0].computed_result, None);
assert_eq!(fields[1].kind, FieldKind::Dynamic("=".to_string()));
assert_eq!(fields[1].instruction, r#"= 1 \# "0.00 "#);
assert_eq!(fields[1].computed_result, None);
let report = doc.report();
assert_eq!(
report.features.unsupported_field_kinds,
vec![FieldKindCount {
kind: FieldKind::Dynamic("=".to_string()),
count: 2,
}]
);
assert_eq!(
report.features.unsupported_field_reasons,
vec![
FieldEvaluationReasonCount {
reason: FieldEvaluationReason::NoComputedResult,
count: 1,
},
FieldEvaluationReasonCount {
reason: FieldEvaluationReason::UnsupportedSwitch,
count: 1,
},
]
);
assert_eq!(
model_simple_field_reason_hints(&doc, |instruction| instruction.starts_with('=')),
vec![
(
r#"= CustomerTotal \# "0.00""#.to_string(),
Some(FieldUnsupportedReason::NoComputedResult),
),
(
r#"= 1 \# "0.00 "#.to_string(),
Some(FieldUnsupportedReason::UnsupportedSwitch),
),
]
);
let main_text = doc.main_text();
assert!(
main_text.contains("cached data formula") && main_text.contains("cached broken formula"),
"uncomputed formula fields should preserve cached text: {main_text:?}"
);
}
#[test]
fn docx_malformed_set_reports_unsupported_switch_without_flagging_unquoted_value_set() {
let doc = Document::open(&set_diagnostics_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 2);
assert_eq!(fields[0].kind, FieldKind::Dynamic("SET".to_string()));
assert_eq!(fields[0].instruction, "SET ClientName Client 42");
assert_eq!(fields[0].computed_result.as_deref(), Some(""));
assert_eq!(fields[1].kind, FieldKind::Dynamic("SET".to_string()));
assert_eq!(fields[1].instruction, r#"SET ClientName "Acme "#);
assert_eq!(fields[1].computed_result, None);
let report = doc.report();
assert_eq!(
report.features.unsupported_field_kinds,
vec![FieldKindCount {
kind: FieldKind::Dynamic("SET".to_string()),
count: 1,
}]
);
assert_eq!(
report.features.unsupported_field_reasons,
vec![FieldEvaluationReasonCount {
reason: FieldEvaluationReason::UnsupportedSwitch,
count: 1,
}]
);
assert_eq!(
model_simple_field_reason_hints(&doc, |instruction| instruction.starts_with("SET")),
vec![(
r#"SET ClientName "Acme "#.to_string(),
Some(FieldUnsupportedReason::UnsupportedSwitch),
),]
);
let main_text = doc.main_text();
assert!(
!main_text.contains("cached unquoted set") && main_text.contains("cached broken set"),
"computed SET fields should render hidden output and malformed SET fields should preserve cached text: {main_text:?}"
);
}
#[test]
fn docx_prompt_fields_compute_explicit_defaults() {
let doc = Document::open(&prompt_default_field_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 7);
assert_eq!(fields[0].kind, FieldKind::Dynamic("FILLIN".to_string()));
assert_eq!(fields[0].instruction, r#"FILLIN "Client?" \d "Acme""#);
assert_eq!(fields[0].result, "stale fillin");
assert_eq!(fields[0].computed_result.as_deref(), Some("Acme"));
assert_eq!(fields[1].kind, FieldKind::Dynamic("FILLIN".to_string()));
assert_eq!(
fields[1].instruction,
r#"FILLIN "Department?" \d "ops" \* Upper"#
);
assert_eq!(fields[1].result, "stale formatted fillin");
assert_eq!(fields[1].computed_result.as_deref(), Some("OPS"));
assert_eq!(fields[2].kind, FieldKind::Dynamic("ASK".to_string()));
assert_eq!(
fields[2].instruction,
r#"ASK ClientCode "Client code?" \d "ac-42" \o"#
);
assert_eq!(fields[2].result, "cached ask default");
assert_eq!(fields[2].computed_result.as_deref(), Some(""));
assert_eq!(fields[3].kind, FieldKind::Ref);
assert_eq!(fields[3].instruction, r#"REF ClientCode \* Upper"#);
assert_eq!(fields[3].result, "stale ask ref");
assert_eq!(fields[3].computed_result.as_deref(), Some("AC-42"));
assert_eq!(fields[4].kind, FieldKind::Dynamic("FILLIN".to_string()));
assert_eq!(
fields[4].instruction,
r#"FILLIN "Project?" \d Client 42 \* Upper"#
);
assert_eq!(fields[4].result, "stale multi-token fillin");
assert_eq!(fields[4].computed_result.as_deref(), Some("CLIENT 42"));
assert_eq!(fields[5].kind, FieldKind::Dynamic("ASK".to_string()));
assert_eq!(
fields[5].instruction,
r#"ASK ClientName "Client name?" \d Client 42 \o"#
);
assert_eq!(fields[5].result, "cached multi-token ask default");
assert_eq!(fields[5].computed_result.as_deref(), Some(""));
assert_eq!(fields[6].kind, FieldKind::Ref);
assert_eq!(fields[6].instruction, r#"REF ClientName \* Upper"#);
assert_eq!(fields[6].result, "stale multi-token ask ref");
assert_eq!(fields[6].computed_result.as_deref(), Some("CLIENT 42"));
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
let main_text = doc.main_text();
assert!(
main_text.contains("Acme")
&& main_text.contains("OPS")
&& main_text.contains("AC-42")
&& main_text.contains("CLIENT 42"),
"computed prompt defaults should appear in main text: {main_text:?}"
);
assert!(
!main_text.contains("stale fillin")
&& !main_text.contains("stale formatted fillin")
&& !main_text.contains("cached ask default")
&& !main_text.contains("stale ask ref")
&& !main_text.contains("stale multi-token fillin")
&& !main_text.contains("cached multi-token ask default")
&& !main_text.contains("stale multi-token ask ref"),
"computed prompt defaults should replace stale cached text: {main_text:?}"
);
}
#[test]
fn docx_prompt_fields_accept_unquoted_multi_token_prompt_text() {
let doc = Document::open(&prompt_unquoted_multi_token_text_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 3);
assert_eq!(fields[0].kind, FieldKind::Dynamic("FILLIN".to_string()));
assert_eq!(
fields[0].instruction,
r#"FILLIN Client display prompt \d Acme Corp \* Upper"#
);
assert_eq!(fields[0].result, "stale unquoted prompt fillin");
assert_eq!(fields[0].computed_result.as_deref(), Some("ACME CORP"));
assert_eq!(fields[1].kind, FieldKind::Dynamic("ASK".to_string()));
assert_eq!(
fields[1].instruction,
r#"ASK ClientName Client name prompt \d Acme Corp"#
);
assert_eq!(fields[1].result, "cached unquoted prompt ask");
assert_eq!(fields[1].computed_result.as_deref(), Some(""));
assert_eq!(fields[2].kind, FieldKind::Ref);
assert_eq!(fields[2].instruction, r#"REF ClientName \* Upper"#);
assert_eq!(fields[2].result, "stale unquoted prompt ask ref");
assert_eq!(fields[2].computed_result.as_deref(), Some("ACME CORP"));
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
let main_text = doc.main_text();
assert!(
main_text.contains("ACME CORP")
&& !main_text.contains("stale unquoted prompt fillin")
&& !main_text.contains("cached unquoted prompt ask")
&& !main_text.contains("stale unquoted prompt ask ref"),
"unquoted multi-token prompt text should parse before explicit defaults: {main_text:?}"
);
}
#[test]
fn docx_prompt_fields_accept_unquoted_multi_token_prompt_text_without_defaults() {
let doc =
Document::open(&prompt_unquoted_multi_token_text_no_default_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 3);
assert_eq!(fields[0].kind, FieldKind::Dynamic("FILLIN".to_string()));
assert_eq!(fields[0].instruction, "FILLIN Client display prompt");
assert_eq!(fields[0].result, "cached unquoted prompt fillin");
assert_eq!(fields[0].computed_result, None);
assert_eq!(fields[1].kind, FieldKind::Dynamic("ASK".to_string()));
assert_eq!(fields[1].instruction, "ASK ClientName Client name prompt");
assert_eq!(fields[1].result, "cached unquoted prompt ask");
assert_eq!(fields[1].computed_result, None);
assert_eq!(fields[2].kind, FieldKind::Ref);
assert_eq!(fields[2].instruction, r#"REF ClientName \* Upper"#);
assert_eq!(fields[2].result, "stale unquoted prompt ask ref");
assert_eq!(fields[2].computed_result, None);
let report = doc.report();
assert_eq!(
report.features.unsupported_field_reasons,
vec![
FieldEvaluationReasonCount {
reason: FieldEvaluationReason::NoComputedResult,
count: 2,
},
FieldEvaluationReasonCount {
reason: FieldEvaluationReason::UnresolvedBookmark,
count: 1,
},
]
);
assert_eq!(
model_simple_field_reason_hints(&doc, |instruction| {
instruction.starts_with("FILLIN")
|| instruction.starts_with("ASK")
|| instruction.starts_with("REF ClientName")
}),
vec![
(
"FILLIN Client display prompt".to_string(),
Some(FieldUnsupportedReason::NoComputedResult),
),
(
"ASK ClientName Client name prompt".to_string(),
Some(FieldUnsupportedReason::NoComputedResult),
),
(
r#"REF ClientName \* Upper"#.to_string(),
Some(FieldUnsupportedReason::UnresolvedBookmark),
),
]
);
assert_eq!(
doc.main_text(),
"cached unquoted prompt fillin\ncached unquoted prompt ask\nstale unquoted prompt ask ref"
);
}
#[test]
fn docx_prompt_fields_compute_compact_explicit_defaults() {
let doc = Document::open(&compact_prompt_default_field_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 3);
assert_eq!(fields[0].kind, FieldKind::Dynamic("FILLIN".to_string()));
assert_eq!(fields[0].instruction, r#"FILLIN "Client?" \d"Acme""#);
assert_eq!(fields[0].result, "stale compact fillin");
assert_eq!(fields[0].computed_result.as_deref(), Some("Acme"));
assert_eq!(fields[1].kind, FieldKind::Dynamic("ASK".to_string()));
assert_eq!(
fields[1].instruction,
r#"ASK ClientCode "Client code?" \d"ac-42""#
);
assert_eq!(fields[1].result, "cached compact ask");
assert_eq!(fields[1].computed_result.as_deref(), Some(""));
assert_eq!(fields[2].kind, FieldKind::Ref);
assert_eq!(fields[2].instruction, r#"REF ClientCode \* Upper"#);
assert_eq!(fields[2].result, "stale compact ask ref");
assert_eq!(fields[2].computed_result.as_deref(), Some("AC-42"));
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
let main_text = doc.main_text();
assert!(
main_text.contains("Acme") && main_text.contains("AC-42"),
"computed compact prompt defaults should appear in main text: {main_text:?}"
);
assert!(
!main_text.contains("stale compact fillin")
&& !main_text.contains("cached compact ask")
&& !main_text.contains("stale compact ask ref"),
"computed compact prompt defaults should replace stale cached text: {main_text:?}"
);
}
#[test]
fn docx_unquoted_single_token_set_fields_feed_later_refs() {
let doc = Document::open(&unquoted_set_field_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 4);
assert_eq!(fields[0].kind, FieldKind::Dynamic("SET".to_string()));
assert_eq!(fields[0].instruction, "SET ClientCode Client-42");
assert_eq!(fields[0].result, "cached set");
assert_eq!(fields[0].computed_result.as_deref(), Some(""));
assert_eq!(fields[1].kind, FieldKind::Ref);
assert_eq!(fields[1].instruction, r#"REF ClientCode \* Upper"#);
assert_eq!(fields[1].result, "stale ref");
assert_eq!(fields[1].computed_result.as_deref(), Some("CLIENT-42"));
assert_eq!(fields[2].kind, FieldKind::Dynamic("SET".to_string()));
assert_eq!(fields[2].instruction, "SET ClientName Client 42");
assert_eq!(fields[2].result, "cached multi-token set");
assert_eq!(fields[2].computed_result.as_deref(), Some(""));
assert_eq!(fields[3].kind, FieldKind::Ref);
assert_eq!(fields[3].instruction, r#"REF ClientName \* Upper"#);
assert_eq!(fields[3].result, "stale multi-token ref");
assert_eq!(fields[3].computed_result.as_deref(), Some("CLIENT 42"));
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
let main_text = doc.main_text();
assert!(
main_text.contains("CLIENT-42") && main_text.contains("CLIENT 42"),
"unquoted SET payloads should feed REF fields: {main_text:?}"
);
assert!(
!main_text.contains("cached set")
&& !main_text.contains("stale ref")
&& !main_text.contains("cached multi-token set")
&& !main_text.contains("stale multi-token ref"),
"computed SET/REF output should replace stale cached text: {main_text:?}"
);
}
#[test]
fn docx_unquoted_single_token_set_fields_feed_later_direct_bookmark_refs() {
let doc = Document::open(&set_backed_direct_ref_field_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 4);
assert_eq!(fields[0].kind, FieldKind::Dynamic("SET".to_string()));
assert_eq!(fields[0].instruction, "SET ClientCode Client-42");
assert_eq!(fields[0].result, "cached set");
assert_eq!(fields[0].computed_result.as_deref(), Some(""));
assert_eq!(fields[1].kind, FieldKind::Ref);
assert_eq!(fields[1].instruction, r#"ClientCode \* Upper"#);
assert_eq!(fields[1].result, "stale direct set ref");
assert_eq!(fields[1].computed_result.as_deref(), Some("CLIENT-42"));
assert_eq!(fields[2].kind, FieldKind::Dynamic("SET".to_string()));
assert_eq!(fields[2].instruction, "SET ClientName Client 42");
assert_eq!(fields[2].result, "cached multi-token set");
assert_eq!(fields[2].computed_result.as_deref(), Some(""));
assert_eq!(fields[3].kind, FieldKind::Ref);
assert_eq!(fields[3].instruction, r#"ClientName \* Upper"#);
assert_eq!(fields[3].result, "stale direct multi-token ref");
assert_eq!(fields[3].computed_result.as_deref(), Some("CLIENT 42"));
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
let main_text = doc.main_text();
assert!(
main_text.contains("CLIENT-42") && main_text.contains("CLIENT 42"),
"unquoted SET payloads should feed direct bookmark refs: {main_text:?}"
);
assert!(
!main_text.contains("cached set")
&& !main_text.contains("stale direct set ref")
&& !main_text.contains("cached multi-token set")
&& !main_text.contains("stale direct multi-token ref"),
"computed SET/direct REF output should replace stale cached text: {main_text:?}"
);
}
#[test]
fn docx_set_backed_direct_ref_gap_model_hint_uses_known_target_reason() {
let doc = Document::open(&set_backed_direct_ref_gap_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 2);
assert_eq!(fields[0].kind, FieldKind::Dynamic("SET".to_string()));
assert_eq!(fields[0].instruction, "SET ClientName Client 42");
assert_eq!(fields[0].computed_result.as_deref(), Some(""));
assert_eq!(fields[1].kind, FieldKind::Ref);
assert_eq!(fields[1].instruction, "ClientName \\f");
assert_eq!(fields[1].result, "cached field-bookmark note ref");
assert_eq!(fields[1].computed_result, None);
assert_eq!(
doc.report().features.unsupported_field_reasons,
vec![FieldEvaluationReasonCount {
reason: FieldEvaluationReason::NoComputedResult,
count: 1,
}]
);
assert_eq!(
model_simple_field_reason_hints(&doc, |instruction| instruction == "ClientName \\f"),
vec![(
"ClientName \\f".to_string(),
Some(FieldUnsupportedReason::NoComputedResult),
)]
);
}
#[test]
fn docx_formula_fields_compute_quoted_literal_numeric_pictures() {
let doc = Document::open(&formula_quoted_literal_picture_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 2);
assert_eq!(fields[0].kind, FieldKind::Dynamic("=".to_string()));
assert_eq!(fields[0].instruction, r##"= 1234 \# "#,##0 'items'""##);
assert_eq!(fields[0].result, "stale items formula");
assert_eq!(fields[0].computed_result.as_deref(), Some("1,234 items"));
assert_eq!(fields[1].kind, FieldKind::Dynamic("=".to_string()));
assert_eq!(fields[1].instruction, r#"= 5 \# "0 'units'""#);
assert_eq!(fields[1].result, "stale units formula");
assert_eq!(fields[1].computed_result.as_deref(), Some("5 units"));
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
let main_text = doc.main_text();
assert!(
main_text.contains("1,234 items")
&& main_text.contains("5 units")
&& !main_text.contains("stale"),
"formula numeric pictures should emit single-quoted literal text: {main_text:?}"
);
}
#[test]
fn docx_formula_fields_compute_sectioned_numeric_pictures() {
let doc = Document::open(&formula_sectioned_numeric_picture_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 3);
assert_eq!(fields[0].kind, FieldKind::Dynamic("=".to_string()));
assert_eq!(
fields[0].instruction,
r#"= 1245.65 \# "$#,##0.00;-$#,##0.00""#
);
assert_eq!(fields[0].result, "stale positive section");
assert_eq!(fields[0].computed_result.as_deref(), Some("$1,245.65"));
assert_eq!(fields[1].kind, FieldKind::Dynamic("=".to_string()));
assert_eq!(
fields[1].instruction,
r#"= 0 - 345.56 \# "$#,##0.00;-$#,##0.00""#
);
assert_eq!(fields[1].result, "stale negative section");
assert_eq!(fields[1].computed_result.as_deref(), Some("-$345.56"));
assert_eq!(fields[2].kind, FieldKind::Dynamic("=".to_string()));
assert_eq!(
fields[2].instruction,
r#"= 0 \# "$#,##0.00;($#,##0.00);$0""#
);
assert_eq!(fields[2].result, "stale zero section");
assert_eq!(fields[2].computed_result.as_deref(), Some("$0"));
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
let main_text = doc.main_text();
assert!(
main_text.contains("$1,245.65")
&& main_text.contains("-$345.56")
&& main_text.contains("$0"),
"computed sectioned numeric pictures should materialize selected sections: {main_text:?}"
);
assert!(
!main_text.contains("stale positive section")
&& !main_text.contains("stale negative section")
&& !main_text.contains("stale zero section"),
"computed sectioned numeric pictures should replace stale cached text: {main_text:?}"
);
}
#[test]
fn docx_formula_fields_compute_numeric_picture_sign_controls() {
let doc = Document::open(&formula_sign_control_numeric_picture_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 4);
assert_eq!(fields[0].kind, FieldKind::Dynamic("=".to_string()));
assert_eq!(fields[0].instruction, r#"= 100 - 90 \# +##"#);
assert_eq!(fields[0].result, "stale plus positive");
assert_eq!(fields[0].computed_result.as_deref(), Some("+10"));
assert_eq!(fields[1].kind, FieldKind::Dynamic("=".to_string()));
assert_eq!(fields[1].instruction, r#"= 90 - 100 \# +##"#);
assert_eq!(fields[1].result, "stale plus negative");
assert_eq!(fields[1].computed_result.as_deref(), Some("-10"));
assert_eq!(fields[2].kind, FieldKind::Dynamic("=".to_string()));
assert_eq!(fields[2].instruction, r#"= 10 - 90 \# -##"#);
assert_eq!(fields[2].result, "stale minus negative");
assert_eq!(fields[2].computed_result.as_deref(), Some("-80"));
assert_eq!(fields[3].kind, FieldKind::Dynamic("=".to_string()));
assert_eq!(fields[3].instruction, r#"= 10 \# -##"#);
assert_eq!(fields[3].result, "stale minus positive");
assert_eq!(fields[3].computed_result.as_deref(), Some(" 10"));
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
let main_text = doc.main_text();
assert!(
main_text.contains("+10")
&& main_text.contains("-10")
&& main_text.contains("-80")
&& main_text.contains("10"),
"computed sign-control numeric pictures should materialize sign-controlled results: {main_text:?}"
);
assert!(
!main_text.contains("stale plus positive")
&& !main_text.contains("stale plus negative")
&& !main_text.contains("stale minus negative")
&& !main_text.contains("stale minus positive"),
"computed sign-control numeric pictures should replace stale cached text: {main_text:?}"
);
}
#[test]
fn docx_formula_fields_compute_literal_numeric_functions() {
let doc = Document::open(&formula_function_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 15);
assert_eq!(fields[0].kind, FieldKind::Dynamic("=".to_string()));
assert_eq!(fields[0].instruction, r#"= ABS(-22)"#);
assert_eq!(fields[0].result, "stale abs");
assert_eq!(fields[0].computed_result.as_deref(), Some("22"));
assert_eq!(fields[1].kind, FieldKind::Dynamic("=".to_string()));
assert_eq!(fields[1].instruction, r#"= SUM(1, 2, 3)"#);
assert_eq!(fields[1].result, "stale sum");
assert_eq!(fields[1].computed_result.as_deref(), Some("6"));
assert_eq!(fields[2].kind, FieldKind::Dynamic("=".to_string()));
assert_eq!(fields[2].instruction, r#"= PRODUCT(2, 3, 4)"#);
assert_eq!(fields[2].result, "stale product");
assert_eq!(fields[2].computed_result.as_deref(), Some("24"));
assert_eq!(fields[3].kind, FieldKind::Dynamic("=".to_string()));
assert_eq!(fields[3].instruction, r#"= MIN(5, -2, 9)"#);
assert_eq!(fields[3].result, "stale min");
assert_eq!(fields[3].computed_result.as_deref(), Some("-2"));
assert_eq!(fields[4].kind, FieldKind::Dynamic("=".to_string()));
assert_eq!(fields[4].instruction, r#"= MAX(5, -2, 9)"#);
assert_eq!(fields[4].result, "stale max");
assert_eq!(fields[4].computed_result.as_deref(), Some("9"));
assert_eq!(fields[5].kind, FieldKind::Dynamic("=".to_string()));
assert_eq!(fields[5].instruction, r#"= ROUND(123.456, 2)"#);
assert_eq!(fields[5].result, "stale round");
assert_eq!(fields[5].computed_result.as_deref(), Some("123.46"));
assert_eq!(fields[6].kind, FieldKind::Dynamic("=".to_string()));
assert_eq!(fields[6].instruction, r#"= INT(5.67)"#);
assert_eq!(fields[6].result, "stale int");
assert_eq!(fields[6].computed_result.as_deref(), Some("5"));
assert_eq!(fields[7].kind, FieldKind::Dynamic("=".to_string()));
assert_eq!(fields[7].instruction, r#"= SIGN(-11)"#);
assert_eq!(fields[7].result, "stale sign");
assert_eq!(fields[7].computed_result.as_deref(), Some("-1"));
assert_eq!(fields[8].kind, FieldKind::Dynamic("=".to_string()));
assert_eq!(fields[8].instruction, r#"= SUM(100, 20) \# "$0""#);
assert_eq!(fields[8].result, "stale formatted function");
assert_eq!(fields[8].computed_result.as_deref(), Some("$120"));
assert_eq!(fields[9].kind, FieldKind::Dynamic("=".to_string()));
assert_eq!(fields[9].instruction, r#"= 2 ^ 3"#);
assert_eq!(fields[9].result, "stale exponent");
assert_eq!(fields[9].computed_result.as_deref(), Some("8"));
assert_eq!(fields[10].kind, FieldKind::Dynamic("=".to_string()));
assert_eq!(fields[10].instruction, r#"= (2 + 1) ^ 3"#);
assert_eq!(fields[10].result, "stale parenthesized exponent");
assert_eq!(fields[10].computed_result.as_deref(), Some("27"));
assert_eq!(fields[11].kind, FieldKind::Dynamic("=".to_string()));
assert_eq!(fields[11].instruction, r#"= ROUND(4 ^ 0.5, 1)"#);
assert_eq!(fields[11].result, "stale fractional exponent");
assert_eq!(fields[11].computed_result.as_deref(), Some("2"));
assert_eq!(fields[12].kind, FieldKind::Dynamic("=".to_string()));
assert_eq!(fields[12].instruction, r#"= 1E3 + 2.5e2"#);
assert_eq!(fields[12].result, "stale scientific sum");
assert_eq!(fields[12].computed_result.as_deref(), Some("1250"));
assert_eq!(fields[13].kind, FieldKind::Dynamic("=".to_string()));
assert_eq!(fields[13].instruction, r#"= ROUND(1.25e-2, 4)"#);
assert_eq!(fields[13].result, "stale scientific fraction");
assert_eq!(fields[13].computed_result.as_deref(), Some("0.0125"));
assert_eq!(fields[14].kind, FieldKind::Dynamic("=".to_string()));
assert_eq!(fields[14].instruction, r#"= 2E+3 / 4"#);
assert_eq!(fields[14].result, "stale signed scientific exponent");
assert_eq!(fields[14].computed_result.as_deref(), Some("500"));
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
let main_text = doc.main_text();
assert!(
[
"22", "6", "24", "-2", "9", "123.46", "5", "-1", "$120", "8", "27", "2", "1250",
"0.0125", "500",
]
.into_iter()
.all(|result| main_text.contains(result)),
"computed literal function results should be materialized in main text: {main_text:?}"
);
assert!(
!main_text.contains("stale"),
"computed literal function results should replace stale cached text: {main_text:?}"
);
}
#[test]
fn docx_formula_fields_compute_additional_literal_functions() {
let doc = Document::open(&formula_additional_function_docx()).expect("fixture opens");
let fields = doc.fields();
let expected = [
(r#"= AVERAGE(2, 4, 6)"#, "stale average", "4"),
(r#"= COUNT(2, 4, 6)"#, "stale count", "3"),
(r#"= MOD(10, 4)"#, "stale mod", "2"),
(r#"= MOD(-3, 2)"#, "stale negative dividend mod", "1"),
(r#"= MOD(3, -2)"#, "stale negative divisor mod", "-1"),
(r#"= MOD(-3, -2)"#, "stale negative both mod", "-1"),
(r#"= TRUE"#, "stale true constant", "1"),
(r#"= FALSE"#, "stale false constant", "0"),
(r#"= AND(1, 2, 3)"#, "stale and true", "1"),
(r#"= AND(1, 0, 3)"#, "stale and false", "0"),
(r#"= OR(0, 0, 7)"#, "stale or true", "1"),
(r#"= NOT(0)"#, "stale not", "1"),
(r#"= IF(0, 10, 20)"#, "stale if false", "20"),
(r#"= IF(OR(0, TRUE), SUM(1, 2), 9)"#, "stale nested if", "3"),
];
assert_eq!(fields.len(), expected.len());
for (field, (instruction, stale, result)) in fields.iter().zip(expected) {
assert_eq!(field.kind, FieldKind::Dynamic("=".to_string()));
assert_eq!(field.instruction, instruction);
assert_eq!(field.result, stale);
assert_eq!(field.computed_result.as_deref(), Some(result));
}
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
let main_text = doc.main_text();
for (_, stale, result) in expected {
assert!(
main_text.contains(result),
"computed literal function result should be materialized in main text: {main_text:?}"
);
assert!(
!main_text.contains(stale),
"computed literal function result should replace stale cached text: {main_text:?}"
);
}
}
#[test]
fn docx_formula_if_short_circuits_unselected_branches() {
let doc = Document::open(&formula_if_short_circuit_docx()).expect("fixture opens");
let fields = doc.fields();
let expected = [
(
r#"= IF(1, 7, MissingTotal + 1)"#,
"stale guarded true",
Some("7"),
),
(
r#"= IF(0, MissingTotal + 1, 9)"#,
"stale guarded false",
Some("9"),
),
(
r#"= IF(DEFINED(MissingTotal), MissingTotal + 1, 3)"#,
"stale defined guard",
Some("3"),
),
(r#"= IF(1; 4; 1 / 0)"#, "stale semicolon guard", Some("4")),
(
r#"= IF(1, MissingTotal + 1, 9)"#,
"cached selected unsupported",
None,
),
];
assert_eq!(fields.len(), expected.len());
for (field, (instruction, stale, result)) in fields.iter().zip(expected) {
assert_eq!(field.kind, FieldKind::Dynamic("=".to_string()));
assert_eq!(field.instruction, instruction);
assert_eq!(field.result, stale);
assert_eq!(field.computed_result.as_deref(), result);
}
let report = doc.report();
assert_eq!(
report.features.unsupported_field_kinds,
vec![FieldKindCount {
kind: FieldKind::Dynamic("=".to_string()),
count: 1
}]
);
assert_eq!(
report.features.unsupported_field_reasons,
vec![FieldEvaluationReasonCount {
reason: FieldEvaluationReason::NoComputedResult,
count: 1
}]
);
let main_text = doc.main_text();
assert!(
main_text.contains("7\n9\n3\n4")
&& main_text.contains("cached selected unsupported")
&& !main_text.contains("stale guarded true")
&& !main_text.contains("stale guarded false")
&& !main_text.contains("stale defined guard")
&& !main_text.contains("stale semicolon guard"),
"IF should compute only the selected branch while unsupported selected branches stay cached: {main_text:?}"
);
}
#[test]
fn docx_formula_fields_compute_semicolon_literal_function_arguments() {
let doc = Document::open(&formula_semicolon_function_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 3);
assert_eq!(fields[0].kind, FieldKind::Dynamic("=".to_string()));
assert_eq!(fields[0].instruction, r#"= SUM(1; 2; 3)"#);
assert_eq!(fields[0].result, "stale semicolon sum");
assert_eq!(fields[0].computed_result.as_deref(), Some("6"));
assert_eq!(fields[1].kind, FieldKind::Dynamic("=".to_string()));
assert_eq!(fields[1].instruction, r#"= IF(OR(0; TRUE); SUM(1; 2); 9)"#);
assert_eq!(fields[1].result, "stale semicolon nested if");
assert_eq!(fields[1].computed_result.as_deref(), Some("3"));
assert_eq!(fields[2].kind, FieldKind::Dynamic("=".to_string()));
assert_eq!(fields[2].instruction, r#"= SUM(1, 2; 3)"#);
assert_eq!(fields[2].result, "cached mixed separators");
assert_eq!(fields[2].computed_result, None);
let report = doc.report();
assert_eq!(
report.features.unsupported_field_kinds,
vec![FieldKindCount {
kind: FieldKind::Dynamic("=".to_string()),
count: 1
}]
);
assert_eq!(
report.features.unsupported_field_reasons,
vec![FieldEvaluationReasonCount {
reason: FieldEvaluationReason::NoComputedResult,
count: 1
}]
);
let main_text = doc.main_text();
assert!(
main_text.contains("6")
&& main_text.contains("3")
&& main_text.contains("cached mixed separators"),
"semicolon formula results should materialize while mixed separators stay cached: {main_text:?}"
);
assert!(
!main_text.contains("stale semicolon sum")
&& !main_text.contains("stale semicolon nested if"),
"computed semicolon formulas should replace stale cached text: {main_text:?}"
);
}
#[test]
fn docx_formula_fields_accept_neutral_format_switches() {
let doc = Document::open(&formula_neutral_switch_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 6);
assert_eq!(fields[0].kind, FieldKind::Dynamic("=".to_string()));
assert_eq!(fields[0].instruction, r#"= 2 + 3 \* MERGEFORMAT"#);
assert_eq!(fields[0].result, "stale neutral formula");
assert_eq!(fields[0].computed_result.as_deref(), Some("5"));
assert_eq!(fields[1].kind, FieldKind::Dynamic("=".to_string()));
assert_eq!(fields[1].instruction, r#"= SUM(1; 2; 3) \*CHARFORMAT"#);
assert_eq!(fields[1].result, "stale compact neutral formula");
assert_eq!(fields[1].computed_result.as_deref(), Some("6"));
assert_eq!(fields[2].kind, FieldKind::Dynamic("=".to_string()));
assert_eq!(fields[2].instruction, r#"= 10.25 \* DollarText"#);
assert_eq!(fields[2].result, "stale dollar formula");
assert_eq!(fields[2].computed_result.as_deref(), Some("ten and 25/100"));
assert_eq!(fields[3].kind, FieldKind::Dynamic("=".to_string()));
assert_eq!(fields[3].instruction, r#"= 31 \* Hex"#);
assert_eq!(fields[3].result, "stale hex formula");
assert_eq!(fields[3].computed_result.as_deref(), Some("1F"));
assert_eq!(fields[4].kind, FieldKind::Dynamic("=".to_string()));
assert_eq!(fields[4].instruction, r#"= 2 + 3 \* Upper"#);
assert_eq!(fields[4].result, "stale upper formula");
assert_eq!(fields[4].computed_result.as_deref(), Some("5"));
assert_eq!(fields[5].kind, FieldKind::Dynamic("=".to_string()));
assert_eq!(fields[5].instruction, r#"= 10.25 \* DollarText \* Upper"#);
assert_eq!(fields[5].result, "stale dollar upper formula");
assert_eq!(fields[5].computed_result.as_deref(), Some("TEN AND 25/100"));
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
let main_text = doc.main_text();
assert!(
main_text.contains("5")
&& main_text.contains("6")
&& main_text.contains("ten and 25/100")
&& main_text.contains("1F")
&& main_text.contains("TEN AND 25/100"),
"neutral formula switches should compute while non-neutral switches stay cached: {main_text:?}"
);
assert!(
!main_text.contains("stale neutral formula")
&& !main_text.contains("stale compact neutral formula")
&& !main_text.contains("stale dollar formula")
&& !main_text.contains("stale hex formula")
&& !main_text.contains("stale upper formula")
&& !main_text.contains("stale dollar upper formula"),
"computed formula switches should replace stale cached text: {main_text:?}"
);
}
#[test]
fn docx_formula_fields_compute_defined_literal_expressions() {
let doc = Document::open(&formula_defined_function_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 5);
assert_eq!(fields[0].kind, FieldKind::Dynamic("=".to_string()));
assert_eq!(fields[0].instruction, r#"= DEFINED(SUM(1; 2; 3))"#);
assert_eq!(fields[0].result, "stale defined expression");
assert_eq!(fields[0].computed_result.as_deref(), Some("1"));
assert_eq!(fields[1].kind, FieldKind::Dynamic("=".to_string()));
assert_eq!(fields[1].instruction, r#"= DEFINED(UnknownBookmark)"#);
assert_eq!(fields[1].result, "stale undefined name");
assert_eq!(fields[1].computed_result.as_deref(), Some("0"));
assert_eq!(fields[2].kind, FieldKind::Dynamic("=".to_string()));
assert_eq!(fields[2].instruction, r#"= DEFINED(1 / 0)"#);
assert_eq!(fields[2].result, "stale error expression");
assert_eq!(fields[2].computed_result.as_deref(), Some("0"));
assert_eq!(fields[3].kind, FieldKind::Dynamic("=".to_string()));
assert_eq!(fields[3].instruction, r#"= IF(DEFINED(2 + 3), 7, 9)"#);
assert_eq!(fields[3].result, "stale nested defined");
assert_eq!(fields[3].computed_result.as_deref(), Some("7"));
assert_eq!(fields[4].kind, FieldKind::Dynamic("=".to_string()));
assert_eq!(fields[4].instruction, r#"= DEFINED()"#);
assert_eq!(fields[4].result, "cached empty defined");
assert_eq!(fields[4].computed_result, None);
let report = doc.report();
assert_eq!(
report.features.unsupported_field_kinds,
vec![FieldKindCount {
kind: FieldKind::Dynamic("=".to_string()),
count: 1
}]
);
assert_eq!(
report.features.unsupported_field_reasons,
vec![FieldEvaluationReasonCount {
reason: FieldEvaluationReason::NoComputedResult,
count: 1
}]
);
let main_text = doc.main_text();
assert!(
main_text.contains("1")
&& main_text.matches('0').count() >= 2
&& main_text.contains("7")
&& main_text.contains("cached empty defined"),
"DEFINED formula results should materialize while malformed empty calls stay cached: {main_text:?}"
);
assert!(
!main_text.contains("stale defined expression")
&& !main_text.contains("stale undefined name")
&& !main_text.contains("stale error expression")
&& !main_text.contains("stale nested defined"),
"computed DEFINED formulas should replace stale cached text: {main_text:?}"
);
}
#[test]
fn docx_formula_fields_compute_simple_table_references() {
let doc = Document::open(&formula_table_reference_docx()).expect("fixture opens");
let fields = doc.fields();
let expected = [
(r#"= SUM(LEFT)"#, "stale left sum", Some("5")),
(
r#"= AVERAGE(LEFT) \# "0.0""#,
"stale left average",
Some("7.5"),
),
(r#"= SUM(BELOW)"#, "stale below sum", Some("11")),
(r#"= SUM(RIGHT)"#, "stale right sum", Some("15")),
(r#"= SUM(ABOVE)"#, "stale above sum", Some("29")),
(r#"= SUM(LEFT)"#, "cached nonnumeric left", None),
];
assert_eq!(fields.len(), expected.len());
for (field, (instruction, stale, result)) in fields.iter().zip(expected) {
assert_eq!(field.kind, FieldKind::Dynamic("=".to_string()));
assert_eq!(field.instruction, instruction);
assert_eq!(field.result, stale);
assert_eq!(field.computed_result.as_deref(), result);
}
let report = doc.report();
assert_eq!(
report.features.unsupported_field_kinds,
vec![FieldKindCount {
kind: FieldKind::Dynamic("=".to_string()),
count: 1
}]
);
assert_eq!(
report.features.unsupported_field_reasons,
vec![FieldEvaluationReasonCount {
reason: FieldEvaluationReason::NoComputedResult,
count: 1
}]
);
let main_text = doc.main_text();
assert!(
main_text.contains("5")
&& main_text.contains("7.5")
&& main_text.contains("11")
&& main_text.contains("15")
&& main_text.contains("29")
&& main_text.contains("cached nonnumeric left"),
"table-reference formula results should materialize while unsafe ranges stay cached: {main_text:?}"
);
assert!(
!main_text.contains("stale left sum")
&& !main_text.contains("stale left average")
&& !main_text.contains("stale below sum")
&& !main_text.contains("stale right sum")
&& !main_text.contains("stale above sum"),
"computed table-reference formulas should replace stale cached text: {main_text:?}"
);
}
#[test]
fn docx_table_formula_positional_arguments_skip_header_rows() {
let doc = Document::open(&formula_table_header_row_reference_docx()).expect("fixture opens");
let fields = doc.fields();
let expected = [
(r#"= SUM(BELOW)"#, "stale header below sum", Some("5")),
(r#"= COUNT(BELOW)"#, "stale header below count", Some("2")),
(r#"= SUM(ABOVE)"#, "stale body above sum", Some("5")),
(r#"= COUNT(ABOVE)"#, "stale body above count", Some("2")),
(r#"= SUM(C)"#, "stale body column sum", Some("15")),
];
assert_eq!(fields.len(), expected.len());
for (field, (instruction, stale, result)) in fields.iter().zip(expected) {
assert_eq!(field.kind, FieldKind::Dynamic("=".to_string()));
assert_eq!(field.instruction, instruction);
assert_eq!(field.result, stale);
assert_eq!(field.computed_result.as_deref(), result);
}
let main_text = doc.main_text();
assert!(
main_text.contains("5")
&& main_text.contains("15")
&& main_text.contains("2")
&& !main_text.contains("stale header below sum")
&& !main_text.contains("stale header below count")
&& !main_text.contains("stale body above sum")
&& !main_text.contains("stale body above count")
&& !main_text.contains("stale body column sum"),
"header rows should not contribute to positional table formulas, including current-column formulas: {main_text:?}"
);
}
#[test]
fn docx_table_formula_positional_span_safety_skips_header_rows() {
let doc =
Document::open(&formula_table_header_row_span_reference_docx()).expect("fixture opens");
let fields = doc.fields();
let expected = [
(r#"= SUM(BELOW)"#, "stale header below span sum", Some("5")),
(r#"= SUM(ABOVE)"#, "stale body above span sum", Some("5")),
(
r#"= SUM(A1:A3)"#,
"cached explicit spanned header range",
None,
),
];
assert_eq!(fields.len(), expected.len());
for (field, (instruction, stale, result)) in fields.iter().zip(expected) {
assert_eq!(field.kind, FieldKind::Dynamic("=".to_string()));
assert_eq!(field.instruction, instruction);
assert_eq!(field.result, stale);
assert_eq!(field.computed_result.as_deref(), result);
}
let main_text = doc.main_text();
assert!(
main_text.contains("5")
&& main_text.contains("cached explicit spanned header range")
&& !main_text.contains("stale header below span sum")
&& !main_text.contains("stale body above span sum"),
"span-bearing header rows should not block directional table formulas: {main_text:?}"
);
}
#[test]
fn docx_table_formula_below_skips_header_formula_rows() {
let doc =
Document::open(&formula_table_header_formula_row_reference_docx()).expect("fixture opens");
let fields = doc.fields();
let expected = [
(
r#"= SUM(BELOW)"#,
"stale header below formula row",
Some("5"),
),
(r#"= SUM(RIGHT)"#, "cached skipped header formula", None),
(r#"= SUM(R)"#, "cached skipped header row formula", None),
];
assert_eq!(fields.len(), expected.len());
for (field, (instruction, stale, result)) in fields.iter().zip(expected) {
assert_eq!(field.kind, FieldKind::Dynamic("=".to_string()));
assert_eq!(field.instruction, instruction);
assert_eq!(field.result, stale);
assert_eq!(field.computed_result.as_deref(), result);
}
let main_text = doc.main_text();
assert!(
main_text.contains("5")
&& main_text.contains("cached skipped header formula")
&& main_text.contains("cached skipped header row formula")
&& !main_text.contains("stale header below formula row"),
"header formula rows should not stop BELOW traversal or contribute header row values: {main_text:?}"
);
}
#[test]
fn docx_table_formula_empty_included_cells_stay_cached() {
let doc = Document::open(&formula_table_empty_included_cell_docx()).expect("fixture opens");
let fields = doc.fields();
let expected = [
(r#"= SUM(LEFT)"#, "cached empty left", None),
(r#"= SUM(LEFT)"#, "stale numeric left", Some("7")),
(r#"= SUM(ABOVE)"#, "cached empty above", None),
];
assert_eq!(fields.len(), expected.len());
for (field, (instruction, stale, result)) in fields.iter().zip(expected) {
assert_eq!(field.kind, FieldKind::Dynamic("=".to_string()));
assert_eq!(field.instruction, instruction);
assert_eq!(field.result, stale);
assert_eq!(field.computed_result.as_deref(), result);
}
let report = doc.report();
assert_eq!(
report.features.unsupported_field_kinds,
vec![FieldKindCount {
kind: FieldKind::Dynamic("=".to_string()),
count: 2
}]
);
assert_eq!(
report.features.unsupported_field_reasons,
vec![FieldEvaluationReasonCount {
reason: FieldEvaluationReason::NoComputedResult,
count: 2
}]
);
let main_text = doc.main_text();
assert!(
main_text.contains("cached empty left")
&& main_text.contains("7")
&& main_text.contains("cached empty above")
&& !main_text.contains("stale numeric left"),
"present empty cells should keep positional formulas cached while numeric rows still compute: {main_text:?}"
);
}
#[test]
fn docx_table_formula_uses_prior_computed_formula_cells_as_source_values() {
let doc =
Document::open(&formula_table_prior_computed_formula_source_docx()).expect("fixture opens");
let fields = doc.fields();
let expected = [
(r#"= SUM(LEFT)"#, "stale row total", Some("5")),
(r#"= SUM(ABOVE)"#, "stale dependent above", Some("5")),
(r#"= SUM(A1:C1)"#, "cached mixed formula range", Some("10")),
];
assert_eq!(fields.len(), expected.len());
for (field, (instruction, stale, result)) in fields.iter().zip(expected) {
assert_eq!(field.kind, FieldKind::Dynamic("=".to_string()));
assert_eq!(field.instruction, instruction);
assert_eq!(field.result, stale);
assert_eq!(field.computed_result.as_deref(), result);
}
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
let main_text = doc.main_text();
assert!(
main_text.contains("5")
&& main_text.contains("10")
&& !main_text.contains("stale row total")
&& !main_text.contains("stale dependent above")
&& !main_text.contains("cached mixed formula range"),
"source-order table formulas should feed later table formulas: {main_text:?}"
);
}
#[test]
fn docx_table_formula_does_not_use_prior_formula_cells_without_cached_results_as_source_values() {
let doc =
Document::open(&formula_table_empty_prior_formula_source_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 2);
assert_eq!(fields[0].instruction, r#"= SUM(RIGHT)"#);
assert_eq!(fields[0].result, "");
assert_eq!(fields[0].computed_result.as_deref(), Some("5"));
assert_eq!(fields[1].instruction, r#"= SUM(ABOVE)"#);
assert_eq!(fields[1].result, "dependent cached");
assert_eq!(fields[1].computed_result, None);
let main_text = doc.main_text();
assert!(
main_text.contains("5") && main_text.contains("dependent cached"),
"empty cached formula cells should render themselves without feeding later formulas: {main_text:?}"
);
}
#[test]
fn docx_table_formula_source_simple_field_uses_single_alternate_content_branch() {
let doc = Document::open(&formula_table_source_field_alternate_content_docx())
.expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 2);
assert_eq!(fields[0].kind, FieldKind::Dynamic("QUOTE".to_string()));
assert_eq!(fields[0].instruction, r#"QUOTE "2""#);
assert_eq!(fields[0].result, "2");
assert_eq!(fields[0].computed_result.as_deref(), Some("2"));
assert_eq!(fields[1].kind, FieldKind::Dynamic("=".to_string()));
assert_eq!(fields[1].instruction, r#"= SUM(LEFT)"#);
assert_eq!(fields[1].result, "stale alt source sum");
assert_eq!(fields[1].computed_result.as_deref(), Some("2"));
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
let main_text = doc.main_text();
assert!(
main_text.contains("2")
&& !main_text.contains("9")
&& !main_text.contains("29")
&& !main_text.contains("stale alt source sum"),
"table formula source cell text must use one AlternateContent branch: {main_text:?}"
);
}
#[test]
fn docx_table_formula_source_simple_field_preserves_nested_simple_field_text() {
let doc =
Document::open(&formula_table_source_field_nested_simple_docx()).expect("fixture opens");
let fields = doc.fields();
let source = fields
.iter()
.find(|field| field.instruction == r#"QUOTE "123""#)
.expect("source field is recorded");
assert_eq!(source.kind, FieldKind::Dynamic("QUOTE".to_string()));
assert_eq!(source.result, "123");
assert_eq!(source.computed_result.as_deref(), Some("123"));
let formula = fields
.iter()
.find(|field| field.instruction == r#"= SUM(LEFT)"#)
.expect("formula field is recorded");
assert_eq!(formula.kind, FieldKind::Dynamic("=".to_string()));
assert_eq!(formula.result, "stale nested source sum");
assert_eq!(formula.computed_result.as_deref(), Some("123"));
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
}
#[test]
fn docx_table_formula_source_simple_field_computes_nested_empty_simple_fields() {
let doc = Document::open(&formula_table_source_nested_empty_simple_field_docx())
.expect("fixture opens");
let fields = doc.fields();
let outer = fields
.iter()
.find(|field| field.instruction == "CUSTOM outer")
.expect("outer source field is recorded");
assert_eq!(outer.kind, FieldKind::Unknown("CUSTOM".to_string()));
assert_eq!(outer.result, "13");
assert_eq!(outer.computed_result, None);
let formula = fields
.iter()
.find(|field| field.instruction == r#"= SUM(LEFT)"#)
.expect("formula field is recorded");
assert_eq!(formula.kind, FieldKind::Dynamic("=".to_string()));
assert_eq!(formula.result, "stale nested empty source sum");
assert_eq!(formula.computed_result.as_deref(), Some("123"));
let main_text = doc.main_text();
assert!(
main_text.contains("\t123") && !main_text.contains("stale nested empty source sum"),
"table formula source text should compute empty simple fields consumed inside another field result: {main_text:?}"
);
}
#[test]
fn docx_table_formula_source_simple_field_computes_nested_simple_fields() {
let doc =
Document::open(&formula_table_source_nested_simple_field_docx()).expect("fixture opens");
let fields = doc.fields();
let outer = fields
.iter()
.find(|field| field.instruction == "CUSTOM outer")
.expect("outer source field is recorded");
assert_eq!(outer.kind, FieldKind::Unknown("CUSTOM".to_string()));
assert_eq!(outer.result, "193");
assert_eq!(outer.computed_result, None);
let formula = fields
.iter()
.find(|field| field.instruction == r#"= SUM(LEFT)"#)
.expect("formula field is recorded");
assert_eq!(formula.kind, FieldKind::Dynamic("=".to_string()));
assert_eq!(formula.result, "stale nested source sum");
assert_eq!(formula.computed_result.as_deref(), Some("123"));
let main_text = doc.main_text();
assert!(
main_text.contains("\t123") && !main_text.contains("stale nested source sum"),
"table formula source text should compute simple fields consumed inside another field result: {main_text:?}"
);
}
#[test]
fn docx_table_formula_source_simple_field_computes_nested_complex_fields() {
let doc =
Document::open(&formula_table_source_nested_complex_field_docx()).expect("fixture opens");
let fields = doc.fields();
let outer = fields
.iter()
.find(|field| field.instruction == "CUSTOM outer")
.expect("outer source field is recorded");
assert_eq!(outer.kind, FieldKind::Unknown("CUSTOM".to_string()));
assert_eq!(outer.result, "193");
assert_eq!(outer.computed_result, None);
let formula = fields
.iter()
.find(|field| field.instruction == r#"= SUM(LEFT)"#)
.expect("formula field is recorded");
assert_eq!(formula.kind, FieldKind::Dynamic("=".to_string()));
assert_eq!(formula.result, "stale nested complex source sum");
assert_eq!(formula.computed_result.as_deref(), Some("123"));
let main_text = doc.main_text();
assert!(
main_text.contains("\t123") && !main_text.contains("stale nested complex source sum"),
"table formula source text should compute complex fields consumed inside another field result: {main_text:?}"
);
}
#[test]
fn docx_table_formula_source_simple_field_uses_computed_nested_result_text() {
let doc = Document::open(&formula_table_source_field_stale_nested_simple_docx())
.expect("fixture opens");
let fields = doc.fields();
let source = fields
.iter()
.find(|field| field.instruction == r#"QUOTE "123""#)
.expect("source field is recorded");
assert_eq!(source.kind, FieldKind::Dynamic("QUOTE".to_string()));
assert_eq!(source.result, "stale source value");
assert_eq!(source.computed_result.as_deref(), Some("123"));
let formula = fields
.iter()
.find(|field| field.instruction == r#"= SUM(LEFT)"#)
.expect("formula field is recorded");
assert_eq!(formula.kind, FieldKind::Dynamic("=".to_string()));
assert_eq!(formula.result, "stale source sum");
assert_eq!(formula.computed_result.as_deref(), Some("123"));
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
let main_text = doc.main_text();
assert!(
main_text.contains("123")
&& !main_text.contains("stale source value")
&& !main_text.contains("stale source sum"),
"table formula source text should use computed deterministic nested field output: {main_text:?}"
);
}
#[test]
fn docx_table_formula_source_complex_field_uses_computed_nested_result_text() {
let doc =
Document::open(&formula_table_source_field_stale_complex_docx()).expect("fixture opens");
let fields = doc.fields();
let source = fields
.iter()
.find(|field| field.instruction == r#"QUOTE "123""#)
.expect("source field is recorded");
assert_eq!(source.kind, FieldKind::Dynamic("QUOTE".to_string()));
assert_eq!(source.result, "stale complex source");
assert_eq!(source.computed_result.as_deref(), Some("123"));
let formula = fields
.iter()
.find(|field| field.instruction == r#"= SUM(LEFT)"#)
.expect("formula field is recorded");
assert_eq!(formula.kind, FieldKind::Dynamic("=".to_string()));
assert_eq!(formula.result, "stale complex source sum");
assert_eq!(formula.computed_result.as_deref(), Some("123"));
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
let main_text = doc.main_text();
assert!(
main_text.contains("123")
&& !main_text.contains("stale complex source")
&& !main_text.contains("stale complex source sum"),
"table formula source text should use computed deterministic complex field output: {main_text:?}"
);
}
#[test]
fn docx_table_formula_source_field_uses_computed_sequence_results() {
let doc = Document::open(&formula_table_source_field_sequence_docx()).expect("fixture opens");
let fields = doc.fields();
let sequence_fields = fields
.iter()
.filter(|field| field.kind == FieldKind::Sequence)
.collect::<Vec<_>>();
assert_eq!(sequence_fields.len(), 3);
assert_eq!(sequence_fields[0].instruction, "SEQ Item");
assert_eq!(sequence_fields[0].computed_result.as_deref(), Some("1"));
assert_eq!(sequence_fields[1].instruction, "SEQ Item");
assert_eq!(sequence_fields[1].result, "99");
assert_eq!(sequence_fields[1].computed_result.as_deref(), Some("2"));
assert_eq!(sequence_fields[2].instruction, "SEQ Item");
assert_eq!(sequence_fields[2].result, "98");
assert_eq!(sequence_fields[2].computed_result.as_deref(), Some("3"));
let formulas = fields
.iter()
.filter(|field| field.instruction == r#"= SUM(LEFT)"#)
.collect::<Vec<_>>();
assert_eq!(formulas.len(), 2);
assert!(formulas
.iter()
.all(|field| field.kind == FieldKind::Dynamic("=".to_string())));
assert_eq!(formulas[0].result, "stale simple sequence source sum");
assert_eq!(formulas[0].computed_result.as_deref(), Some("2"));
assert_eq!(formulas[1].result, "stale complex sequence source sum");
assert_eq!(formulas[1].computed_result.as_deref(), Some("3"));
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
let main_text = doc.main_text();
assert!(
main_text.contains("1\n2\t2\n3\t3")
&& !main_text.contains("99")
&& !main_text.contains("98")
&& !main_text.contains("stale simple sequence source sum")
&& !main_text.contains("stale complex sequence source sum"),
"table formula source text should use computed SEQ source values: {main_text:?}"
);
}
#[test]
fn docx_table_formula_source_field_uses_computed_numbering_results() {
let doc = Document::open(&formula_table_source_field_numbering_docx()).expect("fixture opens");
let fields = doc.fields();
let numbering_fields = fields
.iter()
.filter(|field| field.kind == FieldKind::Numbering("AUTONUM".to_string()))
.collect::<Vec<_>>();
assert_eq!(numbering_fields.len(), 3);
assert_eq!(numbering_fields[0].instruction, "AUTONUM");
assert_eq!(numbering_fields[0].computed_result.as_deref(), Some("1"));
assert_eq!(numbering_fields[1].instruction, "AUTONUM");
assert_eq!(numbering_fields[1].result, "99");
assert_eq!(numbering_fields[1].computed_result.as_deref(), Some("2"));
assert_eq!(numbering_fields[2].instruction, "AUTONUM");
assert_eq!(numbering_fields[2].result, "98");
assert_eq!(numbering_fields[2].computed_result.as_deref(), Some("3"));
let formulas = fields
.iter()
.filter(|field| field.instruction == r#"= SUM(LEFT)"#)
.collect::<Vec<_>>();
assert_eq!(formulas.len(), 2);
assert!(formulas
.iter()
.all(|field| field.kind == FieldKind::Dynamic("=".to_string())));
assert_eq!(formulas[0].result, "stale simple autonum source sum");
assert_eq!(formulas[0].computed_result.as_deref(), Some("2"));
assert_eq!(formulas[1].result, "stale complex autonum source sum");
assert_eq!(formulas[1].computed_result.as_deref(), Some("3"));
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
let main_text = doc.main_text();
assert!(
main_text.contains("1\n2\t2\n3\t3")
&& !main_text.contains("99")
&& !main_text.contains("98")
&& !main_text.contains("stale simple autonum source sum")
&& !main_text.contains("stale complex autonum source sum"),
"table formula source text should use computed AUTONUM source values: {main_text:?}"
);
}
#[test]
fn docx_table_formula_source_field_uses_computed_listnum_results() {
let doc = Document::open(&formula_table_source_field_listnum_docx()).expect("fixture opens");
let fields = doc.fields();
let listnum_fields = fields
.iter()
.filter(|field| field.kind == FieldKind::Numbering("LISTNUM".to_string()))
.collect::<Vec<_>>();
assert_eq!(listnum_fields.len(), 3);
assert_eq!(listnum_fields[0].instruction, "LISTNUM NumberDefault");
assert_eq!(listnum_fields[0].computed_result.as_deref(), Some("1"));
assert_eq!(listnum_fields[1].instruction, "LISTNUM NumberDefault");
assert_eq!(listnum_fields[1].result, "99");
assert_eq!(listnum_fields[1].computed_result.as_deref(), Some("2"));
assert_eq!(listnum_fields[2].instruction, "LISTNUM NumberDefault");
assert_eq!(listnum_fields[2].result, "98");
assert_eq!(listnum_fields[2].computed_result.as_deref(), Some("3"));
let formulas = fields
.iter()
.filter(|field| field.instruction == r#"= SUM(LEFT)"#)
.collect::<Vec<_>>();
assert_eq!(formulas.len(), 2);
assert!(formulas
.iter()
.all(|field| field.kind == FieldKind::Dynamic("=".to_string())));
assert_eq!(formulas[0].result, "stale simple listnum source sum");
assert_eq!(formulas[0].computed_result.as_deref(), Some("2"));
assert_eq!(formulas[1].result, "stale complex listnum source sum");
assert_eq!(formulas[1].computed_result.as_deref(), Some("3"));
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
let main_text = doc.main_text();
assert!(
main_text.contains("1\n2\t2\n3\t3")
&& !main_text.contains("99")
&& !main_text.contains("98")
&& !main_text.contains("stale simple listnum source sum")
&& !main_text.contains("stale complex listnum source sum"),
"table formula source text should use computed LISTNUM source values: {main_text:?}"
);
}
#[test]
fn docx_table_formula_source_field_uses_computed_legacy_form_results() {
let doc =
Document::open(&formula_table_source_field_legacy_form_docx()).expect("fixture opens");
let fields = doc.fields();
let form_fields = fields
.iter()
.filter(|field| field.kind == FieldKind::FormField("FORMDROPDOWN".to_string()))
.collect::<Vec<_>>();
assert_eq!(form_fields.len(), 2);
assert_eq!(form_fields[0].result, "stale prior form");
assert_eq!(form_fields[0].computed_result.as_deref(), Some("99"));
assert_eq!(form_fields[1].result, "stale source form");
assert_eq!(form_fields[1].computed_result.as_deref(), Some("7"));
let formula = fields
.iter()
.find(|field| field.instruction == r#"= SUM(LEFT)"#)
.expect("formula field is recorded");
assert_eq!(formula.kind, FieldKind::Dynamic("=".to_string()));
assert_eq!(formula.result, "stale legacy form source sum");
assert_eq!(formula.computed_result.as_deref(), Some("7"));
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
let main_text = doc.main_text();
assert!(
main_text.contains("99\n7\t7")
&& !main_text.contains("stale source form")
&& !main_text.contains("stale legacy form source sum"),
"table formula source text should use computed legacy form source values: {main_text:?}"
);
}
#[test]
fn docx_table_formula_source_field_uses_computed_note_ref_results() {
let doc = Document::open(&formula_table_source_field_note_ref_docx()).expect("fixture opens");
let fields = doc.fields();
let note_ref = fields
.iter()
.find(|field| field.instruction == "NOTEREF FootOne")
.expect("note-ref source field is recorded");
assert_eq!(note_ref.kind, FieldKind::NoteRef);
assert_eq!(note_ref.result, "stale note source");
assert_eq!(note_ref.computed_result.as_deref(), Some("1"));
let formula = fields
.iter()
.find(|field| field.instruction == r#"= SUM(LEFT)"#)
.expect("formula field is recorded");
assert_eq!(formula.kind, FieldKind::Dynamic("=".to_string()));
assert_eq!(formula.result, "stale note source sum");
assert_eq!(formula.computed_result.as_deref(), Some("1"));
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
let main_text = doc.main_text();
assert!(
main_text.contains("1\t1")
&& !main_text.contains("stale note source")
&& !main_text.contains("stale note source sum"),
"table formula source text should use computed NOTEREF source values: {main_text:?}"
);
}
#[test]
fn docx_table_formula_source_field_does_not_use_relative_note_ref_cache() {
let doc = Document::open(&formula_table_source_field_relative_note_ref_docx())
.expect("fixture opens");
let fields = doc.fields();
let note_ref = fields
.iter()
.find(|field| field.instruction == "NOTEREF FootOne \\p")
.expect("relative note-ref source field is recorded");
assert_eq!(note_ref.kind, FieldKind::NoteRef);
assert_eq!(note_ref.result, "9");
assert_eq!(note_ref.computed_result.as_deref(), Some("above"));
let formula = fields
.iter()
.find(|field| field.instruction == r#"= SUM(LEFT)"#)
.expect("formula field is recorded");
assert_eq!(formula.kind, FieldKind::Dynamic("=".to_string()));
assert_eq!(formula.result, "stale relative note source sum");
assert_eq!(formula.computed_result, None);
let main_text = doc.main_text();
assert!(
main_text.contains("above\tstale relative note source sum")
&& !main_text.contains("9\t9"),
"table formula source text should not use stale relative NOTEREF cache as a number: {main_text:?}"
);
}
#[test]
fn docx_table_formula_source_field_uses_computed_ref_note_mark_results() {
let doc =
Document::open(&formula_table_source_field_ref_note_mark_docx()).expect("fixture opens");
let fields = doc.fields();
let ref_field = fields
.iter()
.find(|field| field.instruction == "REF FootOne \\f")
.expect("REF note mark source field is recorded");
assert_eq!(ref_field.kind, FieldKind::Ref);
assert_eq!(ref_field.result, "stale ref note source");
assert_eq!(ref_field.computed_result.as_deref(), Some("2"));
let formula = fields
.iter()
.find(|field| field.instruction == r#"= SUM(LEFT)"#)
.expect("formula field is recorded");
assert_eq!(formula.kind, FieldKind::Dynamic("=".to_string()));
assert_eq!(formula.result, "stale ref note source sum");
assert_eq!(formula.computed_result.as_deref(), Some("2"));
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
let main_text = doc.main_text();
assert!(
main_text.contains("2\t2")
&& !main_text.contains("stale ref note source")
&& !main_text.contains("stale ref note source sum"),
"table formula source text should use computed REF note-reference marks: {main_text:?}"
);
}
#[test]
fn docx_table_formula_source_field_resolves_document_bookmark_operands() {
let doc = Document::open(&formula_table_source_field_document_bookmark_docx())
.expect("fixture opens");
let fields = doc.fields();
let source = fields
.iter()
.find(|field| field.instruction == r#"IF InvoiceTier = "Gold" "123" "0""#)
.expect("source field is recorded");
assert_eq!(source.kind, FieldKind::Dynamic("IF".to_string()));
assert_eq!(source.result, "stale bookmark source");
assert_eq!(source.computed_result.as_deref(), Some("123"));
let formula = fields
.iter()
.find(|field| field.instruction == r#"= SUM(LEFT)"#)
.expect("formula field is recorded");
assert_eq!(formula.kind, FieldKind::Dynamic("=".to_string()));
assert_eq!(formula.result, "stale bookmark source sum");
assert_eq!(formula.computed_result.as_deref(), Some("123"));
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
let main_text = doc.main_text();
assert!(
main_text.contains("Gold")
&& main_text.contains("123\t123")
&& !main_text.contains("stale bookmark source")
&& !main_text.contains("stale bookmark source sum"),
"table formula source text should use computed bookmark-backed source field output: {main_text:?}"
);
}
#[test]
fn docx_table_formula_source_field_uses_computed_document_info_results() {
let doc =
Document::open(&formula_table_source_field_document_info_docx()).expect("fixture opens");
let fields = doc.fields();
let source = fields
.iter()
.find(|field| field.instruction == "VERSION")
.expect("document-info source field is recorded");
assert_eq!(source.kind, FieldKind::DocumentInfo("VERSION".to_string()));
assert_eq!(source.result, "999");
assert_eq!(source.computed_result.as_deref(), Some("123"));
let formula = fields
.iter()
.find(|field| field.instruction == r#"= SUM(LEFT)"#)
.expect("formula field is recorded");
assert_eq!(formula.kind, FieldKind::Dynamic("=".to_string()));
assert_eq!(formula.result, "stale document-info source sum");
assert_eq!(formula.computed_result.as_deref(), Some("123"));
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
let main_text = doc.main_text();
assert!(
main_text.contains("123\t123")
&& !main_text.contains("999")
&& !main_text.contains("stale document-info source sum"),
"table formula source text should use computed document-info source field output: {main_text:?}"
);
}
#[test]
fn docx_table_formula_source_field_uses_computed_section_results() {
let doc = Document::open(&formula_table_source_field_section_docx()).expect("fixture opens");
let fields = doc.fields();
let source = fields
.iter()
.find(|field| field.instruction == "SECTION")
.expect("SECTION source field is recorded");
assert_eq!(
source.kind,
FieldKind::DocumentStructure("SECTION".to_string())
);
assert_eq!(source.result, "99");
assert_eq!(source.computed_result.as_deref(), Some("1"));
let formula = fields
.iter()
.find(|field| field.instruction == r#"= SUM(LEFT)"#)
.expect("formula field is recorded");
assert_eq!(formula.kind, FieldKind::Dynamic("=".to_string()));
assert_eq!(formula.result, "stale section source sum");
assert_eq!(formula.computed_result.as_deref(), Some("1"));
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
let main_text = doc.main_text();
assert!(
main_text.contains("1\t1")
&& !main_text.contains("99")
&& !main_text.contains("stale section source sum"),
"table formula source text should use computed SECTION source values: {main_text:?}"
);
}
#[test]
fn docx_table_formula_source_field_resolves_ref_bookmark_sources() {
let doc =
Document::open(&formula_table_source_field_ref_bookmark_docx()).expect("fixture opens");
let fields = doc.fields();
let explicit = fields
.iter()
.find(|field| field.instruction == "REF InvoiceTotal")
.expect("explicit REF source field is recorded");
assert_eq!(explicit.kind, FieldKind::Ref);
assert_eq!(explicit.result, "stale ref source");
assert_eq!(explicit.computed_result.as_deref(), Some("123"));
let direct = fields
.iter()
.find(|field| field.instruction == "InvoiceTotal")
.expect("direct bookmark source field is recorded");
assert_eq!(direct.kind, FieldKind::Ref);
assert_eq!(direct.result, "stale direct source");
assert_eq!(direct.computed_result.as_deref(), Some("123"));
let formulas = fields
.iter()
.filter(|field| field.instruction == r#"= SUM(LEFT)"#)
.collect::<Vec<_>>();
assert_eq!(formulas.len(), 2);
assert!(formulas
.iter()
.all(|field| field.kind == FieldKind::Dynamic("=".to_string())));
assert_eq!(formulas[0].result, "stale ref source sum");
assert_eq!(formulas[0].computed_result.as_deref(), Some("123"));
assert_eq!(formulas[1].result, "stale direct source sum");
assert_eq!(formulas[1].computed_result.as_deref(), Some("123"));
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
let main_text = doc.main_text();
assert!(
main_text.matches("123\t123").count() == 2
&& !main_text.contains("stale ref source")
&& !main_text.contains("stale direct source")
&& !main_text.contains("stale ref source sum")
&& !main_text.contains("stale direct source sum"),
"table formula source text should use computed REF/direct bookmark source fields: {main_text:?}"
);
}
#[test]
fn docx_table_formula_source_field_resolves_prior_set_bookmark_operands() {
let doc = Document::open(&formula_table_source_field_prior_set_docx()).expect("fixture opens");
let fields = doc.fields();
let set = fields
.iter()
.find(|field| field.instruction == r#"SET ClientTier "Gold""#)
.expect("SET field is recorded");
assert_eq!(set.kind, FieldKind::Dynamic("SET".to_string()));
assert_eq!(set.result, "cached set tier");
assert_eq!(set.computed_result.as_deref(), Some(""));
let source = fields
.iter()
.find(|field| field.instruction == r#"IF ClientTier = "Gold" "123" "0""#)
.expect("source field is recorded");
assert_eq!(source.kind, FieldKind::Dynamic("IF".to_string()));
assert_eq!(source.result, "stale set source");
assert_eq!(source.computed_result.as_deref(), Some("123"));
let formula = fields
.iter()
.find(|field| field.instruction == r#"= SUM(LEFT)"#)
.expect("formula field is recorded");
assert_eq!(formula.kind, FieldKind::Dynamic("=".to_string()));
assert_eq!(formula.result, "stale set source sum");
assert_eq!(formula.computed_result.as_deref(), Some("123"));
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
let main_text = doc.main_text();
assert!(
main_text.contains("123\t123")
&& !main_text.contains("cached set tier")
&& !main_text.contains("stale set source")
&& !main_text.contains("stale set source sum"),
"table formula source text should use computed SET-backed source field output: {main_text:?}"
);
}
#[test]
fn docx_table_formula_source_field_resolves_prior_complex_set_bookmark_operands() {
let doc = Document::open(&formula_table_source_field_prior_complex_set_docx())
.expect("fixture opens");
let fields = doc.fields();
let set = fields
.iter()
.find(|field| field.instruction == r#"SET ClientTier "Gold""#)
.expect("SET field is recorded");
assert_eq!(set.kind, FieldKind::Dynamic("SET".to_string()));
assert_eq!(set.result, "cached complex set tier");
assert_eq!(set.computed_result.as_deref(), Some(""));
let source = fields
.iter()
.find(|field| field.instruction == r#"IF ClientTier = "Gold" "123" "0""#)
.expect("source field is recorded");
assert_eq!(source.kind, FieldKind::Dynamic("IF".to_string()));
assert_eq!(source.result, "stale complex set source");
assert_eq!(source.computed_result.as_deref(), Some("123"));
let formula = fields
.iter()
.find(|field| field.instruction == r#"= SUM(LEFT)"#)
.expect("formula field is recorded");
assert_eq!(formula.kind, FieldKind::Dynamic("=".to_string()));
assert_eq!(formula.result, "stale complex set source sum");
assert_eq!(formula.computed_result.as_deref(), Some("123"));
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
let main_text = doc.main_text();
assert!(
main_text.contains("123\t123")
&& !main_text.contains("cached complex set tier")
&& !main_text.contains("stale complex set source")
&& !main_text.contains("stale complex set source sum"),
"table formula source text should use computed complex SET-backed source field output: {main_text:?}"
);
}
#[test]
fn docx_table_formula_source_field_keeps_known_field_names_cached() {
let doc = Document::open(&formula_table_source_known_field_name_bookmark_docx())
.expect("fixture opens");
let fields = doc.fields();
let source = fields
.iter()
.find(|field| field.instruction == "PAGEREF")
.expect("known source field is recorded");
assert_eq!(source.kind, FieldKind::PageRef);
assert_eq!(source.result, "123");
let formula = fields
.iter()
.find(|field| field.instruction == r#"= SUM(LEFT)"#)
.expect("formula field is recorded");
assert_eq!(formula.kind, FieldKind::Dynamic("=".to_string()));
assert_eq!(formula.result, "stale known field source sum");
assert_eq!(formula.computed_result.as_deref(), Some("123"));
let main_text = doc.main_text();
assert!(
main_text.contains("\t123") && !main_text.contains("stale known field source sum"),
"table formula source text should keep known field cached text instead of bookmark text: {main_text:?}"
);
}
#[test]
fn docx_table_formula_source_field_hides_toc_entry_marker_fields() {
let doc = Document::open(&formula_table_source_toc_entry_marker_docx()).expect("fixture opens");
let fields = doc.fields();
let marker = fields
.iter()
.find(|field| field.instruction == r#"TC "Hidden" \f m \l 1"#)
.expect("TC marker is recorded");
assert_eq!(marker.kind, FieldKind::TocEntry);
assert_eq!(marker.result, "999");
assert_eq!(marker.computed_result.as_deref(), Some(""));
let formula = fields
.iter()
.find(|field| field.instruction == r#"= SUM(LEFT)"#)
.expect("formula field is recorded");
assert_eq!(formula.kind, FieldKind::Dynamic("=".to_string()));
assert_eq!(formula.result, "stale tc source sum");
assert_eq!(formula.computed_result.as_deref(), Some("123"));
let main_text = doc.main_text();
assert!(
main_text.contains("123\t123")
&& !main_text.contains("999")
&& !main_text.contains("stale tc source sum"),
"table formula source text should hide TC marker fields instead of using cached marker text: {main_text:?}"
);
}
#[test]
fn docx_table_formula_source_simple_field_preserves_supported_symbols() {
let doc = Document::open(&formula_table_source_field_symbol_docx()).expect("fixture opens");
let fields = doc.fields();
let source = fields
.iter()
.find(|field| field.instruction == r#"QUOTE "123""#)
.expect("source field is recorded");
assert_eq!(source.kind, FieldKind::Dynamic("QUOTE".to_string()));
assert_eq!(source.result, "123");
assert_eq!(source.computed_result.as_deref(), Some("123"));
let formula = fields
.iter()
.find(|field| field.instruction == r#"= SUM(LEFT)"#)
.expect("formula field is recorded");
assert_eq!(formula.kind, FieldKind::Dynamic("=".to_string()));
assert_eq!(formula.result, "stale symbol source sum");
assert_eq!(formula.computed_result.as_deref(), Some("123"));
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
}
#[test]
fn docx_table_formula_source_empty_simple_field_uses_computed_result() {
let doc =
Document::open(&formula_table_source_empty_simple_field_docx()).expect("fixture opens");
let fields = doc.fields();
let source = fields
.iter()
.find(|field| field.instruction == r#"QUOTE "123""#)
.expect("source field is recorded");
assert_eq!(source.kind, FieldKind::Dynamic("QUOTE".to_string()));
assert_eq!(source.result, "");
assert_eq!(source.computed_result.as_deref(), Some("123"));
let formula = fields
.iter()
.find(|field| field.instruction == r#"= SUM(LEFT)"#)
.expect("formula field is recorded");
assert_eq!(formula.kind, FieldKind::Dynamic("=".to_string()));
assert_eq!(formula.result, "stale empty source sum");
assert_eq!(formula.computed_result.as_deref(), Some("123"));
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
let main_text = doc.main_text();
assert!(
main_text.contains("123\t123") && !main_text.contains("stale empty source sum"),
"table formula source text should use computed empty simple-field source values: {main_text:?}"
);
}
#[test]
fn docx_table_formula_source_plain_text_preserves_supported_symbols() {
let doc = Document::open(&formula_table_plain_text_symbol_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 1);
assert_eq!(fields[0].kind, FieldKind::Dynamic("=".to_string()));
assert_eq!(fields[0].instruction, r#"= SUM(LEFT)"#);
assert_eq!(fields[0].result, "stale plain symbol sum");
assert_eq!(fields[0].computed_result.as_deref(), Some("123"));
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
let main_text = doc.main_text();
assert!(
main_text.contains("123") && !main_text.contains("stale plain symbol sum"),
"table formula should use supported symbols in plain source-cell text: {main_text:?}"
);
}
#[test]
fn docx_table_formula_ignores_old_cell_property_revisions() {
let doc = Document::open(&formula_table_cell_property_revision_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 1);
assert_eq!(fields[0].kind, FieldKind::Dynamic("=".to_string()));
assert_eq!(fields[0].instruction, r#"= SUM(LEFT)"#);
assert_eq!(fields[0].result, "cached old span sum");
assert_eq!(fields[0].computed_result.as_deref(), Some("5"));
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
let main_text = doc.main_text();
assert!(
main_text.contains("5") && !main_text.contains("cached old span sum"),
"old table-cell property revisions must not suppress table formula computation: {main_text:?}"
);
}
#[test]
fn docx_table_formula_cell_props_use_single_alternate_content_branch() {
let doc = Document::open(&formula_table_cell_property_alternate_content_docx())
.expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 1);
assert_eq!(fields[0].kind, FieldKind::Dynamic("=".to_string()));
assert_eq!(fields[0].instruction, r#"= SUM(LEFT)"#);
assert_eq!(fields[0].result, "cached fallback span sum");
assert_eq!(fields[0].computed_result.as_deref(), Some("5"));
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
let main_text = doc.main_text();
assert!(
main_text.contains("5") && !main_text.contains("cached fallback span sum"),
"untaken fallback cell properties must not suppress table formula computation: {main_text:?}"
);
}
#[test]
fn docx_table_formula_computes_row_local_references_when_other_rows_have_spans() {
let doc = Document::open(&formula_table_span_row_local_docx()).expect("fixture opens");
let fields = doc.fields();
let expected = [
(r#"= SUM(LEFT)"#, "cached row-local left", Some("5")),
(r#"= SUM(RIGHT)"#, "cached row-local right", Some("15")),
(r#"= SUM(ABOVE)"#, "cached span-table above", None),
];
assert_eq!(fields.len(), expected.len());
for (field, (instruction, stale, result)) in fields.iter().zip(expected) {
assert_eq!(field.kind, FieldKind::Dynamic("=".to_string()));
assert_eq!(field.instruction, instruction);
assert_eq!(field.result, stale);
assert_eq!(field.computed_result.as_deref(), result);
}
let report = doc.report();
assert_eq!(
report.features.unsupported_field_kinds,
vec![FieldKindCount {
kind: FieldKind::Dynamic("=".to_string()),
count: 1
}]
);
assert_eq!(
report.features.unsupported_field_reasons,
vec![FieldEvaluationReasonCount {
reason: FieldEvaluationReason::NoComputedResult,
count: 1
}]
);
let main_text = doc.main_text();
assert!(
main_text.contains("5")
&& main_text.contains("15")
&& main_text.contains("cached span-table above"),
"row-local formulas should compute while cross-row formulas stay cached: {main_text:?}"
);
assert!(
!main_text.contains("cached row-local left")
&& !main_text.contains("cached row-local right"),
"computed row-local span-table formulas should replace stale cached text: {main_text:?}"
);
}
#[test]
fn docx_table_formula_computes_current_row_when_other_rows_have_spans() {
let doc = Document::open(&formula_table_span_current_row_docx()).expect("fixture opens");
let fields = doc.fields();
let expected = [
(r#"= SUM(R)"#, "cached span-table row", Some("5")),
(r#"= SUM(C)"#, "cached span-table column", None),
];
assert_eq!(fields.len(), expected.len());
for (field, (instruction, stale, result)) in fields.iter().zip(expected) {
assert_eq!(field.kind, FieldKind::Dynamic("=".to_string()));
assert_eq!(field.instruction, instruction);
assert_eq!(field.result, stale);
assert_eq!(field.computed_result.as_deref(), result);
}
let report = doc.report();
assert_eq!(
report.features.unsupported_field_kinds,
vec![FieldKindCount {
kind: FieldKind::Dynamic("=".to_string()),
count: 1
}]
);
assert_eq!(
report.features.unsupported_field_reasons,
vec![FieldEvaluationReasonCount {
reason: FieldEvaluationReason::NoComputedResult,
count: 1
}]
);
let main_text = doc.main_text();
assert!(
main_text.contains("5") && main_text.contains("cached span-table column"),
"current-row formulas should compute while current-column formulas stay cached: {main_text:?}"
);
assert!(
!main_text.contains("cached span-table row"),
"computed current-row span-table formulas should replace stale cached text: {main_text:?}"
);
}
#[test]
fn docx_table_formula_computes_same_row_cell_references_when_other_rows_have_spans() {
let doc =
Document::open(&formula_table_span_same_row_cell_reference_docx()).expect("fixture opens");
let fields = doc.fields();
let expected = [
(r#"= A2 + B2 \# "0""#, "cached same-row direct", Some("5")),
(r#"= SUM(A3:B3)"#, "cached same-row range", Some("10")),
(r#"= SUM(A1:B2)"#, "cached cross-row range", None),
];
assert_eq!(fields.len(), expected.len());
for (field, (instruction, stale, result)) in fields.iter().zip(expected) {
assert_eq!(field.kind, FieldKind::Dynamic("=".to_string()));
assert_eq!(field.instruction, instruction);
assert_eq!(field.result, stale);
assert_eq!(field.computed_result.as_deref(), result);
}
let report = doc.report();
assert_eq!(
report.features.unsupported_field_kinds,
vec![FieldKindCount {
kind: FieldKind::Dynamic("=".to_string()),
count: 1
}]
);
assert_eq!(
report.features.unsupported_field_reasons,
vec![FieldEvaluationReasonCount {
reason: FieldEvaluationReason::NoComputedResult,
count: 1
}]
);
let main_text = doc.main_text();
assert!(
main_text.contains("5")
&& main_text.contains("10")
&& main_text.contains("cached cross-row range"),
"same-row cell-reference formulas should compute while cross-row ranges stay cached: {main_text:?}"
);
assert!(
!main_text.contains("cached same-row direct")
&& !main_text.contains("cached same-row range"),
"computed same-row cell-reference formulas should replace stale cached text: {main_text:?}"
);
}
#[test]
fn docx_table_formula_computes_cross_row_cell_references_when_referenced_rows_have_no_spans() {
let doc =
Document::open(&formula_table_span_cross_row_cell_reference_docx()).expect("fixture opens");
let fields = doc.fields();
let expected = [
(r#"= A2 + A3 \# "0""#, "cached cross-row direct", Some("6")),
(r#"= SUM(A2:B3)"#, "cached unspanned-row range", Some("15")),
(r#"= SUM(A1:B2)"#, "cached spanned-row range", None),
];
assert_eq!(fields.len(), expected.len());
for (field, (instruction, stale, result)) in fields.iter().zip(expected) {
assert_eq!(field.kind, FieldKind::Dynamic("=".to_string()));
assert_eq!(field.instruction, instruction);
assert_eq!(field.result, stale);
assert_eq!(field.computed_result.as_deref(), result);
}
let report = doc.report();
assert_eq!(
report.features.unsupported_field_kinds,
vec![FieldKindCount {
kind: FieldKind::Dynamic("=".to_string()),
count: 1
}]
);
assert_eq!(
report.features.unsupported_field_reasons,
vec![FieldEvaluationReasonCount {
reason: FieldEvaluationReason::NoComputedResult,
count: 1
}]
);
let main_text = doc.main_text();
assert!(
main_text.contains("6")
&& main_text.contains("15")
&& main_text.contains("cached spanned-row range"),
"cross-row formulas should compute only when referenced rows have no spans: {main_text:?}"
);
assert!(
!main_text.contains("cached cross-row direct")
&& !main_text.contains("cached unspanned-row range"),
"computed cross-row cell-reference formulas should replace stale cached text: {main_text:?}"
);
}
#[test]
fn docx_table_formula_if_short_circuits_span_unsafe_unselected_branches() {
let doc = Document::open(&formula_table_span_if_short_circuit_docx()).expect("fixture opens");
let fields = doc.fields();
let expected = [
(
r#"= IF(SUM(LEFT)>0,SUM(LEFT),SUM(A1:B2))"#,
"cached guarded row-local",
Some("5"),
),
(
r#"= IF(SUM(LEFT)>0,SUM(A1:B2),9)"#,
"cached guarded literal",
Some("9"),
),
(
r#"= IF(SUM(LEFT)>0;7;SUM(A1:B2))"#,
"cached semicolon guarded",
Some("7"),
),
(
r#"= IF(SUM(LEFT)>0,SUM(A1:B2),9)"#,
"cached selected span branch",
None,
),
];
assert_eq!(fields.len(), expected.len());
for (field, (instruction, stale, result)) in fields.iter().zip(expected) {
assert_eq!(field.kind, FieldKind::Dynamic("=".to_string()));
assert_eq!(field.instruction, instruction);
assert_eq!(field.result, stale);
assert_eq!(field.computed_result.as_deref(), result);
}
let report = doc.report();
assert_eq!(
report.features.unsupported_field_kinds,
vec![FieldKindCount {
kind: FieldKind::Dynamic("=".to_string()),
count: 1
}]
);
assert_eq!(
report.features.unsupported_field_reasons,
vec![FieldEvaluationReasonCount {
reason: FieldEvaluationReason::NoComputedResult,
count: 1
}]
);
let main_text = doc.main_text();
assert!(
main_text.contains("2\t3\t5")
&& main_text.contains("0\t9")
&& main_text.contains("4\t7")
&& main_text.contains("cached selected span branch")
&& !main_text.contains("cached guarded row-local")
&& !main_text.contains("cached guarded literal")
&& !main_text.contains("cached semicolon guarded"),
"span-safe table IF should ignore span-unsafe unselected branches: {main_text:?}"
);
}
#[test]
fn docx_table_formula_computes_directional_references_when_traversed_rows_have_no_spans() {
let doc =
Document::open(&formula_table_span_directional_reference_docx()).expect("fixture opens");
let fields = doc.fields();
let expected = [
(r#"= SUM(ABOVE)"#, "cached safe above", Some("3")),
(r#"= SUM(BELOW)"#, "cached safe below", Some("10")),
(r#"= SUM(ABOVE)"#, "cached spanned above", None),
(r#"= SUM(BELOW)"#, "cached spanned below", None),
];
assert_eq!(fields.len(), expected.len());
for (field, (instruction, stale, result)) in fields.iter().zip(expected) {
assert_eq!(field.kind, FieldKind::Dynamic("=".to_string()));
assert_eq!(field.instruction, instruction);
assert_eq!(field.result, stale);
assert_eq!(field.computed_result.as_deref(), result);
}
let report = doc.report();
assert_eq!(
report.features.unsupported_field_kinds,
vec![FieldKindCount {
kind: FieldKind::Dynamic("=".to_string()),
count: 2
}]
);
assert_eq!(
report.features.unsupported_field_reasons,
vec![FieldEvaluationReasonCount {
reason: FieldEvaluationReason::NoComputedResult,
count: 2
}]
);
let main_text = doc.main_text();
assert!(
main_text.contains("3")
&& main_text.contains("10")
&& main_text.contains("cached spanned above")
&& main_text.contains("cached spanned below"),
"directional formulas should compute only when traversed rows have no spans: {main_text:?}"
);
assert!(
!main_text.contains("cached safe above") && !main_text.contains("cached safe below"),
"computed directional formulas should replace stale cached text: {main_text:?}"
);
}
#[test]
fn docx_table_formula_context_uses_current_structural_wrappers() {
let doc = Document::open(&formula_table_structural_wrapper_docx()).expect("fixture opens");
let fields = doc.fields();
let expected = [
(r#"= SUM(LEFT)"#, "cached row wrapper sum", "5"),
(r#"= SUM(LEFT)"#, "cached cell wrapper sum", "10"),
];
assert_eq!(fields.len(), expected.len());
for (field, (instruction, stale, result)) in fields.iter().zip(expected) {
assert_eq!(field.kind, FieldKind::Dynamic("=".to_string()));
assert_eq!(field.instruction, instruction);
assert_eq!(field.result, stale);
assert_eq!(field.computed_result.as_deref(), Some(result));
}
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
let main_text = doc.main_text();
assert!(
main_text.contains("5")
&& main_text.contains("10")
&& !main_text.contains("cached row wrapper sum")
&& !main_text.contains("cached cell wrapper sum"),
"current structural table wrappers should stay visible and computable: {main_text:?}"
);
}
#[test]
fn docx_table_formula_context_uses_structural_alternate_content() {
let doc =
Document::open(&formula_table_structural_alternate_content_docx()).expect("fixture opens");
let fields = doc.fields();
let expected = [
(r#"= SUM(LEFT)"#, "cached alternate row sum", "5"),
(r#"= SUM(LEFT)"#, "cached alternate cell sum", "10"),
];
assert_eq!(fields.len(), expected.len());
for (field, (instruction, stale, result)) in fields.iter().zip(expected) {
assert_eq!(field.kind, FieldKind::Dynamic("=".to_string()));
assert_eq!(field.instruction, instruction);
assert_eq!(field.result, stale);
assert_eq!(field.computed_result.as_deref(), Some(result));
}
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
let main_text = doc.main_text();
assert!(
main_text.contains("5")
&& main_text.contains("10")
&& !main_text.contains("cached alternate row sum")
&& !main_text.contains("cached alternate cell sum")
&& !main_text.contains("fallback row")
&& !main_text.contains("fallback left")
&& !main_text.contains("fallback middle")
&& !main_text.contains("fallback formula"),
"selected table AlternateContent branches should stay visible and computable: {main_text:?}"
);
}
#[test]
fn docx_table_formula_fields_apply_general_number_format_tails() {
let doc = Document::open(&formula_table_general_number_format_docx()).expect("fixture opens");
let fields = doc.fields();
let expected = [
(
r#"= SUM(LEFT) \* DollarText"#,
"stale table dollar",
"ten and 25/100",
),
(r#"= SUM(LEFT) \* Hex"#, "stale table hex", "1F"),
(
r#"= SUM(LEFT) \* OrdText"#,
"stale table ordinal text",
"twenty-first",
),
(
r#"= SUM(LEFT) \* DollarText \* Upper"#,
"stale table dollar upper",
"TEN AND 25/100",
),
];
assert_eq!(fields.len(), expected.len());
for (field, (instruction, stale, result)) in fields.iter().zip(expected) {
assert_eq!(field.kind, FieldKind::Dynamic("=".to_string()));
assert_eq!(field.instruction, instruction);
assert_eq!(field.result, stale);
assert_eq!(field.computed_result.as_deref(), Some(result));
}
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
let main_text = doc.main_text();
assert!(
main_text.contains("ten and 25/100")
&& main_text.contains("1F")
&& main_text.contains("twenty-first")
&& main_text.contains("TEN AND 25/100"),
"table formula general-number tails should materialize computed text: {main_text:?}"
);
assert!(
!main_text.contains("stale table dollar")
&& !main_text.contains("stale table hex")
&& !main_text.contains("stale table ordinal text")
&& !main_text.contains("stale table dollar upper"),
"computed table formula general-number tails should replace stale cached text: {main_text:?}"
);
}
#[test]
fn docx_table_formula_context_ignores_deleted_fields() {
let doc = Document::open(&formula_table_deleted_preceding_field_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 1);
assert_eq!(fields[0].kind, FieldKind::Dynamic("=".to_string()));
assert_eq!(fields[0].instruction, r#"= SUM(LEFT)"#);
assert_eq!(fields[0].result, "stale visible sum");
assert_eq!(fields[0].computed_result.as_deref(), Some("5"));
let main_text = doc.main_text();
assert!(
main_text.contains("5") && !main_text.contains("deleted formula"),
"deleted formulas must not shift visible table formula results: {main_text:?}"
);
}
#[test]
fn docx_table_formula_context_uses_single_alternate_content_branch() {
let doc = Document::open(&formula_table_alternate_content_preceding_field_docx())
.expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 1);
assert_eq!(fields[0].kind, FieldKind::Dynamic("=".to_string()));
assert_eq!(fields[0].instruction, r#"= SUM(LEFT)"#);
assert_eq!(fields[0].result, "stale visible sum");
assert_eq!(fields[0].computed_result.as_deref(), Some("5"));
let main_text = doc.main_text();
assert!(
main_text.contains("5") && !main_text.contains("fallback formula"),
"AlternateContent fallback formulas must not shift visible table formula results: {main_text:?}"
);
}
#[test]
fn docx_formula_fields_compute_combined_table_references() {
let doc = Document::open(&formula_table_combined_reference_docx()).expect("fixture opens");
let fields = doc.fields();
let expected = [
(r#"= SUM(LEFT,ABOVE)"#, "stale left above sum", Some("6")),
(r#"= SUM(RIGHT;ABOVE)"#, "stale right above sum", Some("16")),
(r#"= COUNT(LEFT,RIGHT)"#, "stale side count", Some("2")),
(
r#"= SUM(LEFT,RIGHT;ABOVE)"#,
"cached mixed positional separators",
None,
),
];
assert_eq!(fields.len(), expected.len());
for (field, (instruction, stale, result)) in fields.iter().zip(expected) {
assert_eq!(field.kind, FieldKind::Dynamic("=".to_string()));
assert_eq!(field.instruction, instruction);
assert_eq!(field.result, stale);
assert_eq!(field.computed_result.as_deref(), result);
}
let report = doc.report();
assert_eq!(
report.features.unsupported_field_kinds,
vec![FieldKindCount {
kind: FieldKind::Dynamic("=".to_string()),
count: 1
}]
);
assert_eq!(
report.features.unsupported_field_reasons,
vec![FieldEvaluationReasonCount {
reason: FieldEvaluationReason::NoComputedResult,
count: 1
}]
);
let main_text = doc.main_text();
assert!(
main_text.contains("6")
&& main_text.contains("16")
&& main_text.contains("2")
&& main_text.contains("cached mixed positional separators"),
"combined table-reference formulas should materialize while mixed separators stay cached: {main_text:?}"
);
assert!(
!main_text.contains("stale left above sum")
&& !main_text.contains("stale right above sum")
&& !main_text.contains("stale side count"),
"computed combined table-reference formulas should replace stale cached text: {main_text:?}"
);
}
#[test]
fn docx_formula_fields_compute_table_cell_references() {
let doc = Document::open(&formula_table_cell_reference_docx()).expect("fixture opens");
let fields = doc.fields();
let expected = [
(r#"= SUM(A1:B2)"#, "stale a1 range", Some("16")),
(r#"= PRODUCT(R1C2:R2C3)"#, "stale rncn range", Some("504")),
(r#"= SUM(A1,C2)"#, "stale a1 list", Some("9")),
(r#"= SUM(R)"#, "stale current row", Some("10")),
(r#"= SUM(C)"#, "stale current column", Some("10")),
(
r#"= SUM(R2C1:R2C3)"#,
"stale explicit row range",
Some("15"),
),
(
r#"= SUM(R1C1:R3C1)"#,
"stale explicit column range",
Some("12"),
),
(r#"= SUM(A1,B1;C1)"#, "cached mixed cell separators", None),
];
assert_eq!(fields.len(), expected.len());
for (field, (instruction, stale, result)) in fields.iter().zip(expected) {
assert_eq!(field.kind, FieldKind::Dynamic("=".to_string()));
assert_eq!(field.instruction, instruction);
assert_eq!(field.result, stale);
assert_eq!(field.computed_result.as_deref(), result);
}
let report = doc.report();
assert_eq!(
report.features.unsupported_field_kinds,
vec![FieldKindCount {
kind: FieldKind::Dynamic("=".to_string()),
count: 1
}]
);
assert_eq!(
report.features.unsupported_field_reasons,
vec![FieldEvaluationReasonCount {
reason: FieldEvaluationReason::NoComputedResult,
count: 1
}]
);
let main_text = doc.main_text();
assert!(
main_text.contains("16")
&& main_text.contains("504")
&& main_text.contains("9")
&& main_text.matches("10").count() >= 2
&& main_text.contains("15")
&& main_text.contains("12")
&& main_text.contains("cached mixed cell separators"),
"table cell-reference formulas should materialize while mixed separators stay cached: {main_text:?}"
);
assert!(
!main_text.contains("stale a1 range")
&& !main_text.contains("stale rncn range")
&& !main_text.contains("stale a1 list")
&& !main_text.contains("stale current row")
&& !main_text.contains("stale current column")
&& !main_text.contains("stale explicit row range")
&& !main_text.contains("stale explicit column range"),
"computed table cell-reference formulas should replace stale cached text: {main_text:?}"
);
}
#[test]
fn docx_formula_fields_compute_direct_table_cell_references() {
let doc = Document::open(&formula_table_direct_cell_reference_docx()).expect("fixture opens");
let fields = doc.fields();
let expected = [
(
r#"= A1 + R1C2 \# "0""#,
"stale direct expression",
Some("5"),
),
(r#"= B1"#, "stale direct cell", Some("3")),
(r#"= C1"#, "cached nonnumeric direct cell", None),
];
assert_eq!(fields.len(), expected.len());
for (field, (instruction, stale, result)) in fields.iter().zip(expected) {
assert_eq!(field.kind, FieldKind::Dynamic("=".to_string()));
assert_eq!(field.instruction, instruction);
assert_eq!(field.result, stale);
assert_eq!(field.computed_result.as_deref(), result);
}
let report = doc.report();
assert_eq!(
report.features.unsupported_field_kinds,
vec![FieldKindCount {
kind: FieldKind::Dynamic("=".to_string()),
count: 1
}]
);
assert_eq!(
report.features.unsupported_field_reasons,
vec![FieldEvaluationReasonCount {
reason: FieldEvaluationReason::NoComputedResult,
count: 1
}]
);
let main_text = doc.main_text();
assert!(
main_text.contains("5")
&& main_text.contains("3")
&& main_text.contains("cached nonnumeric direct cell"),
"direct table-cell formula results should materialize while unsafe cells stay cached: {main_text:?}"
);
assert!(
!main_text.contains("stale direct expression") && !main_text.contains("stale direct cell"),
"computed direct table-cell formulas should replace stale cached text: {main_text:?}"
);
}
#[test]
fn docx_formula_fields_compute_nested_table_reference_expressions() {
let doc = Document::open(&formula_table_nested_expression_docx()).expect("fixture opens");
let fields = doc.fields();
let expected = [
(r#"= IF(SUM(LEFT)>=10,10,0)"#, "stale nested if", Some("10")),
(
r#"= AND(SUM(LEFT)<10,SUM(ABOVE)>=2)"#,
"stale nested and",
Some("1"),
),
(
r#"= ROUND(AVERAGE(A1:B2),1)"#,
"stale nested round",
Some("5"),
),
(
r#"= IF(SUM(LEFT,RIGHT;ABOVE)>0,1,0)"#,
"cached mixed nested table expression",
None,
),
(r#"= SUM(LEFT,1)"#, "stale table literal sum", Some("11")),
(
r#"= ROUND(SUM(LEFT,1),0)"#,
"stale nested literal round",
Some("6"),
),
(
r#"= SUM(A1:B1,10)"#,
"stale table range literal sum",
Some("16"),
),
];
assert_eq!(fields.len(), expected.len());
for (field, (instruction, stale, result)) in fields.iter().zip(expected) {
assert_eq!(field.kind, FieldKind::Dynamic("=".to_string()));
assert_eq!(field.instruction, instruction);
assert_eq!(field.result, stale);
assert_eq!(field.computed_result.as_deref(), result);
}
let report = doc.report();
assert_eq!(
report.features.unsupported_field_kinds,
vec![FieldKindCount {
kind: FieldKind::Dynamic("=".to_string()),
count: 1
}]
);
assert_eq!(
report.features.unsupported_field_reasons,
vec![FieldEvaluationReasonCount {
reason: FieldEvaluationReason::NoComputedResult,
count: 1
}]
);
let main_text = doc.main_text();
assert!(
main_text.contains("10")
&& main_text.contains("1")
&& main_text.contains("5")
&& main_text.contains("cached mixed nested table expression"),
"nested table-reference formula results should materialize while mixed separators stay cached: {main_text:?}"
);
assert!(
!main_text.contains("stale nested if")
&& !main_text.contains("stale nested and")
&& !main_text.contains("stale nested round")
&& !main_text.contains("stale table literal sum")
&& !main_text.contains("stale nested literal round")
&& !main_text.contains("stale table range literal sum"),
"computed nested table-reference formulas should replace stale cached text: {main_text:?}"
);
}
#[test]
fn docx_table_formula_defined_resolves_table_references() {
let doc = Document::open(&formula_table_defined_reference_docx()).expect("fixture opens");
let fields = doc.fields();
let expected = [
(r#"= DEFINED(A1)"#, "stale defined direct cell", Some("1")),
(
r#"= DEFINED(SUM(LEFT,1))"#,
"stale defined aggregate",
Some("1"),
),
(r#"= DEFINED(Z99)"#, "stale missing defined", Some("0")),
(
r#"= IF(DEFINED(Z99),Z99,7)"#,
"stale guarded missing defined",
Some("7"),
),
(r#"= DEFINED()"#, "cached empty defined", None),
];
assert_eq!(fields.len(), expected.len());
for (field, (instruction, stale, result)) in fields.iter().zip(expected) {
assert_eq!(field.kind, FieldKind::Dynamic("=".to_string()));
assert_eq!(field.instruction, instruction);
assert_eq!(field.result, stale);
assert_eq!(field.computed_result.as_deref(), result);
}
let report = doc.report();
assert_eq!(
report.features.unsupported_field_kinds,
vec![FieldKindCount {
kind: FieldKind::Dynamic("=".to_string()),
count: 1
}]
);
assert_eq!(
report.features.unsupported_field_reasons,
vec![FieldEvaluationReasonCount {
reason: FieldEvaluationReason::NoComputedResult,
count: 1
}]
);
let main_text = doc.main_text();
assert!(
main_text.contains("2\t1")
&& main_text.contains("4\t6\t1")
&& main_text.contains("5\t0")
&& main_text.contains("5\t7")
&& main_text.contains("cached empty defined")
&& !main_text.contains("stale defined direct cell")
&& !main_text.contains("stale defined aggregate")
&& !main_text.contains("stale missing defined")
&& !main_text.contains("stale guarded missing defined"),
"table DEFINED formulas should compute supported table references and keep empty calls cached: {main_text:?}"
);
}
#[test]
fn docx_table_formula_if_short_circuits_unselected_branches() {
let doc = Document::open(&formula_table_if_short_circuit_docx()).expect("fixture opens");
let fields = doc.fields();
let expected = [
(
r#"= IF(SUM(LEFT)>0,SUM(LEFT),Z99)"#,
"stale guarded left",
Some("5"),
),
(
r#"= IF(SUM(LEFT)>0,Z99,9)"#,
"stale guarded literal",
Some("9"),
),
(
r#"= IF(SUM(LEFT)>0;7;Z99)"#,
"stale semicolon guarded",
Some("7"),
),
(
r#"= IF(SUM(LEFT)>0,Z99,9)"#,
"cached selected table branch",
None,
),
];
assert_eq!(fields.len(), expected.len());
for (field, (instruction, stale, result)) in fields.iter().zip(expected) {
assert_eq!(field.kind, FieldKind::Dynamic("=".to_string()));
assert_eq!(field.instruction, instruction);
assert_eq!(field.result, stale);
assert_eq!(field.computed_result.as_deref(), result);
}
let report = doc.report();
assert_eq!(
report.features.unsupported_field_kinds,
vec![FieldKindCount {
kind: FieldKind::Dynamic("=".to_string()),
count: 1
}]
);
assert_eq!(
report.features.unsupported_field_reasons,
vec![FieldEvaluationReasonCount {
reason: FieldEvaluationReason::NoComputedResult,
count: 1
}]
);
let main_text = doc.main_text();
assert!(
main_text.contains("2\t3\t5")
&& main_text.contains("0\t9")
&& main_text.contains("4\t7")
&& main_text.contains("cached selected table branch")
&& !main_text.contains("stale guarded left")
&& !main_text.contains("stale guarded literal")
&& !main_text.contains("stale semicolon guarded"),
"table formula IF should resolve only selected table-reference branches: {main_text:?}"
);
}
#[test]
fn docx_formula_fields_compute_ragged_table_existing_cell_references() {
let doc = Document::open(&formula_table_ragged_reference_docx()).expect("fixture opens");
let fields = doc.fields();
let expected = [
(r#"= SUM(A1:C2)"#, "stale ragged range", Some("15")),
(r#"= SUM(C)"#, "stale ragged column", Some("4")),
(r#"= SUM(ABOVE)"#, "stale ragged above", Some("6")),
(r#"= SUM(ABOVE)"#, "cached absent above", None),
];
assert_eq!(fields.len(), expected.len());
for (field, (instruction, stale, result)) in fields.iter().zip(expected) {
assert_eq!(field.kind, FieldKind::Dynamic("=".to_string()));
assert_eq!(field.instruction, instruction);
assert_eq!(field.result, stale);
assert_eq!(field.computed_result.as_deref(), result);
}
let report = doc.report();
assert_eq!(
report.features.unsupported_field_kinds,
vec![FieldKindCount {
kind: FieldKind::Dynamic("=".to_string()),
count: 1
}]
);
assert_eq!(
report.features.unsupported_field_reasons,
vec![FieldEvaluationReasonCount {
reason: FieldEvaluationReason::NoComputedResult,
count: 1
}]
);
let main_text = doc.main_text();
assert!(
main_text.contains("15")
&& main_text.contains("4")
&& main_text.contains("6")
&& main_text.contains("cached absent above"),
"ragged table-reference formula results should materialize while empty references stay cached: {main_text:?}"
);
assert!(
!main_text.contains("stale ragged range")
&& !main_text.contains("stale ragged column")
&& !main_text.contains("stale ragged above"),
"computed ragged table-reference formulas should replace stale cached text: {main_text:?}"
);
}
#[test]
fn docx_formula_fields_compute_literal_comparison_expressions() {
let doc = Document::open(&formula_comparison_docx()).expect("fixture opens");
let fields = doc.fields();
let expected = [
(r#"= IF(2 > 1, 10, 20)"#, "stale greater if", "10"),
(r#"= IF(2 < 1, 10, 20)"#, "stale less if", "20"),
(r#"= 2 = 2"#, "stale equal", "1"),
(r#"= 3 <> 3"#, "stale not equal false", "0"),
(
r#"= AND(2 >= 2, 3 <= 4, 5 <> 6)"#,
"stale logical comparisons",
"1",
),
(r#"= OR(1 > 2, 3 < 4)"#, "stale or comparison", "1"),
(r#"= NOT(7 = 8)"#, "stale not comparison", "1"),
];
assert_eq!(fields.len(), expected.len());
for (field, (instruction, stale, result)) in fields.iter().zip(expected) {
assert_eq!(field.kind, FieldKind::Dynamic("=".to_string()));
assert_eq!(field.instruction, instruction);
assert_eq!(field.result, stale);
assert_eq!(field.computed_result.as_deref(), Some(result));
}
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
let main_text = doc.main_text();
for (_, stale, result) in expected {
assert!(
main_text.contains(result),
"computed literal comparison result should be materialized in main text: {main_text:?}"
);
assert!(
!main_text.contains(stale),
"computed literal comparison result should replace stale cached text: {main_text:?}"
);
}
}
#[test]
fn docx_formula_fields_accept_unquoted_multi_token_numeric_pictures() {
let doc = Document::open(&formula_unquoted_multi_token_numeric_picture_docx())
.expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 1);
assert_eq!(fields[0].kind, FieldKind::Dynamic("=".to_string()));
assert_eq!(fields[0].instruction, r#"= 5 \# 0 units \* MERGEFORMAT"#);
assert_eq!(fields[0].result, "stale unquoted units formula");
assert_eq!(fields[0].computed_result.as_deref(), Some("5 units"));
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
let main_text = doc.main_text();
assert!(
main_text.contains("5 units") && !main_text.contains("stale unquoted units formula"),
"unquoted multi-token numeric pictures should replace stale cached text: {main_text:?}"
);
}
#[test]
fn docx_formula_fields_compute_numeric_picture_affixes_and_x_placeholders() {
let doc = Document::open(&formula_numeric_picture_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 6);
assert_eq!(fields[0].kind, FieldKind::Dynamic("=".to_string()));
assert_eq!(fields[0].instruction, r#"= 1234.5 \# "$#,##0.00""#);
assert_eq!(fields[0].result, "stale currency formula");
assert_eq!(fields[0].computed_result.as_deref(), Some("$1,234.50"));
assert_eq!(fields[1].kind, FieldKind::Dynamic("=".to_string()));
assert_eq!(fields[1].instruction, r###"= 33 \# "##%""###);
assert_eq!(fields[1].result, "stale percent formula");
assert_eq!(fields[1].computed_result.as_deref(), Some("33%"));
assert_eq!(fields[2].kind, FieldKind::Dynamic("=".to_string()));
assert_eq!(fields[2].instruction, r#"= 111053 + 111439 \# x##"#);
assert_eq!(fields[2].result, "stale dropped formula");
assert_eq!(fields[2].computed_result.as_deref(), Some("492"));
assert_eq!(fields[3].kind, FieldKind::Dynamic("=".to_string()));
assert_eq!(fields[3].instruction, r#"= 1 / 8 \# 0.00x"#);
assert_eq!(fields[3].result, "stale precision formula");
assert_eq!(fields[3].computed_result.as_deref(), Some("0.125"));
assert_eq!(fields[4].kind, FieldKind::Dynamic("=".to_string()));
assert_eq!(fields[4].instruction, r#"= 3 / 4 \# .x"#);
assert_eq!(fields[4].result, "stale rounded formula");
assert_eq!(fields[4].computed_result.as_deref(), Some(".8"));
assert_eq!(fields[5].kind, FieldKind::Dynamic("=".to_string()));
assert_eq!(fields[5].instruction, r#"= 5 \# "0 units""#);
assert_eq!(fields[5].result, "stale spaced suffix formula");
assert_eq!(fields[5].computed_result.as_deref(), Some("5 units"));
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
let main_text = doc.main_text();
assert!(
main_text.contains("$1,234.50")
&& main_text.contains("33%")
&& main_text.contains("492")
&& main_text.contains("0.125")
&& main_text.contains(".8")
&& main_text.contains("5 units"),
"computed formula numeric pictures should materialize literal affixes: {main_text:?}"
);
assert!(
!main_text.contains("stale currency formula")
&& !main_text.contains("stale percent formula")
&& !main_text.contains("stale dropped formula")
&& !main_text.contains("stale precision formula")
&& !main_text.contains("stale rounded formula")
&& !main_text.contains("stale spaced suffix formula"),
"computed formula numeric pictures should replace stale cached text: {main_text:?}"
);
}
#[test]
fn docx_formula_fields_compute_compact_numeric_pictures() {
let doc = Document::open(&formula_compact_numeric_picture_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 3);
assert_eq!(fields[0].kind, FieldKind::Dynamic("=".to_string()));
assert_eq!(fields[0].instruction, r#"= 10 / 4 \#"0.0""#);
assert_eq!(fields[0].result, "stale compact quoted picture");
assert_eq!(fields[0].computed_result.as_deref(), Some("2.5"));
assert_eq!(fields[1].kind, FieldKind::Dynamic("=".to_string()));
assert_eq!(fields[1].instruction, r#"= SUM(100, 20) \#$0"#);
assert_eq!(fields[1].result, "stale compact unquoted picture");
assert_eq!(fields[1].computed_result.as_deref(), Some("$120"));
assert_eq!(fields[2].kind, FieldKind::Dynamic("=".to_string()));
assert_eq!(fields[2].instruction, r#"= 10 \#"#);
assert_eq!(fields[2].result, "cached missing compact picture");
assert_eq!(fields[2].computed_result, None);
let report = doc.report();
assert_eq!(
report.features.unsupported_field_kinds,
vec![FieldKindCount {
kind: FieldKind::Dynamic("=".to_string()),
count: 1
}]
);
assert_eq!(
report.features.unsupported_field_reasons,
vec![FieldEvaluationReasonCount {
reason: FieldEvaluationReason::UnsupportedSwitch,
count: 1
}]
);
let main_text = doc.main_text();
assert!(
main_text.contains("2.5")
&& main_text.contains("$120")
&& main_text.contains("cached missing compact picture"),
"compact numeric pictures should compute while malformed switches stay cached: {main_text:?}"
);
assert!(
!main_text.contains("stale compact quoted picture")
&& !main_text.contains("stale compact unquoted picture"),
"computed compact numeric pictures should replace stale cached text: {main_text:?}"
);
}
#[test]
fn docx_quote_field_computes_literal_text_and_general_text_formats() {
let doc = Document::open("e_field_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 6);
assert!(fields
.iter()
.all(|field| field.kind == FieldKind::Dynamic("QUOTE".to_string())));
assert_eq!(fields[0].instruction, "QUOTE \"literal text\"");
assert_eq!(fields[0].result, "stale literal");
assert_eq!(fields[0].computed_result.as_deref(), Some("literal text"));
assert_eq!(fields[1].instruction, "QUOTE \"mixed words\" \\* Caps");
assert_eq!(fields[1].result, "stale caps");
assert_eq!(fields[1].computed_result.as_deref(), Some("Mixed Words"));
assert_eq!(fields[2].instruction, "QUOTE \"word\" \\* Upper");
assert_eq!(fields[2].result, "stale upper");
assert_eq!(fields[2].computed_result.as_deref(), Some("WORD"));
assert_eq!(fields[3].instruction, "QUOTE PlainToken");
assert_eq!(fields[3].result, "stale unquoted token");
assert_eq!(fields[3].computed_result.as_deref(), Some("PlainToken"));
assert_eq!(fields[4].instruction, "QUOTE plain words \\* Upper");
assert_eq!(fields[4].result, "stale unquoted phrase");
assert_eq!(fields[4].computed_result.as_deref(), Some("PLAIN WORDS"));
assert_eq!(fields[5].instruction, "QUOTE \"broken literal ");
assert_eq!(fields[5].result, "cached broken quote");
assert_eq!(fields[5].computed_result, None);
let report = doc.report();
assert_eq!(
report.features.unsupported_field_kinds,
vec![FieldKindCount {
kind: FieldKind::Dynamic("QUOTE".to_string()),
count: 1,
}]
);
assert_eq!(
report.features.unsupported_field_reasons,
vec![FieldEvaluationReasonCount {
reason: FieldEvaluationReason::UnsupportedSwitch,
count: 1,
}]
);
assert_eq!(
model_simple_field_reason_hints(&doc, |instruction| instruction.starts_with("QUOTE")),
vec![(
r#"QUOTE "broken literal "#.to_string(),
Some(FieldUnsupportedReason::UnsupportedSwitch),
)]
);
let main_text = doc.main_text();
assert!(
main_text.contains("literal text\nMixed Words\nWORD\nPlainToken\nPLAIN WORDS"),
"computed QUOTE fields should be materialized in main text: {main_text:?}"
);
assert!(
!main_text.contains("stale literal")
&& !main_text.contains("stale caps")
&& !main_text.contains("stale upper")
&& !main_text.contains("stale unquoted token")
&& !main_text.contains("stale unquoted phrase"),
"computed QUOTE fields should not display stale cached text: {main_text:?}"
);
assert!(main_text.contains("cached broken quote"), "{main_text:?}");
}
#[test]
fn docx_inserted_content_fields_are_named_noncomputed_fields() {
let doc = Document::open(&inserted_content_field_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 11);
assert_eq!(
fields[0].kind,
FieldKind::InsertedContent("INCLUDETEXT".to_string())
);
assert_eq!(fields[0].instruction, "INCLUDETEXT \"appendix.docx\"");
assert_eq!(fields[0].result, "Appendix text");
assert_eq!(fields[0].computed_result, None);
assert_eq!(
fields[1].kind,
FieldKind::InsertedContent("INCLUDEPICTURE".to_string())
);
assert_eq!(fields[1].result, "Chart preview");
assert_eq!(fields[1].computed_result, None);
assert_eq!(
fields[2].kind,
FieldKind::InsertedContent("LINK".to_string())
);
assert_eq!(fields[2].result, "42");
assert_eq!(fields[2].computed_result, None);
assert_eq!(
fields[3].kind,
FieldKind::InsertedContent("EMBED".to_string())
);
assert_eq!(fields[3].result, "Embedded object");
assert_eq!(fields[3].computed_result, None);
assert_eq!(
fields[4].kind,
FieldKind::InsertedContent("DATABASE".to_string())
);
assert_eq!(fields[4].result, "Rows");
assert_eq!(fields[4].computed_result, None);
assert_eq!(
fields[5].kind,
FieldKind::InsertedContent("DDE".to_string())
);
assert_eq!(fields[5].result, "DDE value");
assert_eq!(fields[5].computed_result, None);
assert_eq!(
fields[6].kind,
FieldKind::InsertedContent("DDEAUTO".to_string())
);
assert_eq!(fields[6].result, "Auto DDE value");
assert_eq!(fields[6].computed_result, None);
assert_eq!(
fields[7].kind,
FieldKind::InsertedContent("IMPORT".to_string())
);
assert_eq!(fields[7].result, "Imported object");
assert_eq!(fields[7].computed_result, None);
assert_eq!(
fields[8].kind,
FieldKind::InsertedContent("INCLUDE".to_string())
);
assert_eq!(fields[8].result, "Included text");
assert_eq!(fields[8].computed_result, None);
assert_eq!(
fields[9].kind,
FieldKind::InsertedContent("AUTOTEXT".to_string())
);
assert_eq!(fields[9].instruction, "AUTOTEXT Signature");
assert_eq!(fields[9].result, "AutoText signature");
assert_eq!(fields[9].computed_result, None);
assert_eq!(
fields[10].kind,
FieldKind::InsertedContent("AUTOTEXTLIST".to_string())
);
assert_eq!(
fields[10].instruction,
"AUTOTEXTLIST \"Choose clause\" \\s Legal"
);
assert_eq!(fields[10].result, "AutoText list");
assert_eq!(fields[10].computed_result, None);
let report = doc.report();
assert_eq!(
report.features.unsupported_field_kinds,
vec![
FieldKindCount {
kind: FieldKind::InsertedContent("INCLUDETEXT".to_string()),
count: 1,
},
FieldKindCount {
kind: FieldKind::InsertedContent("INCLUDEPICTURE".to_string()),
count: 1,
},
FieldKindCount {
kind: FieldKind::InsertedContent("LINK".to_string()),
count: 1,
},
FieldKindCount {
kind: FieldKind::InsertedContent("EMBED".to_string()),
count: 1,
},
FieldKindCount {
kind: FieldKind::InsertedContent("DATABASE".to_string()),
count: 1,
},
FieldKindCount {
kind: FieldKind::InsertedContent("DDE".to_string()),
count: 1,
},
FieldKindCount {
kind: FieldKind::InsertedContent("DDEAUTO".to_string()),
count: 1,
},
FieldKindCount {
kind: FieldKind::InsertedContent("IMPORT".to_string()),
count: 1,
},
FieldKindCount {
kind: FieldKind::InsertedContent("INCLUDE".to_string()),
count: 1,
},
FieldKindCount {
kind: FieldKind::InsertedContent("AUTOTEXT".to_string()),
count: 1,
},
FieldKindCount {
kind: FieldKind::InsertedContent("AUTOTEXTLIST".to_string()),
count: 1,
},
]
);
assert_eq!(
report.features.unsupported_field_reasons,
vec![FieldEvaluationReasonCount {
reason: FieldEvaluationReason::NoComputedResult,
count: 11,
}]
);
let main_text = doc.main_text();
assert!(
main_text.contains("Appendix text")
&& main_text.contains("Chart preview")
&& main_text.contains("42")
&& main_text.contains("Embedded object")
&& main_text.contains("Rows")
&& main_text.contains("DDE value")
&& main_text.contains("Auto DDE value")
&& main_text.contains("Imported object")
&& main_text.contains("Included text")
&& main_text.contains("AutoText signature")
&& main_text.contains("AutoText list"),
"cached inserted-content field results should remain in main text: {main_text:?}"
);
}
#[test]
fn docx_inserted_content_diagnostics_split_valid_broader_fields_from_malformed_syntax() {
let doc = Document::open(&docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:fldSimple w:instr=" INCLUDETEXT "appendix.docx" "><w:r><w:t>Appendix text</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" INCLUDEPICTURE "chart.png "><w:r><w:t>cached malformed include picture</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" LINK \* "><w:r><w:t>cached dangling format switch</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" INCLUDETEXT "chapter.docx" \* BadFormat "><w:r><w:t>cached bad include format</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
]))
.expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 4);
assert_eq!(
fields[0].kind,
FieldKind::InsertedContent("INCLUDETEXT".to_string())
);
assert_eq!(fields[0].instruction, r#"INCLUDETEXT "appendix.docx""#);
assert_eq!(fields[0].computed_result, None);
assert_eq!(
fields[1].kind,
FieldKind::InsertedContent("INCLUDEPICTURE".to_string())
);
assert_eq!(fields[1].instruction, r#"INCLUDEPICTURE "chart.png "#);
assert_eq!(fields[1].computed_result, None);
assert_eq!(
fields[2].kind,
FieldKind::InsertedContent("LINK".to_string())
);
assert_eq!(fields[2].instruction, r#"LINK \*"#);
assert_eq!(fields[2].computed_result, None);
assert_eq!(
fields[3].kind,
FieldKind::InsertedContent("INCLUDETEXT".to_string())
);
assert_eq!(
fields[3].instruction,
r#"INCLUDETEXT "chapter.docx" \* BadFormat"#
);
assert_eq!(fields[3].computed_result, None);
let report = doc.report();
assert_eq!(
report.features.unsupported_field_kinds,
vec![
FieldKindCount {
kind: FieldKind::InsertedContent("INCLUDETEXT".to_string()),
count: 2,
},
FieldKindCount {
kind: FieldKind::InsertedContent("INCLUDEPICTURE".to_string()),
count: 1,
},
FieldKindCount {
kind: FieldKind::InsertedContent("LINK".to_string()),
count: 1,
},
]
);
assert_eq!(
report.features.unsupported_field_reasons,
vec![
FieldEvaluationReasonCount {
reason: FieldEvaluationReason::NoComputedResult,
count: 1,
},
FieldEvaluationReasonCount {
reason: FieldEvaluationReason::UnsupportedSwitch,
count: 3,
},
]
);
assert_eq!(
model_simple_field_reason_hints(&doc, |instruction| {
instruction.starts_with("INCLUDETEXT")
|| instruction.starts_with("INCLUDEPICTURE")
|| instruction.starts_with("LINK")
}),
vec![
(
r#"INCLUDETEXT "appendix.docx""#.to_string(),
Some(FieldUnsupportedReason::NoComputedResult),
),
(
r#"INCLUDEPICTURE "chart.png "#.to_string(),
Some(FieldUnsupportedReason::UnsupportedSwitch),
),
(
r#"LINK \*"#.to_string(),
Some(FieldUnsupportedReason::UnsupportedSwitch),
),
(
r#"INCLUDETEXT "chapter.docx" \* BadFormat"#.to_string(),
Some(FieldUnsupportedReason::UnsupportedSwitch),
),
]
);
assert!(doc.main_text().contains("cached malformed include picture"));
assert!(doc.main_text().contains("cached dangling format switch"));
assert!(doc.main_text().contains("cached bad include format"));
}
#[test]
fn docx_mail_merge_helper_fields_are_named_noncomputed_fields() {
let doc = Document::open(&mail_merge_helper_field_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 4);
assert_eq!(
fields[0].kind,
FieldKind::MailMerge("ADDRESSBLOCK".to_string())
);
assert_eq!(fields[0].instruction, "ADDRESSBLOCK");
assert_eq!(fields[0].result, "Acme Corp");
assert_eq!(fields[0].computed_result, None);
assert_eq!(
fields[1].kind,
FieldKind::MailMerge("GREETINGLINE".to_string())
);
assert_eq!(fields[1].result, "Dear Hyunjo,");
assert_eq!(fields[1].computed_result, None);
assert_eq!(fields[2].kind, FieldKind::MailMerge("MERGEREC".to_string()));
assert_eq!(fields[2].result, "7");
assert_eq!(fields[2].computed_result, None);
assert_eq!(fields[3].kind, FieldKind::MailMerge("MERGESEQ".to_string()));
assert_eq!(fields[3].result, "3");
assert_eq!(fields[3].computed_result, None);
let report = doc.report();
assert_eq!(
report.features.unsupported_field_kinds,
vec![
FieldKindCount {
kind: FieldKind::MailMerge("ADDRESSBLOCK".to_string()),
count: 1,
},
FieldKindCount {
kind: FieldKind::MailMerge("GREETINGLINE".to_string()),
count: 1,
},
FieldKindCount {
kind: FieldKind::MailMerge("MERGEREC".to_string()),
count: 1,
},
FieldKindCount {
kind: FieldKind::MailMerge("MERGESEQ".to_string()),
count: 1,
},
]
);
assert_eq!(
report.features.unsupported_field_reasons,
vec![FieldEvaluationReasonCount {
reason: FieldEvaluationReason::NoComputedResult,
count: 4,
}]
);
let main_text = doc.main_text();
assert!(
main_text.contains("Acme Corp")
&& main_text.contains("Dear Hyunjo,")
&& main_text.contains("7")
&& main_text.contains("3"),
"cached mail-merge helper field results should remain in main text: {main_text:?}"
);
}
#[test]
fn docx_mail_merge_helper_diagnostics_split_valid_broader_fields_from_malformed_syntax() {
let doc = Document::open(&docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:fldSimple w:instr=" ADDRESSBLOCK "><w:r><w:t>Acme Corp</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" GREETINGLINE "Dear "><w:r><w:t>cached malformed greeting</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
]))
.expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 2);
assert_eq!(
fields[0].kind,
FieldKind::MailMerge("ADDRESSBLOCK".to_string())
);
assert_eq!(fields[0].computed_result, None);
assert_eq!(
fields[1].kind,
FieldKind::MailMerge("GREETINGLINE".to_string())
);
assert_eq!(fields[1].instruction, r#"GREETINGLINE "Dear "#);
assert_eq!(fields[1].computed_result, None);
let report = doc.report();
assert_eq!(
report.features.unsupported_field_kinds,
vec![
FieldKindCount {
kind: FieldKind::MailMerge("ADDRESSBLOCK".to_string()),
count: 1,
},
FieldKindCount {
kind: FieldKind::MailMerge("GREETINGLINE".to_string()),
count: 1,
},
]
);
assert_eq!(
report.features.unsupported_field_reasons,
vec![
FieldEvaluationReasonCount {
reason: FieldEvaluationReason::NoComputedResult,
count: 1,
},
FieldEvaluationReasonCount {
reason: FieldEvaluationReason::UnsupportedSwitch,
count: 1,
},
]
);
assert_eq!(
model_simple_field_reason_hints(&doc, |instruction| {
instruction.starts_with("ADDRESSBLOCK") || instruction.starts_with("GREETINGLINE")
}),
vec![
(
"ADDRESSBLOCK".to_string(),
Some(FieldUnsupportedReason::NoComputedResult),
),
(
r#"GREETINGLINE "Dear "#.to_string(),
Some(FieldUnsupportedReason::UnsupportedSwitch),
),
]
);
assert!(doc.main_text().contains("cached malformed greeting"));
}
#[test]
fn docx_reference_index_fields_are_named_noncomputed_fields() {
let doc = Document::open(&reference_index_field_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 15);
assert_eq!(
fields[0].kind,
FieldKind::ReferenceIndex("BIBLIOGRAPHY".to_string())
);
assert_eq!(fields[0].instruction, "BIBLIOGRAPHY \\l 1033");
assert_eq!(fields[0].result, "Works cited");
assert_eq!(fields[0].computed_result, None);
assert_eq!(
fields[1].kind,
FieldKind::ReferenceIndex("CITATION".to_string())
);
assert_eq!(fields[1].result, "(Smith, 2026)");
assert_eq!(fields[1].computed_result, None);
assert_eq!(
fields[2].kind,
FieldKind::ReferenceIndex("INDEX".to_string())
);
assert_eq!(fields[2].result, "Index preview");
assert_eq!(fields[2].computed_result, None);
assert_eq!(fields[3].kind, FieldKind::ReferenceIndex("TOA".to_string()));
assert_eq!(fields[3].result, "Authorities");
assert_eq!(fields[3].computed_result, None);
assert_eq!(fields[4].kind, FieldKind::ReferenceIndex("TA".to_string()));
assert_eq!(fields[4].result, "Case v. Example");
assert_eq!(fields[4].computed_result.as_deref(), Some(""));
assert_eq!(fields[5].kind, FieldKind::ReferenceIndex("XE".to_string()));
assert_eq!(fields[5].result, "Term");
assert_eq!(fields[5].computed_result.as_deref(), Some(""));
assert_eq!(fields[6].kind, FieldKind::ReferenceIndex("RD".to_string()));
assert_eq!(fields[6].result, "Referenced doc");
assert_eq!(fields[6].computed_result.as_deref(), Some(""));
assert_eq!(fields[7].kind, FieldKind::ReferenceIndex("TA".to_string()));
assert_eq!(fields[7].instruction, "TA \\l\"Compact Case\" \\c2");
assert_eq!(fields[7].result, "Compact Case");
assert_eq!(fields[7].computed_result.as_deref(), Some(""));
assert_eq!(fields[8].kind, FieldKind::ReferenceIndex("TA".to_string()));
assert_eq!(fields[8].instruction, "TA \\sShortEntry \\c3");
assert_eq!(fields[8].result, "Short Entry");
assert_eq!(fields[8].computed_result.as_deref(), Some(""));
assert_eq!(fields[9].kind, FieldKind::ReferenceIndex("XE".to_string()));
assert_eq!(fields[9].instruction, "XE \"See Term\" \\t\"See Also\"");
assert_eq!(fields[9].result, "See Term");
assert_eq!(fields[9].computed_result.as_deref(), Some(""));
assert_eq!(fields[10].kind, FieldKind::ReferenceIndex("RD".to_string()));
assert_eq!(
fields[10].instruction,
"RD \"formatted-appendix.docx\" \\*MERGEFORMAT"
);
assert_eq!(fields[10].result, "Formatted referenced doc");
assert_eq!(fields[10].computed_result.as_deref(), Some(""));
assert_eq!(fields[11].kind, FieldKind::ReferenceIndex("TA".to_string()));
assert_eq!(
fields[11].instruction,
"TA \\l \"Formatted Case\" \\c 1 \\*CHARFORMAT"
);
assert_eq!(fields[11].result, "Formatted Case");
assert_eq!(fields[11].computed_result.as_deref(), Some(""));
assert_eq!(fields[12].kind, FieldKind::ReferenceIndex("XE".to_string()));
assert_eq!(
fields[12].instruction,
"XE \"Formatted Term\" \\*MERGEFORMAT"
);
assert_eq!(fields[12].result, "Formatted Term");
assert_eq!(fields[12].computed_result.as_deref(), Some(""));
assert_eq!(fields[13].kind, FieldKind::ReferenceIndex("XE".to_string()));
assert_eq!(
fields[13].instruction,
"XE \"Duplicate Format\" \\* Upper \\* Lower"
);
assert_eq!(fields[13].result, "Duplicate Format");
assert_eq!(fields[13].computed_result, None);
assert_eq!(fields[14].kind, FieldKind::ReferenceIndex("TA".to_string()));
assert_eq!(fields[14].instruction, "TA \\l \"Broken Case\" \\c 99");
assert_eq!(fields[14].result, "Broken Case");
assert_eq!(fields[14].computed_result, None);
let report = doc.report();
assert_eq!(
report.features.unsupported_field_kinds,
vec![
FieldKindCount {
kind: FieldKind::ReferenceIndex("BIBLIOGRAPHY".to_string()),
count: 1,
},
FieldKindCount {
kind: FieldKind::ReferenceIndex("CITATION".to_string()),
count: 1,
},
FieldKindCount {
kind: FieldKind::ReferenceIndex("INDEX".to_string()),
count: 1,
},
FieldKindCount {
kind: FieldKind::ReferenceIndex("TOA".to_string()),
count: 1,
},
FieldKindCount {
kind: FieldKind::ReferenceIndex("XE".to_string()),
count: 1,
},
FieldKindCount {
kind: FieldKind::ReferenceIndex("TA".to_string()),
count: 1,
},
]
);
assert_eq!(
report.features.unsupported_field_reasons,
vec![
FieldEvaluationReasonCount {
reason: FieldEvaluationReason::NoComputedResult,
count: 4,
},
FieldEvaluationReasonCount {
reason: FieldEvaluationReason::UnsupportedSwitch,
count: 2,
},
]
);
let main_text = doc.main_text();
assert!(
main_text.contains("Works cited")
&& main_text.contains("(Smith, 2026)")
&& main_text.contains("Index preview")
&& main_text.contains("Authorities")
&& main_text.contains("Duplicate Format"),
"cached unresolved reference/index field results should remain in main text: {main_text:?}"
);
assert!(
!main_text.contains("Case v. Example")
&& !main_text.contains("Term")
&& !main_text.contains("Referenced doc")
&& !main_text.contains("Compact Case")
&& !main_text.contains("Short Entry")
&& !main_text.contains("See Term")
&& !main_text.contains("Formatted referenced doc")
&& !main_text.contains("Formatted Case")
&& !main_text.contains("Formatted Term"),
"computed RD/TA/XE marker fields should be hidden in main text: {main_text:?}"
);
}
#[test]
fn docx_reference_index_markers_accept_unquoted_multi_token_switch_operands() {
let doc =
Document::open(&reference_index_unquoted_multi_token_marker_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 2);
assert_eq!(fields[0].kind, FieldKind::ReferenceIndex("TA".to_string()));
assert_eq!(fields[0].instruction, "TA \\l Case v. Example \\c 1");
assert_eq!(fields[0].result, "cached unquoted ta marker");
assert_eq!(fields[0].computed_result.as_deref(), Some(""));
assert_eq!(fields[1].kind, FieldKind::ReferenceIndex("XE".to_string()));
assert_eq!(
fields[1].instruction,
"XE \"Mercury\" \\t See planets \\* FirstCap"
);
assert_eq!(fields[1].result, "cached unquoted xe marker");
assert_eq!(fields[1].computed_result.as_deref(), Some(""));
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
assert_eq!(
model_simple_field_reason_hints(&doc, |instruction| {
instruction.starts_with("TA ") || instruction.starts_with("XE ")
}),
vec![
("TA \\l Case v. Example \\c 1".to_string(), None),
(
"XE \"Mercury\" \\t See planets \\* FirstCap".to_string(),
None,
),
]
);
let main_text = doc.main_text();
assert!(
!main_text.contains("cached unquoted ta marker")
&& !main_text.contains("cached unquoted xe marker"),
"computed TA/XE marker fields should stay hidden for unquoted multi-token switch operands: {main_text:?}"
);
}
#[test]
fn docx_reference_index_marker_fields_remain_reportable_in_model() {
let doc = Document::open(&reference_index_field_docx()).expect("fixture opens");
let marker_hints = model_simple_field_reason_hints(&doc, |instruction| {
matches!(
instruction,
"TA \\l \"Case v. Example\" \\c 1"
| "XE \"Term\""
| "RD \"appendix.docx\""
| "TA \\l\"Compact Case\" \\c2"
| "TA \\sShortEntry \\c3"
| "XE \"See Term\" \\t\"See Also\""
| "RD \"formatted-appendix.docx\" \\*MERGEFORMAT"
| "TA \\l \"Formatted Case\" \\c 1 \\*CHARFORMAT"
| "XE \"Formatted Term\" \\*MERGEFORMAT"
)
});
assert_eq!(
marker_hints,
vec![
("TA \\l \"Case v. Example\" \\c 1".to_string(), None),
("XE \"Term\"".to_string(), None),
("RD \"appendix.docx\"".to_string(), None),
("TA \\l\"Compact Case\" \\c2".to_string(), None),
("TA \\sShortEntry \\c3".to_string(), None),
("XE \"See Term\" \\t\"See Also\"".to_string(), None),
(
"RD \"formatted-appendix.docx\" \\*MERGEFORMAT".to_string(),
None,
),
(
"TA \\l \"Formatted Case\" \\c 1 \\*CHARFORMAT".to_string(),
None,
),
("XE \"Formatted Term\" \\*MERGEFORMAT".to_string(), None),
]
);
#[cfg(feature = "render")]
{
let expected_report = doc.report();
let rendered = rwml::render_pdf_with_report(&doc.model());
assert_eq!(rendered.report.unsupported.fields, 6);
assert_eq!(
rendered.report.unsupported.field_kinds,
expected_report.features.unsupported_field_kinds
);
assert_eq!(
rendered.report.unsupported.unsupported_field_reasons,
expected_report.features.unsupported_field_reasons
);
}
}
#[test]
fn docx_reference_index_diagnostics_split_valid_generated_from_malformed_syntax() {
let doc = Document::open(&docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:fldSimple w:instr=" BIBLIOGRAPHY \l 1033 "><w:r><w:t>Works cited</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" INDEX "bad "><w:r><w:t>cached malformed index</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
]))
.expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 2);
assert_eq!(
fields[0].kind,
FieldKind::ReferenceIndex("BIBLIOGRAPHY".to_string())
);
assert_eq!(fields[0].computed_result, None);
assert_eq!(
fields[1].kind,
FieldKind::ReferenceIndex("INDEX".to_string())
);
assert_eq!(fields[1].instruction, r#"INDEX "bad "#);
assert_eq!(fields[1].computed_result, None);
let report = doc.report();
assert_eq!(
report.features.unsupported_field_kinds,
vec![
FieldKindCount {
kind: FieldKind::ReferenceIndex("BIBLIOGRAPHY".to_string()),
count: 1,
},
FieldKindCount {
kind: FieldKind::ReferenceIndex("INDEX".to_string()),
count: 1,
},
]
);
assert_eq!(
report.features.unsupported_field_reasons,
vec![
FieldEvaluationReasonCount {
reason: FieldEvaluationReason::NoComputedResult,
count: 1,
},
FieldEvaluationReasonCount {
reason: FieldEvaluationReason::UnsupportedSwitch,
count: 1,
},
]
);
assert_eq!(
model_simple_field_reason_hints(&doc, |instruction| {
instruction.starts_with("BIBLIOGRAPHY") || instruction.starts_with("INDEX")
}),
vec![
(
"BIBLIOGRAPHY \\l 1033".to_string(),
Some(FieldUnsupportedReason::NoComputedResult),
),
(
r#"INDEX "bad "#.to_string(),
Some(FieldUnsupportedReason::UnsupportedSwitch),
),
]
);
assert!(doc.main_text().contains("cached malformed index"));
}
#[test]
fn docx_numbering_fields_compute_formatted_autonum_subset() {
let doc = Document::open(&numbering_field_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 14);
assert_eq!(fields[0].kind, FieldKind::Numbering("AUTONUM".to_string()));
assert_eq!(fields[0].instruction, "AUTONUM");
assert_eq!(fields[0].result, "stale autonum one");
assert_eq!(fields[0].computed_result.as_deref(), Some("1"));
assert_eq!(fields[1].kind, FieldKind::Numbering("AUTONUM".to_string()));
assert_eq!(fields[1].instruction, "AUTONUM \\* MERGEFORMAT");
assert_eq!(fields[1].result, "stale autonum two");
assert_eq!(fields[1].computed_result.as_deref(), Some("2"));
assert_eq!(fields[2].kind, FieldKind::Numbering("AUTONUM".to_string()));
assert_eq!(fields[2].instruction, "AUTONUM \\* roman");
assert_eq!(fields[2].result, "stale autonum roman");
assert_eq!(fields[2].computed_result.as_deref(), Some("iii"));
assert_eq!(fields[3].kind, FieldKind::Numbering("AUTONUM".to_string()));
assert_eq!(fields[3].instruction, "AUTONUM \\* Unknown");
assert_eq!(fields[3].result, "cached unsupported autonum");
assert_eq!(fields[3].computed_result, None);
assert_eq!(fields[4].kind, FieldKind::Numbering("AUTONUM".to_string()));
assert_eq!(fields[4].instruction, "AUTONUM");
assert_eq!(fields[4].result, "stale autonum after unsupported");
assert_eq!(fields[4].computed_result.as_deref(), Some("4"));
assert_eq!(fields[5].kind, FieldKind::Numbering("AUTONUM".to_string()));
assert_eq!(fields[5].instruction, "AUTONUM \\s.");
assert_eq!(fields[5].result, "stale autonum separator");
assert_eq!(fields[5].computed_result.as_deref(), Some("5."));
assert_eq!(fields[6].kind, FieldKind::Numbering("AUTONUM".to_string()));
assert_eq!(fields[6].instruction, "AUTONUM \\s \")\"");
assert_eq!(fields[6].result, "stale quoted autonum separator");
assert_eq!(fields[6].computed_result.as_deref(), Some("6)"));
assert_eq!(
fields[7].kind,
FieldKind::Numbering("AUTONUMLGL".to_string())
);
assert_eq!(fields[7].result, "cached legal number");
assert_eq!(fields[7].computed_result.as_deref(), Some("7"));
assert_eq!(
fields[8].kind,
FieldKind::Numbering("AUTONUMLGL".to_string())
);
assert_eq!(fields[8].instruction, "AUTONUMLGL \\* roman");
assert_eq!(fields[8].result, "cached legal roman");
assert_eq!(fields[8].computed_result.as_deref(), Some("viii"));
assert_eq!(
fields[9].kind,
FieldKind::Numbering("AUTONUMOUT".to_string())
);
assert_eq!(fields[9].result, "cached outline number");
assert_eq!(fields[9].computed_result.as_deref(), Some("9"));
assert_eq!(
fields[10].kind,
FieldKind::Numbering("AUTONUMOUT".to_string())
);
assert_eq!(fields[10].instruction, "AUTONUMOUT \\* roman");
assert_eq!(fields[10].result, "cached outline roman");
assert_eq!(fields[10].computed_result.as_deref(), Some("x"));
assert_eq!(fields[11].kind, FieldKind::Numbering("LISTNUM".to_string()));
assert_eq!(fields[11].instruction, "LISTNUM LegalDefault \\l 2");
assert_eq!(fields[11].result, "cached list number");
assert_eq!(fields[11].computed_result, None);
assert_eq!(
fields[12].kind,
FieldKind::Numbering("BIDIOUTLINE".to_string())
);
assert_eq!(fields[12].instruction, "BIDIOUTLINE");
assert_eq!(fields[12].result, "cached bidi outline");
assert_eq!(fields[12].computed_result.as_deref(), Some("11"));
assert_eq!(
fields[13].kind,
FieldKind::Numbering("BIDIOUTLINE".to_string())
);
assert_eq!(fields[13].instruction, "BIDIOUTLINE \\x");
assert_eq!(fields[13].result, "cached malformed bidi outline");
assert_eq!(fields[13].computed_result, None);
let report = doc.report();
assert_eq!(
report.features.unsupported_field_kinds,
vec![
FieldKindCount {
kind: FieldKind::Numbering("AUTONUM".to_string()),
count: 1,
},
FieldKindCount {
kind: FieldKind::Numbering("LISTNUM".to_string()),
count: 1,
},
FieldKindCount {
kind: FieldKind::Numbering("BIDIOUTLINE".to_string()),
count: 1,
},
]
);
assert_eq!(
report.features.unsupported_field_reasons,
vec![
FieldEvaluationReasonCount {
reason: FieldEvaluationReason::UnsupportedSwitch,
count: 2,
},
FieldEvaluationReasonCount {
reason: FieldEvaluationReason::NoComputedResult,
count: 1,
},
]
);
assert_eq!(
model_simple_field_reason_hints(&doc, |instruction| {
instruction.starts_with("AUTONUM \\* Unknown")
|| instruction.starts_with("LISTNUM LegalDefault")
|| instruction.starts_with("BIDIOUTLINE")
}),
vec![
(
"AUTONUM \\* Unknown".to_string(),
Some(FieldUnsupportedReason::UnsupportedSwitch),
),
(
"LISTNUM LegalDefault \\l 2".to_string(),
Some(FieldUnsupportedReason::NoComputedResult),
),
(
"BIDIOUTLINE \\x".to_string(),
Some(FieldUnsupportedReason::UnsupportedSwitch),
),
]
);
let main_text = doc.main_text();
assert!(
main_text.contains("1")
&& main_text.contains("2")
&& main_text.contains("iii")
&& main_text.contains("cached unsupported autonum")
&& main_text.contains("4")
&& main_text.contains("5.")
&& main_text.contains("6)")
&& main_text.contains("7")
&& main_text.contains("viii")
&& main_text.contains("9")
&& main_text.contains("x")
&& main_text.contains("cached list number")
&& main_text.contains("11")
&& main_text.contains("cached malformed bidi outline"),
"computed AUTONUM and cached remaining numbering field results should appear in main text: {main_text:?}"
);
assert!(
!main_text.contains("stale autonum one")
&& !main_text.contains("stale autonum two")
&& !main_text.contains("stale autonum roman")
&& !main_text.contains("stale autonum after unsupported")
&& !main_text.contains("stale autonum separator")
&& !main_text.contains("stale quoted autonum separator")
&& !main_text.contains("cached legal number")
&& !main_text.contains("cached legal roman")
&& !main_text.contains("cached outline number")
&& !main_text.contains("cached outline roman")
&& !main_text.contains("cached bidi outline"),
"computed automatic numbering fields should replace stale cached text: {main_text:?}"
);
}
#[test]
fn docx_bidioutline_computes_valid_format_tails() {
let doc = Document::open(&docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:fldSimple w:instr=" BIDIOUTLINE \* MERGEFORMAT "><w:r><w:t>cached bidi mergeformat</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" BIDIOUTLINE \* roman \* Upper "><w:r><w:t>cached bidi formatted</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" BIDIOUTLINE \* BadFormat "><w:r><w:t>cached bad bidi format</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
]))
.expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 3);
assert!(fields
.iter()
.all(|field| field.kind == FieldKind::Numbering("BIDIOUTLINE".to_string())));
assert_eq!(fields[0].instruction, "BIDIOUTLINE \\* MERGEFORMAT");
assert_eq!(fields[0].computed_result.as_deref(), Some("1"));
assert_eq!(fields[1].instruction, "BIDIOUTLINE \\* roman \\* Upper");
assert_eq!(fields[1].computed_result.as_deref(), Some("II"));
assert_eq!(fields[2].instruction, "BIDIOUTLINE \\* BadFormat");
assert_eq!(fields[2].computed_result, None);
let report = doc.report();
assert_eq!(
report.features.unsupported_field_kinds,
vec![FieldKindCount {
kind: FieldKind::Numbering("BIDIOUTLINE".to_string()),
count: 1,
}]
);
assert_eq!(
report.features.unsupported_field_reasons,
vec![FieldEvaluationReasonCount {
reason: FieldEvaluationReason::UnsupportedSwitch,
count: 1,
}]
);
let main_text = doc.main_text();
assert!(main_text.contains("1"));
assert!(main_text.contains("II"));
assert!(!main_text.contains("cached bidi mergeformat"));
assert!(!main_text.contains("cached bidi formatted"));
assert!(main_text.contains("cached bad bidi format"));
}
#[test]
fn docx_listnum_number_default_computes_level_one_subset() {
let doc = Document::open(&listnum_number_default_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 10);
assert!(fields
.iter()
.all(|field| field.kind == FieldKind::Numbering("LISTNUM".to_string())));
assert_eq!(fields[0].instruction, "LISTNUM NumberDefault");
assert_eq!(fields[0].result, "stale listnum one");
assert_eq!(fields[0].computed_result.as_deref(), Some("1"));
assert_eq!(
fields[1].instruction,
"LISTNUM NumberDefault \\* MERGEFORMAT"
);
assert_eq!(fields[1].result, "stale listnum mergeformat");
assert_eq!(fields[1].computed_result.as_deref(), Some("2"));
assert_eq!(fields[2].instruction, "LISTNUM NumberDefault \\*CHARFORMAT");
assert_eq!(fields[2].result, "stale listnum charformat");
assert_eq!(fields[2].computed_result.as_deref(), Some("3"));
assert_eq!(fields[3].instruction, "LISTNUM NumberDefault \\s 4");
assert_eq!(fields[3].result, "stale listnum reset");
assert_eq!(fields[3].computed_result.as_deref(), Some("4"));
assert_eq!(fields[4].instruction, "LISTNUM NumberDefault");
assert_eq!(fields[4].result, "stale listnum after reset");
assert_eq!(fields[4].computed_result.as_deref(), Some("5"));
assert_eq!(fields[5].instruction, "LISTNUM NumberDefault \\* roman");
assert_eq!(fields[5].result, "stale listnum roman");
assert_eq!(fields[5].computed_result.as_deref(), Some("vi"));
assert_eq!(fields[6].instruction, "LISTNUM NumberDefault \\l 2");
assert_eq!(fields[6].result, "cached nested listnum");
assert_eq!(fields[6].computed_result, None);
assert_eq!(fields[7].instruction, "LISTNUM LegalDefault");
assert_eq!(fields[7].result, "cached legal listnum");
assert_eq!(fields[7].computed_result.as_deref(), Some("7"));
assert_eq!(fields[8].instruction, "LISTNUM \"NumberDefault\"");
assert_eq!(fields[8].result, "stale quoted listnum");
assert_eq!(fields[8].computed_result.as_deref(), Some("8"));
assert_eq!(fields[9].instruction, "LISTNUM");
assert_eq!(fields[9].result, "stale unnamed listnum");
assert_eq!(fields[9].computed_result.as_deref(), Some("9"));
let report = doc.report();
assert_eq!(
report.features.unsupported_field_kinds,
vec![FieldKindCount {
kind: FieldKind::Numbering("LISTNUM".to_string()),
count: 1,
}]
);
assert_eq!(
report.features.unsupported_field_reasons,
vec![FieldEvaluationReasonCount {
reason: FieldEvaluationReason::NoComputedResult,
count: 1,
}]
);
assert_eq!(
model_simple_field_reason_hints(&doc, |instruction| {
instruction.starts_with("LISTNUM NumberDefault \\l 2")
}),
vec![(
"LISTNUM NumberDefault \\l 2".to_string(),
Some(FieldUnsupportedReason::NoComputedResult),
)]
);
let main_text = doc.main_text();
assert!(
main_text.contains("1")
&& main_text.contains("2")
&& main_text.contains("3")
&& main_text.contains("4")
&& main_text.contains("5")
&& main_text.contains("vi")
&& main_text.contains("cached nested listnum")
&& main_text.contains("7")
&& main_text.contains("8")
&& main_text.contains("9"),
"computed listnum values and unsupported cached results should be visible: {main_text:?}"
);
assert!(
!main_text.contains("stale listnum one")
&& !main_text.contains("stale listnum mergeformat")
&& !main_text.contains("stale listnum charformat")
&& !main_text.contains("stale listnum reset")
&& !main_text.contains("stale listnum after reset")
&& !main_text.contains("stale listnum roman")
&& !main_text.contains("cached legal listnum")
&& !main_text.contains("stale quoted listnum")
&& !main_text.contains("stale unnamed listnum"),
"computed listnum results should replace stale cached field text: {main_text:?}"
);
}
#[test]
fn docx_sequence_and_numbering_fields_apply_text_format_switches() {
let doc = Document::open(&sequence_numbering_text_format_field_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 7);
assert_eq!(fields[0].kind, FieldKind::Sequence);
assert_eq!(fields[0].instruction, "SEQ Figure \\* CardText \\* Upper");
assert_eq!(fields[0].computed_result.as_deref(), Some("ONE"));
assert_eq!(fields[1].kind, FieldKind::Sequence);
assert_eq!(fields[1].instruction, "SEQ Figure \\* roman \\* Upper");
assert_eq!(fields[1].computed_result.as_deref(), Some("II"));
assert_eq!(fields[2].kind, FieldKind::Sequence);
assert_eq!(fields[2].instruction, "SEQ Invoice \\r 21 \\* DollarText");
assert_eq!(
fields[2].computed_result.as_deref(),
Some("twenty-one and 00/100")
);
assert_eq!(fields[3].kind, FieldKind::Numbering("AUTONUM".to_string()));
assert_eq!(fields[3].instruction, "AUTONUM \\* CardText \\* Upper");
assert_eq!(fields[3].computed_result.as_deref(), Some("ONE"));
assert_eq!(fields[4].kind, FieldKind::Numbering("AUTONUM".to_string()));
assert_eq!(fields[4].instruction, "AUTONUM \\* roman \\* Upper");
assert_eq!(fields[4].computed_result.as_deref(), Some("II"));
assert_eq!(fields[5].kind, FieldKind::Numbering("LISTNUM".to_string()));
assert_eq!(
fields[5].instruction,
"LISTNUM NumberDefault \\* CardText \\* Upper"
);
assert_eq!(fields[5].computed_result.as_deref(), Some("ONE"));
assert_eq!(fields[6].kind, FieldKind::Numbering("LISTNUM".to_string()));
assert_eq!(
fields[6].instruction,
"LISTNUM NumberDefault \\* roman \\* Upper"
);
assert_eq!(fields[6].computed_result.as_deref(), Some("II"));
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
let main_text = doc.main_text();
assert!(
!main_text.contains("stale sequence card")
&& !main_text.contains("stale sequence roman")
&& !main_text.contains("stale sequence dollars")
&& !main_text.contains("stale autonum card")
&& !main_text.contains("stale autonum roman")
&& !main_text.contains("stale listnum card")
&& !main_text.contains("stale listnum roman"),
"formatted sequence and numbering fields should replace stale cached text: {main_text:?}"
);
}
#[test]
fn docx_document_structure_fields_are_named_and_section_is_computed() {
let doc = Document::open(&document_structure_field_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 6);
assert_eq!(
fields[0].kind,
FieldKind::DocumentStructure("REVNUM".to_string())
);
assert_eq!(fields[0].instruction, "REVNUM");
assert_eq!(fields[0].result, "4");
assert_eq!(fields[0].computed_result.as_deref(), Some("12"));
assert_eq!(
fields[1].kind,
FieldKind::DocumentStructure("SECTION".to_string())
);
assert_eq!(fields[1].result, "2");
assert_eq!(fields[1].computed_result.as_deref(), Some("1"));
assert_eq!(
fields[2].kind,
FieldKind::DocumentStructure("SECTIONPAGES".to_string())
);
assert_eq!(fields[2].result, "5");
assert_eq!(fields[2].computed_result, None);
assert_eq!(
fields[3].kind,
FieldKind::DocumentStructure("STYLEREF".to_string())
);
assert_eq!(fields[3].instruction, "STYLEREF \"Heading 1\" \\n");
assert_eq!(fields[3].result, "Executive Summary");
assert_eq!(fields[3].computed_result, None);
assert_eq!(
fields[4].kind,
FieldKind::DocumentStructure("STYLEREF".to_string())
);
assert_eq!(fields[4].instruction, "STYLEREF \"Heading 1 ");
assert_eq!(fields[4].result, "cached broken style ref");
assert_eq!(fields[4].computed_result, None);
assert_eq!(
fields[5].kind,
FieldKind::DocumentStructure("STYLEREF".to_string())
);
assert_eq!(fields[5].instruction, "STYLEREF \\p \"Heading 1\"");
assert_eq!(fields[5].result, "cached switch-first style ref");
assert_eq!(fields[5].computed_result, None);
let report = doc.report();
assert_eq!(
report.features.unsupported_field_kinds,
vec![
FieldKindCount {
kind: FieldKind::DocumentStructure("SECTIONPAGES".to_string()),
count: 1,
},
FieldKindCount {
kind: FieldKind::DocumentStructure("STYLEREF".to_string()),
count: 3,
},
]
);
assert_eq!(
report.features.unsupported_field_reasons,
vec![
FieldEvaluationReasonCount {
reason: FieldEvaluationReason::NoComputedResult,
count: 3,
},
FieldEvaluationReasonCount {
reason: FieldEvaluationReason::UnsupportedSwitch,
count: 1,
},
]
);
assert_eq!(
model_simple_field_reason_hints(&doc, |instruction| {
instruction.starts_with("SECTIONPAGES") || instruction.starts_with("STYLEREF")
}),
vec![
(
"SECTIONPAGES".to_string(),
Some(FieldUnsupportedReason::NoComputedResult),
),
(
"STYLEREF \"Heading 1\" \\n".to_string(),
Some(FieldUnsupportedReason::NoComputedResult),
),
(
"STYLEREF \"Heading 1 ".to_string(),
Some(FieldUnsupportedReason::UnsupportedSwitch),
),
(
"STYLEREF \\p \"Heading 1\"".to_string(),
Some(FieldUnsupportedReason::NoComputedResult),
),
]
);
let main_text = doc.main_text();
assert!(
main_text.contains("12")
&& main_text.contains("1")
&& main_text.contains("5")
&& main_text.contains("Executive Summary")
&& main_text.contains("cached broken style ref")
&& main_text.contains("cached switch-first style ref"),
"computed REVNUM/SECTION and cached remaining document-structure fields should appear in main text: {main_text:?}"
);
assert!(
!main_text.contains("4"),
"computed REVNUM should replace stale cached revision text: {main_text:?}"
);
}
#[test]
fn docx_document_structure_diagnostics_reject_unknown_switches() {
let doc = Document::open(&docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:fldSimple w:instr=" REVNUM \x "><w:r><w:t>cached bad revision</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" SECTIONPAGES \x "><w:r><w:t>cached bad section pages</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
]))
.expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 2);
assert_eq!(
fields[0].kind,
FieldKind::DocumentStructure("REVNUM".to_string())
);
assert_eq!(fields[0].instruction, "REVNUM \\x");
assert_eq!(fields[0].computed_result, None);
assert_eq!(
fields[1].kind,
FieldKind::DocumentStructure("SECTIONPAGES".to_string())
);
assert_eq!(fields[1].instruction, "SECTIONPAGES \\x");
assert_eq!(fields[1].computed_result, None);
let report = doc.report();
assert_eq!(
report.features.unsupported_field_kinds,
vec![
FieldKindCount {
kind: FieldKind::DocumentStructure("REVNUM".to_string()),
count: 1,
},
FieldKindCount {
kind: FieldKind::DocumentStructure("SECTIONPAGES".to_string()),
count: 1,
},
]
);
assert_eq!(
report.features.unsupported_field_reasons,
vec![FieldEvaluationReasonCount {
reason: FieldEvaluationReason::UnsupportedSwitch,
count: 2,
}]
);
assert_eq!(
model_simple_field_reason_hints(&doc, |instruction| {
instruction.starts_with("REVNUM") || instruction.starts_with("SECTIONPAGES")
}),
vec![
(
"REVNUM \\x".to_string(),
Some(FieldUnsupportedReason::UnsupportedSwitch),
),
(
"SECTIONPAGES \\x".to_string(),
Some(FieldUnsupportedReason::UnsupportedSwitch),
),
]
);
}
#[test]
fn docx_revnum_field_computes_with_text_format_switches() {
let doc = Document::open(&revision_number_text_format_docx()).expect("fixture opens");
let fields = doc.fields();
let expected = [
("REVNUM \\* Upper", "stale upper revision", "DRAFT REVISION"),
("REVNUM \\*Lower", "stale lower revision", "draft revision"),
("REVNUM \\* Caps", "stale caps revision", "Draft REVISION"),
(
"REVNUM \\* FirstCap",
"stale first-cap revision",
"Draft REVISION",
),
];
assert_eq!(fields.len(), expected.len());
for (field, (instruction, result, computed)) in fields.iter().zip(expected) {
assert_eq!(
field.kind,
FieldKind::DocumentStructure("REVNUM".to_string())
);
assert_eq!(field.instruction, instruction);
assert_eq!(field.result, result);
assert_eq!(field.computed_result.as_deref(), Some(computed));
}
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
let main_text = doc.main_text();
for computed in [
"DRAFT REVISION",
"draft revision",
"Draft REVISION",
"Draft REVISION",
] {
assert!(
main_text.contains(computed),
"formatted REVNUM output should be materialized: {main_text:?}"
);
}
assert!(
!main_text.contains("stale"),
"formatted REVNUM fields should replace stale cached text: {main_text:?}"
);
}
#[test]
fn docx_docproperty_revision_number_matches_revnum() {
let doc = Document::open(&doc_property_revision_number_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 2);
for field in &fields {
assert_eq!(
field.kind,
FieldKind::DocumentInfo("DOCPROPERTY".to_string())
);
assert_eq!(field.computed_result.as_deref(), Some("12"));
}
assert_eq!(fields[0].instruction, "DOCPROPERTY RevisionNumber");
assert_eq!(fields[0].result, "stale revnum property");
assert_eq!(fields[1].instruction, "DOCPROPERTY \"Revision Number\"");
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
let main_text = doc.main_text();
assert!(
main_text.contains("12")
&& !main_text.contains("stale revnum property")
&& !main_text.contains("stale spaced revnum"),
"DOCPROPERTY RevisionNumber should compute the core revision: {main_text:?}"
);
}
#[test]
fn docx_docproperty_last_author_matches_last_modified_by() {
let doc = Document::open(&doc_property_last_author_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 2);
for field in &fields {
assert_eq!(
field.kind,
FieldKind::DocumentInfo("DOCPROPERTY".to_string())
);
assert_eq!(field.computed_result.as_deref(), Some("Dana Reviewer"));
}
assert_eq!(fields[0].instruction, "DOCPROPERTY \"Last Author\"");
assert_eq!(fields[0].result, "stale author name");
assert_eq!(fields[1].instruction, "DOCPROPERTY LastAuthor");
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
let main_text = doc.main_text();
assert!(
main_text.contains("Dana Reviewer") && !main_text.contains("stale author name"),
"DOCPROPERTY Last Author should compute cp:lastModifiedBy: {main_text:?}"
);
}
#[test]
fn docx_fields_with_context_compute_date_time_and_user_fields() {
let doc = Document::open(&context_document_info_docx()).expect("fixture opens");
// Context-free extraction keeps volatile fields cached-only, except the
// explicit USERNAME literal override that already computes today.
let plain = doc.fields();
assert_eq!(plain.len(), 5);
assert_eq!(plain[0].computed_result, None);
assert_eq!(plain[1].computed_result, None);
assert_eq!(plain[2].computed_result, None);
assert_eq!(plain[3].computed_result, None);
assert_eq!(plain[4].computed_result.as_deref(), Some("Override Name"));
let context = rwml::FieldContext::new()
.now("2026-07-03T10:30:00Z")
.user_name("Dana Reviewer");
let fields = doc.fields_with_context(&context);
assert_eq!(fields.len(), 5);
assert_eq!(fields[0].instruction, "DATE \\@ \"yyyy-MM-dd\"");
assert_eq!(fields[0].result, "stale cached date");
assert_eq!(fields[0].computed_result.as_deref(), Some("2026-07-03"));
assert_eq!(fields[1].computed_result.as_deref(), Some("10:30"));
// A pictureless DATE would need a locale-default picture: stays cached.
assert_eq!(fields[2].computed_result, None);
assert_eq!(fields[3].computed_result.as_deref(), Some("Dana Reviewer"));
// Explicit literal overrides win over caller context.
assert_eq!(fields[4].computed_result.as_deref(), Some("Override Name"));
}
#[test]
fn docx_fields_with_context_ignores_malformed_or_missing_context() {
let doc = Document::open(&context_document_info_docx()).expect("fixture opens");
let malformed = rwml::FieldContext::new().now("not a timestamp");
let fields = doc.fields_with_context(&malformed);
assert_eq!(fields[0].computed_result, None);
assert_eq!(fields[1].computed_result, None);
assert_eq!(fields[3].computed_result, None);
let empty = rwml::FieldContext::new();
let fields = doc.fields_with_context(&empty);
assert_eq!(fields[0].computed_result, None);
assert_eq!(fields[3].computed_result, None);
assert_eq!(fields[4].computed_result.as_deref(), Some("Override Name"));
}
#[test]
fn docx_fields_with_context_compute_merge_and_include_text_fields() {
let doc = Document::open(&context_merge_include_docx()).expect("fixture opens");
let plain = doc.fields();
assert_eq!(plain.len(), 4);
assert_eq!(plain[0].kind, FieldKind::MergeField);
assert_eq!(plain[0].instruction, r#"MERGEFIELD "Client Name" \* Upper"#);
assert_eq!(plain[0].computed_result, None);
assert_eq!(plain[1].kind, FieldKind::MergeField);
assert_eq!(plain[1].computed_result, None);
assert_eq!(
plain[2].kind,
FieldKind::InsertedContent("INCLUDETEXT".to_string())
);
assert_eq!(plain[2].instruction, r#"INCLUDETEXT "appendix.docx""#);
assert_eq!(plain[2].computed_result, None);
assert_eq!(
plain[3].kind,
FieldKind::InsertedContent("INCLUDETEXT".to_string())
);
assert_eq!(plain[3].computed_result, None);
let context = rwml::FieldContext::new()
.merge_value("client_name", "Acme LLC")
.include_text("appendix.docx", "External appendix");
let fields = doc.fields_with_context(&context);
assert_eq!(fields.len(), 4);
assert_eq!(fields[0].result, "stale client");
assert_eq!(fields[0].computed_result.as_deref(), Some("ACME LLC"));
assert_eq!(fields[1].result, "stale uncovered merge");
assert_eq!(fields[1].computed_result, None);
assert_eq!(fields[2].result, "stale appendix");
assert_eq!(
fields[2].computed_result.as_deref(),
Some("External appendix")
);
assert_eq!(fields[3].result, "stale missing include");
assert_eq!(fields[3].computed_result, None);
let empty = rwml::FieldContext::new();
let fields = doc.fields_with_context(&empty);
assert!(fields.iter().all(|field| field.computed_result.is_none()));
}
#[test]
fn docx_numeric_document_info_fields_apply_star_number_format() {
let doc = Document::open(&numeric_doc_info_star_format_docx()).expect("fixture opens");
let fields = doc.fields();
let expected = [
("NUMPAGES \\* roman", "stale roman pages", "xii"),
("NUMPAGES \\* ROMAN", "stale upper roman pages", "XII"),
("NUMPAGES \\* Arabic", "stale arabic pages", "12"),
("NUMWORDS \\* Ordinal", "stale ordinal words", "321st"),
];
assert_eq!(fields.len(), expected.len());
for (field, (instruction, result, computed)) in fields.iter().zip(expected) {
assert_eq!(field.instruction, instruction);
assert_eq!(field.result, result);
assert_eq!(field.computed_result.as_deref(), Some(computed));
}
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
let main_text = doc.main_text();
assert!(
main_text.contains("xii")
&& main_text.contains("XII")
&& main_text.contains("321st")
&& !main_text.contains("stale"),
"numeric document-info fields should apply the number format: {main_text:?}"
);
}
#[test]
fn docx_edittime_document_info_field_applies_star_number_format() {
let doc = Document::open(&edittime_number_format_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 2);
for field in &fields {
assert_eq!(field.kind, FieldKind::DocumentInfo("EDITTIME".to_string()));
}
assert_eq!(fields[0].instruction, "EDITTIME \\* roman");
assert_eq!(fields[0].computed_result.as_deref(), Some("vii"));
assert_eq!(fields[1].instruction, "EDITTIME \\* Arabic");
assert_eq!(fields[1].computed_result.as_deref(), Some("7"));
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
}
#[test]
fn docx_section_field_computes_current_structural_section_number() {
let doc = Document::open(§ion_field_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 3);
for field in &fields {
assert_eq!(
field.kind,
FieldKind::DocumentStructure("SECTION".to_string())
);
}
assert_eq!(fields[0].instruction, "SECTION");
assert_eq!(fields[0].computed_result.as_deref(), Some("1"));
assert_eq!(fields[1].instruction, "SECTION");
assert_eq!(fields[1].computed_result.as_deref(), Some("2"));
assert_eq!(fields[2].instruction, "SECTION \\* MERGEFORMAT");
assert_eq!(fields[2].computed_result.as_deref(), Some("3"));
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
let main_text = doc.main_text();
assert!(
!main_text.contains("stale first section")
&& !main_text.contains("stale second section")
&& !main_text.contains("stale third section"),
"computed SECTION fields should replace stale cached text: {main_text:?}"
);
assert!(main_text.contains("1"), "{main_text:?}");
assert!(main_text.contains("2"), "{main_text:?}");
assert!(main_text.contains("3"), "{main_text:?}");
}
#[test]
fn docx_section_field_computes_with_number_and_text_format_switches() {
let doc = Document::open(§ion_field_text_format_docx()).expect("fixture opens");
let fields = doc.fields();
let expected = [
("SECTION \\* ROMAN", "stale roman section", "I"),
(
"SECTION \\* CardText \\* Upper",
"stale card section",
"TWO",
),
("SECTION \\* Ordinal", "stale ordinal section", "3rd"),
];
assert_eq!(fields.len(), expected.len());
for (field, (instruction, result, computed)) in fields.iter().zip(expected) {
assert_eq!(
field.kind,
FieldKind::DocumentStructure("SECTION".to_string())
);
assert_eq!(field.instruction, instruction);
assert_eq!(field.result, result);
assert_eq!(field.computed_result.as_deref(), Some(computed));
}
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
let main_text = doc.main_text();
for computed in ["I", "TWO", "3rd"] {
assert!(
main_text.contains(computed),
"formatted SECTION output should be materialized: {main_text:?}"
);
}
assert!(
!main_text.contains("stale"),
"formatted SECTION fields should replace stale cached text: {main_text:?}"
);
}
#[test]
fn docx_section_field_invalid_switch_does_not_shift_later_fields() {
let doc =
Document::open(§ion_field_invalid_switch_alignment_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 2);
assert_eq!(
fields[0].kind,
FieldKind::DocumentStructure("SECTION".to_string())
);
assert_eq!(fields[0].instruction, "SECTION \\* Unknown");
assert_eq!(fields[0].computed_result, None);
assert_eq!(
fields[1].kind,
FieldKind::DocumentStructure("SECTION".to_string())
);
assert_eq!(fields[1].instruction, "SECTION");
assert_eq!(fields[1].computed_result.as_deref(), Some("1"));
let report = doc.report();
assert_eq!(
report.features.unsupported_field_kinds,
vec![FieldKindCount {
kind: FieldKind::DocumentStructure("SECTION".to_string()),
count: 1,
}]
);
assert_eq!(
report.features.unsupported_field_reasons,
vec![FieldEvaluationReasonCount {
reason: FieldEvaluationReason::UnsupportedSwitch,
count: 1,
}]
);
let main_text = doc.main_text();
assert!(
main_text.contains("cached invalid section"),
"{main_text:?}"
);
assert!(!main_text.contains("stale valid section"), "{main_text:?}");
assert!(main_text.contains("1"), "{main_text:?}");
}
#[test]
fn docx_section_context_uses_single_alternate_content_branch() {
let doc = Document::open(§ion_alternate_content_break_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 1);
assert_eq!(
fields[0].kind,
FieldKind::DocumentStructure("SECTION".to_string())
);
assert_eq!(fields[0].computed_result.as_deref(), Some("2"));
}
#[test]
fn docx_section_pages_field_computes_structural_section_page_count() {
let doc = Document::open(§ion_pages_field_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 4);
for field in &fields {
assert_eq!(
field.kind,
FieldKind::DocumentStructure("SECTIONPAGES".to_string())
);
}
assert_eq!(fields[0].instruction, "SECTIONPAGES");
assert_eq!(fields[0].computed_result.as_deref(), Some("3"));
assert_eq!(fields[1].instruction, "SECTIONPAGES \\* ROMAN");
assert_eq!(fields[1].computed_result.as_deref(), Some("III"));
assert_eq!(fields[2].instruction, "SECTIONPAGES \\* CardText \\* Upper");
assert_eq!(fields[2].computed_result.as_deref(), Some("THREE"));
assert_eq!(fields[3].instruction, "SECTIONPAGES \\* Ordinal");
assert_eq!(fields[3].computed_result.as_deref(), Some("1st"));
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
let main_text = doc.main_text();
assert!(main_text.contains("3"), "{main_text:?}");
assert!(main_text.contains("III"), "{main_text:?}");
assert!(main_text.contains("THREE"), "{main_text:?}");
assert!(main_text.contains("1st"), "{main_text:?}");
}
#[test]
fn docx_section_pages_cached_result_text_does_not_block_structural_count() {
let doc = Document::open(§ion_pages_cached_result_text_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 2);
assert_eq!(
fields[0].kind,
FieldKind::DocumentStructure("SECTIONPAGES".to_string())
);
assert_eq!(fields[0].instruction, "SECTIONPAGES");
assert_eq!(fields[0].result, "stale pages");
assert_eq!(fields[0].computed_result.as_deref(), Some("2"));
assert_eq!(
fields[1].kind,
FieldKind::DocumentStructure("SECTIONPAGES".to_string())
);
assert_eq!(fields[1].instruction, "SECTIONPAGES \\* ROMAN");
assert_eq!(fields[1].result, "stale roman pages");
assert_eq!(fields[1].computed_result.as_deref(), Some("II"));
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
let main_text = doc.main_text();
assert!(main_text.contains("2"), "{main_text:?}");
assert!(main_text.contains("II"), "{main_text:?}");
assert!(
!main_text.contains("stale pages") && !main_text.contains("stale roman pages"),
"computed SECTIONPAGES should replace stale cached result text: {main_text:?}"
);
}
#[test]
fn docx_section_pages_symbol_content_keeps_cached_text() {
let doc = Document::open(§ion_pages_symbol_content_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 1);
assert_eq!(
fields[0].kind,
FieldKind::DocumentStructure("SECTIONPAGES".to_string())
);
assert_eq!(fields[0].instruction, "SECTIONPAGES");
assert_eq!(fields[0].result, "");
assert_eq!(fields[0].computed_result, None);
let report = doc.report();
assert_eq!(
report.features.unsupported_field_kinds,
vec![FieldKindCount {
kind: FieldKind::DocumentStructure("SECTIONPAGES".to_string()),
count: 1,
}]
);
assert_eq!(
report.features.unsupported_field_reasons,
vec![FieldEvaluationReasonCount {
reason: FieldEvaluationReason::NoComputedResult,
count: 1,
}]
);
}
#[test]
fn docx_section_pages_note_mark_content_keeps_cached_text() {
let doc = Document::open(§ion_pages_note_mark_content_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 1);
assert_eq!(
fields[0].kind,
FieldKind::DocumentStructure("SECTIONPAGES".to_string())
);
assert_eq!(fields[0].instruction, "SECTIONPAGES");
assert_eq!(fields[0].result, "");
assert_eq!(fields[0].computed_result, None);
let report = doc.report();
assert_eq!(
report.features.unsupported_field_kinds,
vec![FieldKindCount {
kind: FieldKind::DocumentStructure("SECTIONPAGES".to_string()),
count: 1,
}]
);
assert_eq!(
report.features.unsupported_field_reasons,
vec![FieldEvaluationReasonCount {
reason: FieldEvaluationReason::NoComputedResult,
count: 1,
}]
);
}
#[test]
fn docx_section_pages_endnote_mark_content_keeps_cached_text() {
let doc = Document::open(§ion_pages_endnote_mark_content_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 1);
assert_eq!(
fields[0].kind,
FieldKind::DocumentStructure("SECTIONPAGES".to_string())
);
assert_eq!(fields[0].instruction, "SECTIONPAGES");
assert_eq!(fields[0].result, "");
assert_eq!(fields[0].computed_result, None);
let report = doc.report();
assert_eq!(
report.features.unsupported_field_kinds,
vec![FieldKindCount {
kind: FieldKind::DocumentStructure("SECTIONPAGES".to_string()),
count: 1,
}]
);
assert_eq!(
report.features.unsupported_field_reasons,
vec![FieldEvaluationReasonCount {
reason: FieldEvaluationReason::NoComputedResult,
count: 1,
}]
);
}
#[test]
fn docx_section_pages_ignores_stale_note_mark_inside_computed_field_results() {
let doc =
Document::open(§ion_pages_stale_computed_field_marker_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 3);
assert_eq!(fields[0].kind, FieldKind::Dynamic("SET".to_string()));
assert_eq!(fields[0].instruction, r#"SET SimpleHidden "Plain""#);
assert_eq!(fields[0].computed_result.as_deref(), Some(""));
assert_eq!(fields[1].kind, FieldKind::Dynamic("SET".to_string()));
assert_eq!(fields[1].instruction, r#"SET ComplexHidden "Plain""#);
assert_eq!(fields[1].computed_result.as_deref(), Some(""));
assert_eq!(
fields[2].kind,
FieldKind::DocumentStructure("SECTIONPAGES".to_string())
);
assert_eq!(fields[2].instruction, "SECTIONPAGES");
assert_eq!(fields[2].result, "cached section pages");
assert_eq!(fields[2].computed_result.as_deref(), Some("1"));
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
let main_text = doc.main_text();
assert!(
main_text.contains('1')
&& !main_text.contains("cached section pages")
&& !main_text.contains('\u{0002}'),
"SECTIONPAGES should ignore stale markers hidden inside computed field results: {main_text:?}"
);
}
#[test]
fn docx_section_pages_uses_empty_document_info_result_for_content_scan() {
let doc =
Document::open(§ion_pages_empty_document_info_result_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 2);
assert_eq!(fields[0].kind, FieldKind::DocumentInfo("TITLE".to_string()));
assert_eq!(fields[0].instruction, "TITLE");
assert_eq!(fields[0].result, "stale section title");
assert_eq!(fields[0].computed_result.as_deref(), Some(""));
assert_eq!(
fields[1].kind,
FieldKind::DocumentStructure("SECTIONPAGES".to_string())
);
assert_eq!(fields[1].instruction, "SECTIONPAGES");
assert_eq!(fields[1].result, "cached section pages");
assert_eq!(fields[1].computed_result.as_deref(), Some("1"));
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
let main_text = doc.main_text();
assert!(
main_text.contains('1')
&& !main_text.contains("stale section title")
&& !main_text.contains("cached section pages"),
"SECTIONPAGES should use computed empty document-info output when deciding section content: {main_text:?}"
);
}
#[test]
fn docx_section_pages_ignores_stale_empty_ref_result() {
let doc = Document::open(§ion_pages_empty_ref_result_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 2);
assert_eq!(fields[0].kind, FieldKind::Ref);
assert_eq!(fields[0].instruction, "REF EmptyTarget");
assert_eq!(fields[0].result, "stale empty section ref");
assert_eq!(fields[0].computed_result.as_deref(), Some(""));
assert_eq!(
fields[1].kind,
FieldKind::DocumentStructure("SECTIONPAGES".to_string())
);
assert_eq!(fields[1].instruction, "SECTIONPAGES");
assert_eq!(fields[1].result, "cached section pages");
assert_eq!(fields[1].computed_result.as_deref(), Some("1"));
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
let main_text = doc.main_text();
assert!(
main_text.contains('1')
&& !main_text.contains("stale empty section ref")
&& !main_text.contains("cached section pages"),
"SECTIONPAGES should use computed empty REF output when deciding section content: {main_text:?}"
);
}
#[test]
fn docx_section_pages_ignores_stale_empty_direct_bookmark_result() {
let doc =
Document::open(§ion_pages_empty_direct_bookmark_result_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 2);
assert_eq!(fields[0].kind, FieldKind::Ref);
assert_eq!(fields[0].instruction, "EmptyTarget");
assert_eq!(fields[0].result, "stale empty direct section ref");
assert_eq!(fields[0].computed_result.as_deref(), Some(""));
assert_eq!(
fields[1].kind,
FieldKind::DocumentStructure("SECTIONPAGES".to_string())
);
assert_eq!(fields[1].instruction, "SECTIONPAGES");
assert_eq!(fields[1].result, "cached section pages");
assert_eq!(fields[1].computed_result.as_deref(), Some("1"));
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
let main_text = doc.main_text();
assert!(
main_text.contains('1')
&& !main_text.contains("stale empty direct section ref")
&& !main_text.contains("cached section pages"),
"SECTIONPAGES should use computed empty direct bookmark output when deciding section content: {main_text:?}"
);
}
#[test]
fn docx_style_ref_field_computes_nearest_paragraph_style_text() {
let doc = Document::open(&style_ref_field_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 6);
for field in &fields {
assert_eq!(
field.kind,
FieldKind::DocumentStructure("STYLEREF".to_string())
);
}
assert_eq!(fields[0].instruction, "STYLEREF \"heading 1\"");
assert_eq!(
fields[0].computed_result.as_deref(),
Some("Executive Summary")
);
assert_eq!(fields[1].instruction, "STYLEREF \"heading 1\" \\p");
assert_eq!(fields[1].computed_result.as_deref(), Some("above"));
assert_eq!(fields[2].instruction, "STYLEREF \\p \"heading 1\"");
assert_eq!(fields[2].computed_result.as_deref(), Some("above"));
assert_eq!(fields[3].instruction, "STYLEREF CustomCallout");
assert_eq!(
fields[3].computed_result.as_deref(),
Some("Forward Finding")
);
assert_eq!(
fields[4].instruction,
"STYLEREF CustomCallout \\p \\* Upper"
);
assert_eq!(fields[4].computed_result.as_deref(), Some("BELOW"));
assert_eq!(
fields[5].instruction,
"STYLEREF \"Custom Heading\" \\* MERGEFORMAT"
);
assert_eq!(
fields[5].computed_result.as_deref(),
Some("Forward Finding")
);
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
let main_text = doc.main_text();
assert!(
!main_text.contains("stale heading style")
&& !main_text.contains("stale heading relative")
&& !main_text.contains("stale switch-first heading relative")
&& !main_text.contains("stale forward style")
&& !main_text.contains("stale forward relative")
&& !main_text.contains("stale custom style"),
"computed STYLEREF fields should replace stale cached text: {main_text:?}"
);
let model = doc.model();
let paragraph_style_ids = model
.blocks
.iter()
.filter_map(|block| match block {
Block::Paragraph(paragraph) => paragraph.props.style_id.as_deref(),
_ => None,
})
.collect::<Vec<_>>();
assert_eq!(paragraph_style_ids, vec!["Heading1", "CustomCallout"]);
let paragraph_text = model
.blocks
.iter()
.filter_map(|block| match block {
Block::Paragraph(paragraph) => Some(paragraph.text()),
_ => None,
})
.collect::<Vec<_>>();
assert_eq!(
paragraph_text,
vec![
"Executive Summary".to_string(),
"Executive Summary".to_string(),
"above".to_string(),
"above".to_string(),
"Forward Finding".to_string(),
"BELOW".to_string(),
"Forward Finding".to_string(),
"Forward Finding".to_string(),
]
);
}
#[test]
fn docx_style_ref_accepts_unquoted_multi_token_style_names() {
let doc =
Document::open(&style_ref_unquoted_multi_token_style_name_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 2);
for field in &fields {
assert_eq!(
field.kind,
FieldKind::DocumentStructure("STYLEREF".to_string())
);
}
assert_eq!(fields[0].instruction, "STYLEREF Heading 1 \\* Upper");
assert_eq!(fields[0].result, "stale unquoted heading");
assert_eq!(
fields[0].computed_result.as_deref(),
Some("EXECUTIVE SUMMARY")
);
assert_eq!(
fields[1].instruction,
"STYLEREF Custom Heading \\* MERGEFORMAT"
);
assert_eq!(fields[1].result, "stale unquoted custom style");
assert_eq!(
fields[1].computed_result.as_deref(),
Some("Forward Finding")
);
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
let main_text = doc.main_text();
assert!(
!main_text.contains("stale unquoted heading")
&& !main_text.contains("stale unquoted custom style"),
"unquoted multi-token STYLEREF style names should compute: {main_text:?}"
);
assert!(main_text.contains("EXECUTIVE SUMMARY"), "{main_text:?}");
assert!(main_text.contains("Forward Finding"), "{main_text:?}");
}
#[test]
fn docx_style_ref_context_ignores_deleted_styled_paragraphs() {
let doc = Document::open(&style_ref_deleted_heading_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 1);
assert_eq!(
fields[0].kind,
FieldKind::DocumentStructure("STYLEREF".to_string())
);
assert_eq!(fields[0].instruction, "STYLEREF \"heading 1\"");
assert_eq!(
fields[0].computed_result.as_deref(),
Some("Visible Heading")
);
let main_text = doc.main_text();
assert!(
main_text.contains("Visible Heading")
&& !main_text.contains("Deleted Heading")
&& !main_text.contains("Moved Heading"),
"STYLEREF should follow accepted-current style context: {main_text:?}"
);
}
#[test]
fn docx_style_ref_ignores_old_paragraph_property_revisions() {
let doc = Document::open(&style_ref_property_revision_heading_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 2);
assert!(fields
.iter()
.all(|field| field.kind == FieldKind::DocumentStructure("STYLEREF".to_string())));
assert_eq!(fields[0].instruction, "STYLEREF \"heading 1\"");
assert_eq!(fields[0].result, "stale before current heading");
assert_eq!(
fields[0].computed_result.as_deref(),
Some("Current Heading")
);
assert_eq!(fields[1].instruction, "STYLEREF \"heading 1\"");
assert_eq!(fields[1].result, "stale after current heading");
assert_eq!(
fields[1].computed_result.as_deref(),
Some("Current Heading")
);
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
let main_text = doc.main_text();
assert!(main_text.contains("Former heading only"));
assert!(main_text.contains("Current Heading"));
assert!(!main_text.contains("stale before current heading"));
assert!(!main_text.contains("stale after current heading"));
}
#[test]
fn docx_style_ref_context_uses_single_alternate_content_branch() {
let doc = Document::open(&style_ref_alternate_content_heading_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 1);
assert_eq!(
fields[0].kind,
FieldKind::DocumentStructure("STYLEREF".to_string())
);
assert_eq!(fields[0].instruction, "STYLEREF \"heading 1\"");
assert_eq!(fields[0].computed_result.as_deref(), Some("Choice Heading"));
let main_text = doc.main_text();
assert!(
main_text.contains("Choice Heading")
&& !main_text.contains("Fallback Heading")
&& !main_text.contains("Fallback Inline"),
"STYLEREF should use one AlternateContent branch: {main_text:?}"
);
}
#[test]
fn docx_style_ref_source_text_includes_visible_simple_field_results() {
let doc = Document::open(&style_ref_simple_field_source_text_docx()).expect("fixture opens");
let fields = doc.fields();
let style_ref_fields = fields
.iter()
.filter(|field| field.kind == FieldKind::DocumentStructure("STYLEREF".to_string()))
.collect::<Vec<_>>();
assert_eq!(style_ref_fields.len(), 2);
assert_eq!(style_ref_fields[0].instruction, "STYLEREF \"heading 1\"");
assert_eq!(
style_ref_fields[0].computed_result.as_deref(),
Some("Chapter 1: Scope")
);
assert_eq!(
style_ref_fields[1].instruction,
"STYLEREF \"heading 1\" \\* Upper"
);
assert_eq!(
style_ref_fields[1].computed_result.as_deref(),
Some("CHAPTER 1: SCOPE")
);
let main_text = doc.main_text();
assert!(
main_text.contains("Chapter 1: Scope")
&& main_text.contains("CHAPTER 1: SCOPE")
&& !main_text.contains("stale simple-field source")
&& !main_text.contains("stale upper simple-field source"),
"STYLEREF source context should include visible simple-field result text: {main_text:?}"
);
}
#[test]
fn docx_style_ref_source_text_uses_computed_simple_field_results() {
let doc =
Document::open(&style_ref_stale_simple_field_source_text_docx()).expect("fixture opens");
let fields = doc.fields();
let quote = fields
.iter()
.find(|field| field.instruction == r#"QUOTE "Computed""#)
.expect("QUOTE field is recorded");
assert_eq!(quote.kind, FieldKind::Dynamic("QUOTE".to_string()));
assert_eq!(quote.result, "stale simple source");
assert_eq!(quote.computed_result.as_deref(), Some("Computed"));
let style_ref_fields = fields
.iter()
.filter(|field| field.kind == FieldKind::DocumentStructure("STYLEREF".to_string()))
.collect::<Vec<_>>();
assert_eq!(style_ref_fields.len(), 2);
assert_eq!(style_ref_fields[0].instruction, "STYLEREF \"heading 1\"");
assert_eq!(
style_ref_fields[0].computed_result.as_deref(),
Some("Chapter Computed Scope")
);
assert_eq!(
style_ref_fields[1].instruction,
"STYLEREF \"heading 1\" \\* Upper"
);
assert_eq!(
style_ref_fields[1].computed_result.as_deref(),
Some("CHAPTER COMPUTED SCOPE")
);
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
let main_text = doc.main_text();
assert!(
main_text.contains("Chapter Computed Scope")
&& main_text.contains("CHAPTER COMPUTED SCOPE")
&& !main_text.contains("stale simple source")
&& !main_text.contains("stale style source")
&& !main_text.contains("stale upper style source"),
"STYLEREF source context should use computed simple-field result text: {main_text:?}"
);
}
#[test]
fn docx_style_ref_source_text_uses_computed_legacy_form_results() {
let doc = Document::open(&style_ref_legacy_form_source_text_docx()).expect("fixture opens");
let fields = doc.fields();
let form_fields = fields
.iter()
.filter(|field| field.kind == FieldKind::FormField("FORMDROPDOWN".to_string()))
.collect::<Vec<_>>();
assert_eq!(form_fields.len(), 2);
assert_eq!(form_fields[0].result, "stale prior form");
assert_eq!(form_fields[0].computed_result.as_deref(), Some("99"));
assert_eq!(form_fields[1].result, "stale source form");
assert_eq!(form_fields[1].computed_result.as_deref(), Some("7"));
let style_ref_fields = fields
.iter()
.filter(|field| field.kind == FieldKind::DocumentStructure("STYLEREF".to_string()))
.collect::<Vec<_>>();
assert_eq!(style_ref_fields.len(), 2);
assert_eq!(style_ref_fields[0].instruction, "STYLEREF \"heading 1\"");
assert_eq!(
style_ref_fields[0].computed_result.as_deref(),
Some("Choice 7 ready")
);
assert_eq!(
style_ref_fields[1].instruction,
"STYLEREF \"heading 1\" \\* Upper"
);
assert_eq!(
style_ref_fields[1].computed_result.as_deref(),
Some("CHOICE 7 READY")
);
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
let main_text = doc.main_text();
assert!(
main_text.contains("Choice 7 ready")
&& main_text.contains("CHOICE 7 READY")
&& !main_text.contains("stale source form")
&& !main_text.contains("stale legacy form style source")
&& !main_text.contains("stale upper legacy form style source"),
"STYLEREF source context should use computed legacy form values: {main_text:?}"
);
}
#[test]
fn docx_style_ref_source_text_uses_computed_empty_simple_field_results() {
let doc =
Document::open(&style_ref_empty_simple_field_source_text_docx()).expect("fixture opens");
let fields = doc.fields();
let quote = fields
.iter()
.find(|field| field.instruction == r#"QUOTE "Computed""#)
.expect("QUOTE field is recorded");
assert_eq!(quote.kind, FieldKind::Dynamic("QUOTE".to_string()));
assert_eq!(quote.result, "");
assert_eq!(quote.computed_result.as_deref(), Some("Computed"));
let style_ref_fields = fields
.iter()
.filter(|field| field.kind == FieldKind::DocumentStructure("STYLEREF".to_string()))
.collect::<Vec<_>>();
assert_eq!(style_ref_fields.len(), 2);
assert_eq!(style_ref_fields[0].instruction, "STYLEREF \"heading 1\"");
assert_eq!(
style_ref_fields[0].computed_result.as_deref(),
Some("Chapter Computed Scope")
);
assert_eq!(
style_ref_fields[1].instruction,
"STYLEREF \"heading 1\" \\* Upper"
);
assert_eq!(
style_ref_fields[1].computed_result.as_deref(),
Some("CHAPTER COMPUTED SCOPE")
);
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
let main_text = doc.main_text();
assert!(
main_text.contains("Chapter Computed Scope")
&& main_text.contains("CHAPTER COMPUTED SCOPE")
&& !main_text.contains("stale empty style source")
&& !main_text.contains("stale upper empty style source"),
"STYLEREF source context should use computed empty simple-field result text: {main_text:?}"
);
}
#[test]
fn docx_style_ref_source_text_computes_empty_simple_fields_inside_field_results() {
let doc = Document::open(&style_ref_nested_empty_simple_field_source_text_docx())
.expect("fixture opens");
let fields = doc.fields();
let style_ref_fields = fields
.iter()
.filter(|field| field.kind == FieldKind::DocumentStructure("STYLEREF".to_string()))
.collect::<Vec<_>>();
assert_eq!(style_ref_fields.len(), 2);
assert_eq!(style_ref_fields[0].instruction, "STYLEREF \"heading 1\"");
assert_eq!(
style_ref_fields[0].computed_result.as_deref(),
Some("Chapter Prefix Inner Suffix Done")
);
assert_eq!(
style_ref_fields[1].instruction,
"STYLEREF \"heading 1\" \\* Upper"
);
assert_eq!(
style_ref_fields[1].computed_result.as_deref(),
Some("CHAPTER PREFIX INNER SUFFIX DONE")
);
let main_text = doc.main_text();
assert!(
main_text.contains("Chapter Prefix Inner Suffix Done")
&& main_text.contains("CHAPTER PREFIX INNER SUFFIX DONE")
&& !main_text.contains("stale nested empty style source")
&& !main_text.contains("stale upper nested empty style source"),
"STYLEREF source context should compute empty simple fields consumed inside another field result: {main_text:?}"
);
}
#[test]
fn docx_style_ref_source_text_computes_simple_fields_inside_field_results() {
let doc =
Document::open(&style_ref_nested_simple_field_source_text_docx()).expect("fixture opens");
let fields = doc.fields();
let style_ref_fields = fields
.iter()
.filter(|field| field.kind == FieldKind::DocumentStructure("STYLEREF".to_string()))
.collect::<Vec<_>>();
assert_eq!(style_ref_fields.len(), 2);
assert_eq!(style_ref_fields[0].instruction, "STYLEREF \"heading 1\"");
assert_eq!(
style_ref_fields[0].computed_result.as_deref(),
Some("Chapter Prefix Inner Suffix Done")
);
assert_eq!(
style_ref_fields[1].instruction,
"STYLEREF \"heading 1\" \\* Upper"
);
assert_eq!(
style_ref_fields[1].computed_result.as_deref(),
Some("CHAPTER PREFIX INNER SUFFIX DONE")
);
let main_text = doc.main_text();
assert!(
main_text.contains("Chapter Prefix Inner Suffix Done")
&& main_text.contains("CHAPTER PREFIX INNER SUFFIX DONE")
&& !main_text.contains("stale nested style source")
&& !main_text.contains("stale upper nested style source"),
"STYLEREF source context should compute simple fields consumed inside another field result: {main_text:?}"
);
}
#[test]
fn docx_style_ref_source_text_uses_computed_sequence_field_results() {
let doc =
Document::open(&style_ref_stale_sequence_field_source_text_docx()).expect("fixture opens");
let fields = doc.fields();
let sequence_fields = fields
.iter()
.filter(|field| field.kind == FieldKind::Sequence)
.collect::<Vec<_>>();
assert_eq!(sequence_fields.len(), 2);
assert_eq!(sequence_fields[0].instruction, "SEQ Chapter");
assert_eq!(sequence_fields[0].result, "99");
assert_eq!(sequence_fields[0].computed_result.as_deref(), Some("1"));
assert_eq!(sequence_fields[1].instruction, "SEQ Chapter");
assert_eq!(sequence_fields[1].result, "98");
assert_eq!(sequence_fields[1].computed_result.as_deref(), Some("2"));
let style_ref_fields = fields
.iter()
.filter(|field| field.kind == FieldKind::DocumentStructure("STYLEREF".to_string()))
.collect::<Vec<_>>();
assert_eq!(style_ref_fields.len(), 2);
assert_eq!(style_ref_fields[0].instruction, "STYLEREF \"heading 1\"");
assert_eq!(
style_ref_fields[0].computed_result.as_deref(),
Some("Simple 1 Source")
);
assert_eq!(style_ref_fields[1].instruction, "STYLEREF \"heading 1\"");
assert_eq!(
style_ref_fields[1].computed_result.as_deref(),
Some("Complex 2 Source")
);
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
let main_text = doc.main_text();
assert!(
main_text.contains("Simple 1 Source")
&& main_text.contains("Complex 2 Source")
&& !main_text.contains("Simple 99 Source")
&& !main_text.contains("Complex 98 Source")
&& !main_text.contains("stale simple sequence style source")
&& !main_text.contains("stale complex sequence style source"),
"STYLEREF source context should use computed SEQ source text: {main_text:?}"
);
}
#[test]
fn docx_style_ref_source_text_uses_computed_numbering_field_results() {
let doc =
Document::open(&style_ref_stale_numbering_field_source_text_docx()).expect("fixture opens");
let fields = doc.fields();
let numbering_fields = fields
.iter()
.filter(|field| field.kind == FieldKind::Numbering("AUTONUM".to_string()))
.collect::<Vec<_>>();
assert_eq!(numbering_fields.len(), 2);
assert_eq!(numbering_fields[0].instruction, "AUTONUM");
assert_eq!(numbering_fields[0].result, "99");
assert_eq!(numbering_fields[0].computed_result.as_deref(), Some("1"));
assert_eq!(numbering_fields[1].instruction, "AUTONUM");
assert_eq!(numbering_fields[1].result, "98");
assert_eq!(numbering_fields[1].computed_result.as_deref(), Some("2"));
let style_ref_fields = fields
.iter()
.filter(|field| field.kind == FieldKind::DocumentStructure("STYLEREF".to_string()))
.collect::<Vec<_>>();
assert_eq!(style_ref_fields.len(), 2);
assert_eq!(style_ref_fields[0].instruction, "STYLEREF \"heading 1\"");
assert_eq!(
style_ref_fields[0].computed_result.as_deref(),
Some("Simple 1 Source")
);
assert_eq!(style_ref_fields[1].instruction, "STYLEREF \"heading 1\"");
assert_eq!(
style_ref_fields[1].computed_result.as_deref(),
Some("Complex 2 Source")
);
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
let main_text = doc.main_text();
assert!(
main_text.contains("Simple 1 Source")
&& main_text.contains("Complex 2 Source")
&& !main_text.contains("Simple 99 Source")
&& !main_text.contains("Complex 98 Source")
&& !main_text.contains("stale simple autonum style source")
&& !main_text.contains("stale complex autonum style source"),
"STYLEREF source context should use computed AUTONUM source text: {main_text:?}"
);
}
#[test]
fn docx_style_ref_source_text_uses_computed_listnum_field_results() {
let doc =
Document::open(&style_ref_stale_listnum_field_source_text_docx()).expect("fixture opens");
let fields = doc.fields();
let listnum_fields = fields
.iter()
.filter(|field| field.kind == FieldKind::Numbering("LISTNUM".to_string()))
.collect::<Vec<_>>();
assert_eq!(listnum_fields.len(), 2);
assert_eq!(listnum_fields[0].instruction, "LISTNUM NumberDefault");
assert_eq!(listnum_fields[0].result, "99");
assert_eq!(listnum_fields[0].computed_result.as_deref(), Some("1"));
assert_eq!(listnum_fields[1].instruction, "LISTNUM NumberDefault");
assert_eq!(listnum_fields[1].result, "98");
assert_eq!(listnum_fields[1].computed_result.as_deref(), Some("2"));
let style_ref_fields = fields
.iter()
.filter(|field| field.kind == FieldKind::DocumentStructure("STYLEREF".to_string()))
.collect::<Vec<_>>();
assert_eq!(style_ref_fields.len(), 2);
assert_eq!(style_ref_fields[0].instruction, "STYLEREF \"heading 1\"");
assert_eq!(
style_ref_fields[0].computed_result.as_deref(),
Some("Simple 1 Source")
);
assert_eq!(style_ref_fields[1].instruction, "STYLEREF \"heading 1\"");
assert_eq!(
style_ref_fields[1].computed_result.as_deref(),
Some("Complex 2 Source")
);
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
let main_text = doc.main_text();
assert!(
main_text.contains("Simple 1 Source")
&& main_text.contains("Complex 2 Source")
&& !main_text.contains("Simple 99 Source")
&& !main_text.contains("Complex 98 Source")
&& !main_text.contains("stale simple listnum style source")
&& !main_text.contains("stale complex listnum style source"),
"STYLEREF source context should use computed LISTNUM source text: {main_text:?}"
);
}
#[test]
fn docx_style_ref_source_text_resolves_prior_set_operands() {
let doc = Document::open(&style_ref_source_prior_set_operand_docx()).expect("fixture opens");
let fields = doc.fields();
let set = fields
.iter()
.find(|field| field.instruction == "SET ClientTotal 40")
.expect("SET field is recorded");
assert_eq!(set.kind, FieldKind::Dynamic("SET".to_string()));
assert_eq!(set.result, "cached style set");
assert_eq!(set.computed_result.as_deref(), Some(""));
let formula = fields
.iter()
.find(|field| field.instruction == "= ClientTotal + 8")
.expect("formula field is recorded");
assert_eq!(formula.kind, FieldKind::Dynamic("=".to_string()));
assert_eq!(formula.result, "stale style formula");
assert_eq!(formula.computed_result.as_deref(), Some("48"));
let style_ref_fields = fields
.iter()
.filter(|field| field.kind == FieldKind::DocumentStructure("STYLEREF".to_string()))
.collect::<Vec<_>>();
assert_eq!(style_ref_fields.len(), 2);
assert_eq!(style_ref_fields[0].instruction, "STYLEREF \"heading 1\"");
assert_eq!(
style_ref_fields[0].computed_result.as_deref(),
Some("Total 48 due")
);
assert_eq!(
style_ref_fields[1].instruction,
"STYLEREF \"heading 1\" \\* Upper"
);
assert_eq!(
style_ref_fields[1].computed_result.as_deref(),
Some("TOTAL 48 DUE")
);
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
let main_text = doc.main_text();
assert!(
main_text.contains("Total 48 due")
&& main_text.contains("TOTAL 48 DUE")
&& !main_text.contains("cached style set")
&& !main_text.contains("stale style formula")
&& !main_text.contains("stale set style source")
&& !main_text.contains("stale upper set style source"),
"STYLEREF source context should resolve prior SET operands: {main_text:?}"
);
}
#[test]
fn docx_style_ref_source_text_resolves_document_bookmark_operands() {
let doc =
Document::open(&style_ref_source_document_bookmark_operand_docx()).expect("fixture opens");
let fields = doc.fields();
let formula = fields
.iter()
.find(|field| field.instruction == "= InvoiceSubtotal + 8")
.expect("formula field is recorded");
assert_eq!(formula.kind, FieldKind::Dynamic("=".to_string()));
assert_eq!(formula.result, "stale bookmark style formula");
assert_eq!(formula.computed_result.as_deref(), Some("48"));
let style_ref_fields = fields
.iter()
.filter(|field| field.kind == FieldKind::DocumentStructure("STYLEREF".to_string()))
.collect::<Vec<_>>();
assert_eq!(style_ref_fields.len(), 2);
assert_eq!(style_ref_fields[0].instruction, "STYLEREF \"heading 1\"");
assert_eq!(
style_ref_fields[0].computed_result.as_deref(),
Some("Total 48 due")
);
assert_eq!(
style_ref_fields[1].instruction,
"STYLEREF \"heading 1\" \\* Upper"
);
assert_eq!(
style_ref_fields[1].computed_result.as_deref(),
Some("TOTAL 48 DUE")
);
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
let main_text = doc.main_text();
assert!(
main_text.contains("40")
&& main_text.contains("Total 48 due")
&& main_text.contains("TOTAL 48 DUE")
&& !main_text.contains("stale bookmark style formula")
&& !main_text.contains("stale bookmark style source")
&& !main_text.contains("stale upper bookmark style source"),
"STYLEREF source context should resolve document bookmark operands: {main_text:?}"
);
}
#[test]
fn docx_style_ref_source_text_uses_computed_document_info_results() {
let doc = Document::open(&style_ref_source_document_info_field_docx()).expect("fixture opens");
let fields = doc.fields();
let source = fields
.iter()
.find(|field| field.instruction == "TITLE")
.expect("document-info source field is recorded");
assert_eq!(source.kind, FieldKind::DocumentInfo("TITLE".to_string()));
assert_eq!(source.result, "stale style title");
assert_eq!(source.computed_result.as_deref(), Some("Quarter Plan"));
let style_ref_fields = fields
.iter()
.filter(|field| field.kind == FieldKind::DocumentStructure("STYLEREF".to_string()))
.collect::<Vec<_>>();
assert_eq!(style_ref_fields.len(), 2);
assert_eq!(style_ref_fields[0].instruction, "STYLEREF \"heading 1\"");
assert_eq!(
style_ref_fields[0].computed_result.as_deref(),
Some("Topic Quarter Plan Scope")
);
assert_eq!(
style_ref_fields[1].instruction,
"STYLEREF \"heading 1\" \\* Upper"
);
assert_eq!(
style_ref_fields[1].computed_result.as_deref(),
Some("TOPIC QUARTER PLAN SCOPE")
);
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
let main_text = doc.main_text();
assert!(
main_text.contains("Topic Quarter Plan Scope")
&& main_text.contains("TOPIC QUARTER PLAN SCOPE")
&& !main_text.contains("stale style title")
&& !main_text.contains("stale document-info style source")
&& !main_text.contains("stale upper document-info style source"),
"STYLEREF source context should use computed document-info field output: {main_text:?}"
);
}
#[test]
fn docx_style_ref_source_text_uses_computed_section_field_results() {
let doc = Document::open(&style_ref_source_section_field_docx()).expect("fixture opens");
let fields = doc.fields();
let section = fields
.iter()
.find(|field| field.instruction == "SECTION")
.expect("SECTION source field is recorded");
assert_eq!(
section.kind,
FieldKind::DocumentStructure("SECTION".to_string())
);
assert_eq!(section.result, "99");
assert_eq!(section.computed_result.as_deref(), Some("1"));
let style_ref = fields
.iter()
.find(|field| field.instruction == "STYLEREF \"heading 1\"")
.expect("STYLEREF field is recorded");
assert_eq!(
style_ref.kind,
FieldKind::DocumentStructure("STYLEREF".to_string())
);
assert_eq!(style_ref.result, "stale section style source");
assert_eq!(style_ref.computed_result.as_deref(), Some("Topic 1 Review"));
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
let main_text = doc.main_text();
assert!(
main_text.contains("Topic 1 Review")
&& !main_text.contains("Topic 99 Review")
&& !main_text.contains("stale section style source"),
"STYLEREF source context should use computed SECTION source text: {main_text:?}"
);
}
#[test]
fn docx_style_ref_source_text_resolves_ref_bookmark_fields() {
let doc = Document::open(&style_ref_source_ref_bookmark_field_docx()).expect("fixture opens");
let fields = doc.fields();
let explicit_ref = fields
.iter()
.find(|field| field.instruction == "REF BaseText \\* Upper")
.expect("explicit REF source field is recorded");
assert_eq!(explicit_ref.kind, FieldKind::Ref);
assert_eq!(explicit_ref.result, "stale explicit source ref");
assert_eq!(
explicit_ref.computed_result.as_deref(),
Some("CURRENT BASE")
);
let direct_ref = fields
.iter()
.find(|field| field.instruction == "BaseText \\* FirstCap")
.expect("direct bookmark source field is recorded");
assert_eq!(direct_ref.kind, FieldKind::Ref);
assert_eq!(direct_ref.result, "stale direct source ref");
assert_eq!(direct_ref.computed_result.as_deref(), Some("Current base"));
let style_ref_fields = fields
.iter()
.filter(|field| field.kind == FieldKind::DocumentStructure("STYLEREF".to_string()))
.collect::<Vec<_>>();
assert_eq!(style_ref_fields.len(), 2);
assert_eq!(style_ref_fields[0].instruction, "STYLEREF \"heading 1\"");
assert_eq!(
style_ref_fields[0].computed_result.as_deref(),
Some("Source CURRENT BASE and Current base ready")
);
assert_eq!(
style_ref_fields[1].instruction,
"STYLEREF \"heading 1\" \\* Upper"
);
assert_eq!(
style_ref_fields[1].computed_result.as_deref(),
Some("SOURCE CURRENT BASE AND CURRENT BASE READY")
);
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
let main_text = doc.main_text();
assert!(
main_text.contains("Source CURRENT BASE and Current base ready")
&& main_text.contains("SOURCE CURRENT BASE AND CURRENT BASE READY")
&& !main_text.contains("stale explicit source ref")
&& !main_text.contains("stale direct source ref")
&& !main_text.contains("stale ref style source")
&& !main_text.contains("stale upper ref style source"),
"STYLEREF source context should resolve REF/direct bookmark source fields: {main_text:?}"
);
}
#[test]
fn docx_style_ref_source_text_uses_computed_note_ref_field_results() {
let doc = Document::open(&style_ref_source_note_ref_field_docx()).expect("fixture opens");
let fields = doc.fields();
let note_ref = fields
.iter()
.find(|field| field.instruction == "NOTEREF FootOne")
.expect("NOTEREF source field is recorded");
assert_eq!(note_ref.kind, FieldKind::NoteRef);
assert_eq!(note_ref.result, "stale style note");
assert_eq!(note_ref.computed_result.as_deref(), Some("1"));
let relative_note_ref = fields
.iter()
.find(|field| field.instruction == "NOTEREF FootOne \\p")
.expect("relative NOTEREF source field is recorded");
assert_eq!(relative_note_ref.kind, FieldKind::NoteRef);
assert_eq!(relative_note_ref.result, "stale style relative note");
assert_eq!(relative_note_ref.computed_result.as_deref(), Some("above"));
let relative_ftnref = fields
.iter()
.find(|field| field.instruction == "FTNREF FootOne \\p")
.expect("relative FTNREF source field is recorded");
assert_eq!(relative_ftnref.kind, FieldKind::NoteRef);
assert_eq!(relative_ftnref.result, "stale style relative ftnref");
assert_eq!(relative_ftnref.computed_result.as_deref(), Some("above"));
let style_ref_fields = fields
.iter()
.filter(|field| field.kind == FieldKind::DocumentStructure("STYLEREF".to_string()))
.collect::<Vec<_>>();
assert_eq!(style_ref_fields.len(), 2);
assert_eq!(style_ref_fields[0].instruction, "STYLEREF \"heading 1\"");
assert_eq!(
style_ref_fields[0].computed_result.as_deref(),
Some("Topic 1 / above / above Scope")
);
assert_eq!(
style_ref_fields[1].instruction,
"STYLEREF \"heading 1\" \\* Upper"
);
assert_eq!(
style_ref_fields[1].computed_result.as_deref(),
Some("TOPIC 1 / ABOVE / ABOVE SCOPE")
);
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
let main_text = doc.main_text();
assert!(
main_text.contains("Topic 1 / above / above Scope")
&& main_text.contains("TOPIC 1 / ABOVE / ABOVE SCOPE")
&& !main_text.contains("stale style note")
&& !main_text.contains("stale style relative note")
&& !main_text.contains("stale style relative ftnref")
&& !main_text.contains("stale note-ref style source")
&& !main_text.contains("stale upper note-ref style source"),
"STYLEREF source text should use the computed NOTEREF note number: {main_text:?}"
);
}
#[test]
fn docx_style_ref_source_text_uses_computed_ref_note_mark_field_results() {
let doc = Document::open(&style_ref_source_ref_note_mark_field_docx()).expect("fixture opens");
let fields = doc.fields();
let ref_field = fields
.iter()
.find(|field| field.instruction == "REF FootOne \\f")
.expect("REF note mark source field is recorded");
assert_eq!(ref_field.kind, FieldKind::Ref);
assert_eq!(ref_field.result, "stale style ref note");
assert_eq!(ref_field.computed_result.as_deref(), Some("2"));
let style_ref_fields = fields
.iter()
.filter(|field| field.kind == FieldKind::DocumentStructure("STYLEREF".to_string()))
.collect::<Vec<_>>();
assert_eq!(style_ref_fields.len(), 2);
assert_eq!(style_ref_fields[0].instruction, "STYLEREF \"heading 1\"");
assert_eq!(
style_ref_fields[0].computed_result.as_deref(),
Some("Topic 2 Scope")
);
assert_eq!(
style_ref_fields[1].instruction,
"STYLEREF \"heading 1\" \\* Upper"
);
assert_eq!(
style_ref_fields[1].computed_result.as_deref(),
Some("TOPIC 2 SCOPE")
);
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
let main_text = doc.main_text();
assert!(
main_text.contains("Topic 2 Scope")
&& main_text.contains("TOPIC 2 SCOPE")
&& !main_text.contains("stale style ref note")
&& !main_text.contains("stale ref-note style source")
&& !main_text.contains("stale upper ref-note style source"),
"STYLEREF source text should use the computed REF note-reference mark: {main_text:?}"
);
}
#[test]
fn docx_style_ref_source_text_keeps_known_field_names_cached() {
let doc =
Document::open(&style_ref_source_known_field_name_bookmark_docx()).expect("fixture opens");
let fields = doc.fields();
let source = fields
.iter()
.find(|field| field.instruction == "PAGEREF")
.expect("known source field is recorded");
assert_eq!(source.kind, FieldKind::PageRef);
assert_eq!(source.result, "known field source");
let style_ref = fields
.iter()
.find(|field| field.instruction == "STYLEREF \"heading 1\"")
.expect("STYLEREF field is recorded");
assert_eq!(
style_ref.computed_result.as_deref(),
Some("Heading known field source ready")
);
let main_text = doc.main_text();
assert!(
main_text.contains("Heading known field source ready")
&& !main_text.contains("stale known field style source"),
"STYLEREF source text should keep known field cached text instead of bookmark text: {main_text:?}"
);
}
#[test]
fn docx_style_ref_source_text_hides_toc_entry_marker_fields() {
let doc = Document::open(&style_ref_source_toc_entry_marker_docx()).expect("fixture opens");
let fields = doc.fields();
let marker = fields
.iter()
.find(|field| field.instruction == r#"TC "Hidden" \f m \l 1"#)
.expect("TC marker is recorded");
assert_eq!(marker.kind, FieldKind::TocEntry);
assert_eq!(marker.result, "stale tc marker");
assert_eq!(marker.computed_result.as_deref(), Some(""));
let style_ref = fields
.iter()
.find(|field| field.instruction == "STYLEREF \"heading 1\"")
.expect("STYLEREF field is recorded");
assert_eq!(style_ref.computed_result.as_deref(), Some("Chapter Scope"));
let main_text = doc.main_text();
assert!(
main_text.contains("Chapter Scope")
&& !main_text.contains("stale tc marker")
&& !main_text.contains("stale tc style source"),
"STYLEREF source text should hide TC marker fields instead of leaking cached marker text: {main_text:?}"
);
}
#[test]
fn docx_style_ref_source_text_includes_visible_complex_field_results() {
let doc = Document::open(&style_ref_complex_field_source_text_docx()).expect("fixture opens");
let fields = doc.fields();
let style_ref_fields = fields
.iter()
.filter(|field| field.kind == FieldKind::DocumentStructure("STYLEREF".to_string()))
.collect::<Vec<_>>();
assert_eq!(style_ref_fields.len(), 2);
assert_eq!(style_ref_fields[0].instruction, "STYLEREF \"heading 1\"");
assert_eq!(
style_ref_fields[0].computed_result.as_deref(),
Some("Chapter 1: Depth")
);
assert_eq!(
style_ref_fields[1].instruction,
"STYLEREF \"heading 1\" \\* Caps"
);
assert_eq!(
style_ref_fields[1].computed_result.as_deref(),
Some("Chapter 1: Depth")
);
let main_text = doc.main_text();
assert!(
main_text.contains("Chapter 1: Depth")
&& !main_text.contains("stale complex-field source")
&& !main_text.contains("stale caps complex-field source"),
"STYLEREF source context should include visible complex-field result text: {main_text:?}"
);
}
#[test]
fn docx_style_ref_source_text_uses_computed_complex_field_results() {
let doc =
Document::open(&style_ref_stale_complex_field_source_text_docx()).expect("fixture opens");
let fields = doc.fields();
let quote = fields
.iter()
.find(|field| field.instruction == r#"QUOTE "Computed""#)
.expect("QUOTE field is recorded");
assert_eq!(quote.kind, FieldKind::Dynamic("QUOTE".to_string()));
assert_eq!(quote.result, "stale complex source");
assert_eq!(quote.computed_result.as_deref(), Some("Computed"));
let style_ref_fields = fields
.iter()
.filter(|field| field.kind == FieldKind::DocumentStructure("STYLEREF".to_string()))
.collect::<Vec<_>>();
assert_eq!(style_ref_fields.len(), 2);
assert_eq!(style_ref_fields[0].instruction, "STYLEREF \"heading 1\"");
assert_eq!(
style_ref_fields[0].computed_result.as_deref(),
Some("Chapter Computed Scope")
);
assert_eq!(
style_ref_fields[1].instruction,
"STYLEREF \"heading 1\" \\* Upper"
);
assert_eq!(
style_ref_fields[1].computed_result.as_deref(),
Some("CHAPTER COMPUTED SCOPE")
);
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
let main_text = doc.main_text();
assert!(
main_text.contains("Chapter Computed Scope")
&& main_text.contains("CHAPTER COMPUTED SCOPE")
&& !main_text.contains("stale complex source")
&& !main_text.contains("stale style source")
&& !main_text.contains("stale upper style source"),
"STYLEREF source context should use computed complex-field result text: {main_text:?}"
);
}
#[test]
fn docx_style_ref_source_text_uses_outer_computed_nested_complex_field_results() {
let doc =
Document::open(&style_ref_nested_complex_field_source_text_docx()).expect("fixture opens");
let fields = doc.fields();
let inner = fields
.iter()
.find(|field| field.instruction == r#"QUOTE "Inner""#)
.expect("inner QUOTE field is recorded");
assert_eq!(inner.kind, FieldKind::Dynamic("QUOTE".to_string()));
assert_eq!(inner.result, "stale inner");
assert_eq!(inner.computed_result.as_deref(), Some("Inner"));
let outer = fields
.iter()
.find(|field| field.instruction == r#"QUOTE "Outer""#)
.expect("outer QUOTE field is recorded");
assert_eq!(outer.kind, FieldKind::Dynamic("QUOTE".to_string()));
assert_eq!(outer.result, "cached before stale inner cached after");
assert_eq!(outer.computed_result.as_deref(), Some("Outer"));
let style_ref_fields = fields
.iter()
.filter(|field| field.kind == FieldKind::DocumentStructure("STYLEREF".to_string()))
.collect::<Vec<_>>();
assert_eq!(style_ref_fields.len(), 2);
assert_eq!(style_ref_fields[0].instruction, "STYLEREF \"heading 1\"");
assert_eq!(
style_ref_fields[0].computed_result.as_deref(),
Some("Lead Outer Tail")
);
assert_eq!(
style_ref_fields[1].instruction,
"STYLEREF \"heading 1\" \\* Upper"
);
assert_eq!(
style_ref_fields[1].computed_result.as_deref(),
Some("LEAD OUTER TAIL")
);
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
let main_text = doc.main_text();
assert!(
main_text.contains("Lead Outer Tail")
&& main_text.contains("LEAD OUTER TAIL")
&& !main_text.contains("stale nested complex source")
&& !main_text.contains("stale upper nested complex source"),
"STYLEREF source context should use the outer computed nested complex field result: {main_text:?}"
);
}
#[test]
fn docx_style_ref_number_switches_compute_numbered_paragraph_labels() {
let doc = Document::open(&numbered_style_ref_switch_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 5);
for field in &fields {
assert_eq!(
field.kind,
FieldKind::DocumentStructure("STYLEREF".to_string())
);
}
assert_eq!(fields[0].instruction, "STYLEREF NumberedTarget \\r");
assert_eq!(fields[0].computed_result.as_deref(), Some("5.1"));
assert_eq!(fields[1].instruction, "STYLEREF NumberedTarget \\r \\t");
assert_eq!(fields[1].computed_result.as_deref(), Some("5.1"));
assert_eq!(fields[2].instruction, "STYLEREF NumberedTarget \\n");
assert_eq!(fields[2].computed_result.as_deref(), Some("Part 1"));
assert_eq!(fields[3].instruction, "STYLEREF NumberedTarget \\n\\t");
assert_eq!(fields[3].computed_result.as_deref(), Some("1"));
assert_eq!(
fields[4].instruction,
"STYLEREF \"Numbered Target\" \\w \\* MERGEFORMAT"
);
assert_eq!(fields[4].computed_result.as_deref(), Some("4.5.1"));
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
let main_text = doc.main_text();
assert!(
!main_text.contains("stale relative style number")
&& !main_text.contains("stale relative numeric style number")
&& !main_text.contains("stale style number")
&& !main_text.contains("stale numeric style number")
&& !main_text.contains("stale full style number"),
"computed STYLEREF numbering fields should replace stale cached text: {main_text:?}"
);
assert!(main_text.contains("5.1"), "{main_text:?}");
assert!(main_text.contains("Part 1"), "{main_text:?}");
assert!(main_text.contains("4.5.1"), "{main_text:?}");
}
#[test]
fn docx_style_ref_field_computes_character_style_text_by_source_order() {
let doc = Document::open(&character_style_ref_field_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 3);
for field in &fields {
assert_eq!(
field.kind,
FieldKind::DocumentStructure("STYLEREF".to_string())
);
}
assert_eq!(fields[0].instruction, "STYLEREF \"Last Name\"");
assert_eq!(fields[0].computed_result.as_deref(), Some("Ackerman"));
assert_eq!(fields[1].instruction, "STYLEREF LastName");
assert_eq!(fields[1].computed_result.as_deref(), Some("Ackerman"));
assert_eq!(fields[2].instruction, "STYLEREF \"Last Name\" \\* Upper");
assert_eq!(fields[2].computed_result.as_deref(), Some("BERG"));
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
let main_text = doc.main_text();
assert!(
!main_text.contains("stale forward last")
&& !main_text.contains("stale same paragraph first")
&& !main_text.contains("stale same paragraph second"),
"computed character-style STYLEREF fields should replace stale cached text: {main_text:?}"
);
assert!(main_text.contains("Ackerman"), "{main_text:?}");
assert!(main_text.contains("BERG"), "{main_text:?}");
}
#[test]
fn docx_style_ref_character_style_source_includes_simple_field_result_runs() {
let doc =
Document::open(&character_style_ref_simple_field_source_docx()).expect("fixture opens");
let fields = doc.fields();
let style_ref_fields = fields
.iter()
.filter(|field| field.kind == FieldKind::DocumentStructure("STYLEREF".to_string()))
.collect::<Vec<_>>();
assert_eq!(style_ref_fields.len(), 2);
assert_eq!(style_ref_fields[0].instruction, "STYLEREF \"Last Name\"");
assert_eq!(
style_ref_fields[0].computed_result.as_deref(),
Some("Curie")
);
assert_eq!(
style_ref_fields[1].instruction,
"STYLEREF LastName \\* Upper"
);
assert_eq!(
style_ref_fields[1].computed_result.as_deref(),
Some("CURIE")
);
let main_text = doc.main_text();
assert!(
main_text.contains("Curie")
&& main_text.contains("CURIE")
&& !main_text.contains("stale simple field character source")
&& !main_text.contains("stale upper simple field character source"),
"character-style STYLEREF should index visible simple-field result runs: {main_text:?}"
);
}
#[test]
fn docx_style_ref_character_style_source_uses_computed_simple_field_results() {
let doc = Document::open(&character_style_ref_stale_simple_field_source_docx())
.expect("fixture opens");
let fields = doc.fields();
let quote = fields
.iter()
.find(|field| field.instruction == r#"QUOTE "Curie""#)
.expect("QUOTE field is recorded");
assert_eq!(quote.kind, FieldKind::Dynamic("QUOTE".to_string()));
assert_eq!(quote.result, "stale character source");
assert_eq!(quote.computed_result.as_deref(), Some("Curie"));
let style_ref_fields = fields
.iter()
.filter(|field| field.kind == FieldKind::DocumentStructure("STYLEREF".to_string()))
.collect::<Vec<_>>();
assert_eq!(style_ref_fields.len(), 2);
assert_eq!(style_ref_fields[0].instruction, "STYLEREF \"Last Name\"");
assert_eq!(
style_ref_fields[0].computed_result.as_deref(),
Some("Curie")
);
assert_eq!(
style_ref_fields[1].instruction,
"STYLEREF LastName \\* Upper"
);
assert_eq!(
style_ref_fields[1].computed_result.as_deref(),
Some("CURIE")
);
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
let main_text = doc.main_text();
assert!(
main_text.contains("Curie")
&& main_text.contains("CURIE")
&& !main_text.contains("stale character source")
&& !main_text.contains("stale simple field character source")
&& !main_text.contains("stale upper simple field character source"),
"character-style STYLEREF should use computed simple-field source text: {main_text:?}"
);
}
#[test]
fn docx_style_ref_character_style_source_uses_computed_split_simple_field_results() {
let doc = Document::open(&character_style_ref_split_simple_field_source_docx())
.expect("fixture opens");
let fields = doc.fields();
let quote = fields
.iter()
.find(|field| field.instruction == r#"QUOTE "Curie""#)
.expect("QUOTE field is recorded");
assert_eq!(quote.kind, FieldKind::Dynamic("QUOTE".to_string()));
assert_eq!(quote.result, "stale character source");
assert_eq!(quote.computed_result.as_deref(), Some("Curie"));
let style_ref_fields = fields
.iter()
.filter(|field| field.kind == FieldKind::DocumentStructure("STYLEREF".to_string()))
.collect::<Vec<_>>();
assert_eq!(style_ref_fields.len(), 2);
assert_eq!(style_ref_fields[0].instruction, "STYLEREF \"Last Name\"");
assert_eq!(
style_ref_fields[0].computed_result.as_deref(),
Some("Curie")
);
assert_eq!(
style_ref_fields[1].instruction,
"STYLEREF LastName \\* Upper"
);
assert_eq!(
style_ref_fields[1].computed_result.as_deref(),
Some("CURIE")
);
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
let main_text = doc.main_text();
assert!(
main_text.contains("Curie")
&& main_text.contains("CURIE")
&& !main_text.contains("stale split simple field character source")
&& !main_text.contains("stale upper split simple field character source"),
"character-style STYLEREF should use computed split simple-field source text: {main_text:?}"
);
}
#[test]
fn docx_style_ref_character_style_source_computes_nested_simple_field_results() {
let doc = Document::open(&character_style_ref_nested_simple_field_source_docx())
.expect("fixture opens");
let fields = doc.fields();
let style_ref_fields = fields
.iter()
.filter(|field| field.kind == FieldKind::DocumentStructure("STYLEREF".to_string()))
.collect::<Vec<_>>();
assert_eq!(style_ref_fields.len(), 2);
assert_eq!(style_ref_fields[0].instruction, "STYLEREF \"Last Name\"");
assert_eq!(
style_ref_fields[0].computed_result.as_deref(),
Some("Curie")
);
assert_eq!(
style_ref_fields[1].instruction,
"STYLEREF LastName \\* Upper"
);
assert_eq!(
style_ref_fields[1].computed_result.as_deref(),
Some("CURIE")
);
let report = doc.report();
assert_eq!(
report.features.unsupported_field_kinds,
vec![FieldKindCount {
kind: FieldKind::Unknown("CUSTOM".to_string()),
count: 1,
}]
);
assert_eq!(
report.features.unsupported_field_reasons,
vec![FieldEvaluationReasonCount {
reason: FieldEvaluationReason::UnknownField,
count: 1,
}]
);
let main_text = doc.main_text();
assert!(
main_text.contains("Curie")
&& main_text.contains("CURIE")
&& !main_text.contains("stale nested simple character source")
&& !main_text.contains("stale upper nested simple character source"),
"character-style STYLEREF should compute nested simple-field source text: {main_text:?}"
);
}
#[test]
fn docx_style_ref_character_style_source_uses_computed_complex_field_results() {
let doc = Document::open(&character_style_ref_stale_complex_field_source_docx())
.expect("fixture opens");
let fields = doc.fields();
let quote = fields
.iter()
.find(|field| field.instruction == r#"QUOTE "Curie""#)
.expect("QUOTE field is recorded");
assert_eq!(quote.kind, FieldKind::Dynamic("QUOTE".to_string()));
assert_eq!(quote.result, "stale character complex source");
assert_eq!(quote.computed_result.as_deref(), Some("Curie"));
let style_ref_fields = fields
.iter()
.filter(|field| field.kind == FieldKind::DocumentStructure("STYLEREF".to_string()))
.collect::<Vec<_>>();
assert_eq!(style_ref_fields.len(), 2);
assert_eq!(style_ref_fields[0].instruction, "STYLEREF \"Last Name\"");
assert_eq!(
style_ref_fields[0].computed_result.as_deref(),
Some("Curie")
);
assert_eq!(
style_ref_fields[1].instruction,
"STYLEREF LastName \\* Upper"
);
assert_eq!(
style_ref_fields[1].computed_result.as_deref(),
Some("CURIE")
);
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
let main_text = doc.main_text();
assert!(
main_text.contains("Curie")
&& main_text.contains("CURIE")
&& !main_text.contains("stale character complex source")
&& !main_text.contains("stale complex field character source")
&& !main_text.contains("stale upper complex field character source"),
"character-style STYLEREF should use computed complex-field source text: {main_text:?}"
);
}
#[test]
fn docx_style_ref_source_text_includes_supported_symbols() {
let doc = Document::open(&style_ref_symbol_source_text_docx()).expect("fixture opens");
let fields = doc.fields();
let style_ref_fields = fields
.iter()
.filter(|field| field.kind == FieldKind::DocumentStructure("STYLEREF".to_string()))
.collect::<Vec<_>>();
assert_eq!(style_ref_fields.len(), 2);
assert_eq!(style_ref_fields[0].instruction, "STYLEREF \"heading 1\"");
assert_eq!(
style_ref_fields[0].computed_result.as_deref(),
Some("Risk • Control")
);
assert_eq!(
style_ref_fields[1].instruction,
"STYLEREF \"Symbol Target\""
);
assert_eq!(
style_ref_fields[1].computed_result.as_deref(),
Some("Marked • Run")
);
let main_text = doc.main_text();
assert!(
main_text.contains("Risk • Control")
&& main_text.contains("Marked • Run")
&& !main_text.contains("stale symbol heading")
&& !main_text.contains("stale symbol character"),
"STYLEREF source context should include supported literal symbols: {main_text:?}"
);
}
#[test]
fn docx_style_ref_ignores_old_run_property_revisions() {
let doc = Document::open(&character_style_ref_property_revision_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 3);
assert!(fields
.iter()
.all(|field| field.kind == FieldKind::DocumentStructure("STYLEREF".to_string())));
assert_eq!(fields[0].instruction, "STYLEREF \"Last Name\"");
assert_eq!(fields[0].computed_result.as_deref(), Some("Current Last"));
assert_eq!(fields[1].instruction, "STYLEREF \"Last Name\"");
assert_eq!(fields[1].computed_result.as_deref(), Some("Current Last"));
assert_eq!(fields[2].instruction, "STYLEREF \"Last Name\" \\* Upper");
assert_eq!(fields[2].computed_result.as_deref(), Some("CURRENT LAST"));
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
let main_text = doc.main_text();
assert!(main_text.contains("Former Styled"));
assert!(main_text.contains("Current Last"));
assert!(!main_text.contains("stale before old run"));
assert!(!main_text.contains("stale after old run"));
assert!(!main_text.contains("stale after current run"));
}
#[test]
fn docx_display_fields_compute_deterministic_subset() {
let doc = Document::open(&display_field_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 28);
assert_eq!(fields[0].kind, FieldKind::Display("ADVANCE".to_string()));
assert_eq!(fields[0].instruction, "ADVANCE \\r 2 \\d4 \\* MERGEFORMAT");
assert_eq!(fields[0].result, "offset text");
assert_eq!(fields[0].computed_result.as_deref(), Some(""));
assert_eq!(fields[1].kind, FieldKind::Display("ADVANCE".to_string()));
assert_eq!(fields[1].instruction, "ADVANCE \\z 2");
assert_eq!(fields[1].result, "cached unsupported advance");
assert_eq!(fields[1].computed_result, None);
assert_eq!(fields[2].kind, FieldKind::Display("EQ".to_string()));
assert_eq!(fields[2].result, "stale equation");
assert_eq!(fields[2].computed_result.as_deref(), Some("1/2"));
assert_eq!(fields[3].kind, FieldKind::Display("EQ".to_string()));
assert_eq!(
fields[3].instruction,
r#"EQ \f( "Alpha, One" , "Beta Two" ) \* Upper"#
);
assert_eq!(fields[3].result, "stale quoted equation");
assert_eq!(
fields[3].computed_result.as_deref(),
Some("ALPHA, ONE/BETA TWO")
);
assert_eq!(fields[4].kind, FieldKind::Display("EQ".to_string()));
assert_eq!(fields[4].result, "stale semicolon equation");
assert_eq!(fields[4].computed_result.as_deref(), Some("3/4"));
assert_eq!(fields[5].kind, FieldKind::Display("EQ".to_string()));
assert_eq!(fields[5].result, "stale escaped equation");
assert_eq!(fields[5].computed_result.as_deref(), Some("A,B/C\\D"));
assert_eq!(fields[6].kind, FieldKind::Display("EQ".to_string()));
assert_eq!(fields[6].result, "stale square root");
assert_eq!(fields[6].computed_result.as_deref(), Some("√9"));
assert_eq!(fields[7].kind, FieldKind::Display("EQ".to_string()));
assert_eq!(fields[7].result, "stale cube root");
assert_eq!(fields[7].computed_result.as_deref(), Some("3√27"));
assert_eq!(fields[8].kind, FieldKind::Display("EQ".to_string()));
assert_eq!(fields[8].result, "stale nested equation");
assert_eq!(fields[8].computed_result.as_deref(), Some("1/(2/3)"));
assert_eq!(fields[9].kind, FieldKind::Display("EQ".to_string()));
assert_eq!(fields[9].result, "stale nested radical");
assert_eq!(fields[9].computed_result.as_deref(), Some("√(1/4)"));
assert_eq!(fields[10].kind, FieldKind::Display("EQ".to_string()));
assert_eq!(fields[10].instruction, r#"EQ \b("Chapter One")"#);
assert_eq!(fields[10].result, "stale bracket equation");
assert_eq!(fields[10].computed_result.as_deref(), Some("(Chapter One)"));
assert_eq!(fields[11].kind, FieldKind::Display("EQ".to_string()));
assert_eq!(fields[11].instruction, r#"EQ \x \to \bo(\f(5,8)) \* Upper"#);
assert_eq!(fields[11].result, "stale boxed equation");
assert_eq!(fields[11].computed_result.as_deref(), Some("(5/8)"));
assert_eq!(fields[12].kind, FieldKind::Display("EQ".to_string()));
assert_eq!(fields[12].instruction, r#"EQ \b \bc\{ (\r(3,x))"#);
assert_eq!(fields[12].result, "stale brace bracket equation");
assert_eq!(fields[12].computed_result.as_deref(), Some("{(3√x)}"));
assert_eq!(fields[13].kind, FieldKind::Display("EQ".to_string()));
assert_eq!(fields[13].instruction, r#"EQ \b \lc\[ \rc\] ("Range")"#);
assert_eq!(fields[13].result, "stale explicit bracket equation");
assert_eq!(fields[13].computed_result.as_deref(), Some("[Range]"));
assert_eq!(fields[14].kind, FieldKind::Display("EQ".to_string()));
assert_eq!(fields[14].instruction, r#"EQ \l(A,"B, C",\r(4,16))"#);
assert_eq!(fields[14].result, "stale list equation");
assert_eq!(fields[14].computed_result.as_deref(), Some("A,B, C,(4√16)"));
assert_eq!(fields[15].kind, FieldKind::Display("EQ".to_string()));
assert_eq!(
fields[15].instruction,
r#"EQ \a \al \co2 \vs3 \hs3(Axy,Bxy,A,B)"#
);
assert_eq!(fields[15].result, "stale array equation");
assert_eq!(
fields[15].computed_result.as_deref(),
Some("Axy\tBxy\nA\tB")
);
assert_eq!(fields[16].kind, FieldKind::Display("EQ".to_string()));
assert_eq!(fields[16].instruction, r#"EQ \d \fo10 \li()"#);
assert_eq!(fields[16].result, "stale displace equation");
assert_eq!(fields[16].computed_result.as_deref(), Some(""));
assert_eq!(fields[17].kind, FieldKind::Display("EQ".to_string()));
assert_eq!(fields[17].instruction, r#"EQ \s\up8(UB)\s\do8(2)"#);
assert_eq!(fields[17].result, "stale script equation");
assert_eq!(fields[17].computed_result.as_deref(), Some("^{UB}_2"));
assert_eq!(fields[18].kind, FieldKind::Display("EQ".to_string()));
assert_eq!(fields[18].instruction, r#"EQ \i(0,1,x)"#);
assert_eq!(fields[18].result, "stale integral equation");
assert_eq!(fields[18].computed_result.as_deref(), Some("∫_0^1 x"));
assert_eq!(fields[19].kind, FieldKind::Display("EQ".to_string()));
assert_eq!(fields[19].instruction, r#"EQ \i \su(1,5,\f(3,4))"#);
assert_eq!(fields[19].result, "stale summation equation");
assert_eq!(fields[19].computed_result.as_deref(), Some("Σ_1^5 (3/4)"));
assert_eq!(fields[20].kind, FieldKind::Display("EQ".to_string()));
assert_eq!(fields[20].instruction, r#"EQ \i \pr(1,3,y)"#);
assert_eq!(fields[20].result, "stale product equation");
assert_eq!(fields[20].computed_result.as_deref(), Some("Π_1^3 y"));
assert_eq!(fields[21].kind, FieldKind::Display("EQ".to_string()));
assert_eq!(fields[21].instruction, r#"EQ \i \in(a,b,\r(9))"#);
assert_eq!(fields[21].result, "stale integral option equation");
assert_eq!(fields[21].computed_result.as_deref(), Some("∫_a^b (√9)"));
assert_eq!(fields[22].kind, FieldKind::Display("EQ".to_string()));
assert_eq!(fields[22].instruction, r#"EQ \i \fc\∮(C,D,z)"#);
assert_eq!(fields[22].result, "stale custom integral equation");
assert_eq!(fields[22].computed_result.as_deref(), Some("∮_C^D z"));
assert_eq!(fields[23].kind, FieldKind::Display("EQ".to_string()));
assert_eq!(fields[23].instruction, r#"EQ \i \vc\∯(S,T,w)"#);
assert_eq!(fields[23].result, "stale vertical custom integral equation");
assert_eq!(fields[23].computed_result.as_deref(), Some("∯_S^T w"));
assert_eq!(fields[24].kind, FieldKind::Display("EQ".to_string()));
assert_eq!(fields[24].instruction, r#"EQ \o \ac("A",/)"#);
assert_eq!(fields[24].result, "stale overstrike equation");
assert_eq!(fields[24].computed_result.as_deref(), Some("A/"));
assert_eq!(fields[25].kind, FieldKind::Display("SYMBOL".to_string()));
assert_eq!(fields[25].result, "symbol");
assert_eq!(fields[25].computed_result.as_deref(), Some("•"));
assert_eq!(fields[26].kind, FieldKind::Display("EQ".to_string()));
assert_eq!(fields[26].instruction, r#"EQ \s\ai4()\di3()"#);
assert_eq!(fields[26].result, "stale empty script equation");
assert_eq!(fields[26].computed_result.as_deref(), Some(""));
assert_eq!(fields[27].kind, FieldKind::Display("EQ".to_string()));
assert_eq!(
fields[27].instruction,
r#"EQ \s\ai4()\up8(UB)\s\di3()\do8(2)"#
);
assert_eq!(fields[27].result, "stale layout script equation");
assert_eq!(fields[27].computed_result.as_deref(), Some("^{UB}_2"));
let report = doc.report();
assert_eq!(
report.features.unsupported_field_kinds,
vec![FieldKindCount {
kind: FieldKind::Display("ADVANCE".to_string()),
count: 1,
}]
);
assert_eq!(
report.features.unsupported_field_reasons,
vec![FieldEvaluationReasonCount {
reason: FieldEvaluationReason::UnsupportedSwitch,
count: 1,
}]
);
let main_text = doc.main_text();
assert!(
main_text.contains("cached unsupported advance")
&& main_text.contains("1/2")
&& main_text.contains("ALPHA, ONE/BETA TWO")
&& main_text.contains("3/4")
&& main_text.contains("A,B/C\\D")
&& main_text.contains("√9")
&& main_text.contains("3√27")
&& main_text.contains("1/(2/3)")
&& main_text.contains("√(1/4)")
&& main_text.contains("(Chapter One)")
&& main_text.contains("(5/8)")
&& main_text.contains("{(3√x)}")
&& main_text.contains("[Range]")
&& main_text.contains("A,B, C,(4√16)")
&& main_text.contains("Axy\tBxy\nA\tB")
&& main_text.contains("^{UB}_2")
&& main_text.contains("∫_0^1 x")
&& main_text.contains("Σ_1^5 (3/4)")
&& main_text.contains("Π_1^3 y")
&& main_text.contains("∫_a^b (√9)")
&& main_text.contains("∮_C^D z")
&& main_text.contains("∯_S^T w")
&& main_text.contains("A/")
&& main_text.contains("•"),
"computed and cached display field results should appear in main text: {main_text:?}"
);
assert!(
!main_text.contains("offset text")
&& !main_text.contains("stale equation")
&& !main_text.contains("stale quoted equation")
&& !main_text.contains("stale semicolon equation")
&& !main_text.contains("stale escaped equation")
&& !main_text.contains("stale square root")
&& !main_text.contains("stale cube root")
&& !main_text.contains("stale nested equation")
&& !main_text.contains("stale nested radical")
&& !main_text.contains("stale bracket equation")
&& !main_text.contains("stale boxed equation")
&& !main_text.contains("stale brace bracket equation")
&& !main_text.contains("stale explicit bracket equation")
&& !main_text.contains("stale list equation")
&& !main_text.contains("stale array equation")
&& !main_text.contains("stale displace equation")
&& !main_text.contains("stale script equation")
&& !main_text.contains("stale integral equation")
&& !main_text.contains("stale summation equation")
&& !main_text.contains("stale product equation")
&& !main_text.contains("stale integral option equation")
&& !main_text.contains("stale custom integral equation")
&& !main_text.contains("stale vertical custom integral equation")
&& !main_text.contains("stale overstrike equation")
&& !main_text.contains("symbol")
&& !main_text.contains("stale empty script equation")
&& !main_text.contains("stale layout script equation"),
"computed display fields should replace stale cached text: {main_text:?}"
);
}
#[test]
fn docx_advance_fields_accept_compact_and_quoted_point_switches() {
let doc = Document::open(&advance_compact_quoted_display_docx()).expect("fixture opens");
let fields = doc.fields();
let expected = [
r#"ADVANCE \r"2""#,
r#"ADVANCE \u "3" \d4"#,
r#"ADVANCE \l2 \y "5" \* Upper"#,
];
assert_eq!(fields.len(), expected.len());
for (field, instruction) in fields.iter().zip(expected) {
assert_eq!(field.kind, FieldKind::Display("ADVANCE".to_string()));
assert_eq!(field.instruction, instruction);
assert_eq!(field.computed_result.as_deref(), Some(""));
}
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
let main_text = doc.main_text();
assert!(
!main_text.contains("stale compact right")
&& !main_text.contains("stale quoted up down")
&& !main_text.contains("stale compact left vertical"),
"computed ADVANCE fields should remove stale cached text: {main_text:?}"
);
}
#[test]
fn docx_display_field_diagnostics_split_valid_broader_eq_from_malformed_eq() {
let doc = Document::open(&docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:fldSimple w:instr=" EQ \s\up8(A)\ai4(B) "><w:r><w:t>cached broader script equation</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" EQ \s\up8(A "><w:r><w:t>cached malformed script equation</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" EQ \d \fo10(A) "><w:r><w:t>cached broader displace equation</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" EQ \d \fo10(A "><w:r><w:t>cached malformed displace equation</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
]))
.expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 4);
assert_eq!(fields[0].kind, FieldKind::Display("EQ".to_string()));
assert_eq!(fields[0].instruction, r#"EQ \s\up8(A)\ai4(B)"#);
assert_eq!(fields[0].result, "cached broader script equation");
assert_eq!(fields[0].computed_result.as_deref(), Some("^AB"));
assert_eq!(fields[1].kind, FieldKind::Display("EQ".to_string()));
assert_eq!(fields[1].instruction, r#"EQ \s\up8(A"#);
assert_eq!(fields[1].result, "cached malformed script equation");
assert_eq!(fields[1].computed_result, None);
assert_eq!(fields[2].kind, FieldKind::Display("EQ".to_string()));
assert_eq!(fields[2].instruction, r#"EQ \d \fo10(A)"#);
assert_eq!(fields[2].result, "cached broader displace equation");
assert_eq!(fields[2].computed_result.as_deref(), Some("A"));
assert_eq!(fields[3].kind, FieldKind::Display("EQ".to_string()));
assert_eq!(fields[3].instruction, r#"EQ \d \fo10(A"#);
assert_eq!(fields[3].result, "cached malformed displace equation");
assert_eq!(fields[3].computed_result, None);
let report = doc.report();
assert_eq!(
report.features.unsupported_field_kinds,
vec![FieldKindCount {
kind: FieldKind::Display("EQ".to_string()),
count: 2,
}]
);
assert_eq!(
report.features.unsupported_field_reasons,
vec![FieldEvaluationReasonCount {
reason: FieldEvaluationReason::UnsupportedSwitch,
count: 2,
}]
);
assert_eq!(
model_simple_field_reason_hints(&doc, |instruction| instruction.starts_with("EQ")),
vec![
(
r#"EQ \s\up8(A"#.to_string(),
Some(FieldUnsupportedReason::UnsupportedSwitch),
),
(
r#"EQ \d \fo10(A"#.to_string(),
Some(FieldUnsupportedReason::UnsupportedSwitch),
),
]
);
let main_text = doc.main_text();
assert!(!main_text.contains("cached broader script equation"));
assert!(main_text.contains("^AB"));
assert!(main_text.contains("cached malformed script equation"));
assert!(!main_text.contains("cached broader displace equation"));
assert!(main_text.contains("A"));
assert!(main_text.contains("cached malformed displace equation"));
}
#[test]
fn docx_symbol_field_computes_deterministic_symbols() {
let doc = Document::open(&symbol_field_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 7);
for field in &fields {
assert_eq!(field.kind, FieldKind::Display("SYMBOL".to_string()));
}
assert_eq!(fields[0].instruction, "SYMBOL 163");
assert_eq!(fields[0].computed_result.as_deref(), Some("£"));
assert_eq!(fields[1].instruction, "SYMBOL 0x03BB \\u \\h");
assert_eq!(fields[1].computed_result.as_deref(), Some("λ"));
assert_eq!(fields[2].instruction, "SYMBOL 211 \\f \"Symbol\" \\s 12");
assert_eq!(fields[2].computed_result.as_deref(), Some("©"));
assert_eq!(fields[3].instruction, "SYMBOL 183 \\fSymbol \\s12");
assert_eq!(fields[3].computed_result.as_deref(), Some("•"));
assert_eq!(fields[4].instruction, "SYMBOL 0x03BB \\u \\f Symbol");
assert_eq!(fields[4].computed_result.as_deref(), Some("\u{03bb}"));
assert_eq!(fields[5].instruction, "SYMBOL 0x0041 \\u \\s \"10\"");
assert_eq!(fields[5].computed_result.as_deref(), Some("A"));
assert_eq!(fields[6].instruction, "SYMBOL 0x0042 \\u \\s\"11\"");
assert_eq!(fields[6].computed_result.as_deref(), Some("B"));
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
let main_text = doc.main_text();
assert!(
!main_text.contains("stale pound")
&& !main_text.contains("stale lambda")
&& !main_text.contains("stale copyright")
&& !main_text.contains("stale compact symbol")
&& !main_text.contains("stale unicode font")
&& !main_text.contains("stale quoted size")
&& !main_text.contains("stale compact quoted size"),
"computed SYMBOL fields should replace stale cached text: {main_text:?}"
);
assert!(main_text.contains("£"), "{main_text:?}");
assert!(main_text.contains("λ"), "{main_text:?}");
assert!(main_text.contains("©"), "{main_text:?}");
assert!(main_text.contains("•"), "{main_text:?}");
assert!(main_text.contains("A"), "{main_text:?}");
assert!(main_text.contains("B"), "{main_text:?}");
}
#[test]
fn docx_symbol_field_diagnostics_split_mapped_wingdings_from_malformed_symbol() {
let doc = Document::open(&docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:fldSimple w:instr=" SYMBOL 65 \f Wingdings "><w:r><w:t>cached unmapped wingdings</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" SYMBOL 74 \f Wingdings "><w:r><w:t>cached smile wingdings</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" SYMBOL 0xF0FC \f Wingdings "><w:r><w:t>cached private-use check</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" SYMBOL 65 \f "Wingdings "><w:r><w:t>cached malformed symbol</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
]))
.expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 4);
assert_eq!(fields[0].kind, FieldKind::Display("SYMBOL".to_string()));
assert_eq!(fields[0].instruction, r#"SYMBOL 65 \f Wingdings"#);
assert_eq!(fields[0].result, "cached unmapped wingdings");
assert_eq!(fields[0].computed_result.as_deref(), Some("\u{270C}"));
assert_eq!(fields[1].kind, FieldKind::Display("SYMBOL".to_string()));
assert_eq!(fields[1].instruction, r#"SYMBOL 74 \f Wingdings"#);
assert_eq!(fields[1].result, "cached smile wingdings");
assert_eq!(fields[1].computed_result.as_deref(), Some("\u{263A}"));
assert_eq!(fields[2].kind, FieldKind::Display("SYMBOL".to_string()));
assert_eq!(fields[2].instruction, r#"SYMBOL 0xF0FC \f Wingdings"#);
assert_eq!(fields[2].result, "cached private-use check");
assert_eq!(fields[2].computed_result.as_deref(), Some("\u{2713}"));
assert_eq!(fields[3].kind, FieldKind::Display("SYMBOL".to_string()));
assert_eq!(fields[3].instruction, r#"SYMBOL 65 \f "Wingdings "#);
assert_eq!(fields[3].result, "cached malformed symbol");
assert_eq!(fields[3].computed_result, None);
let report = doc.report();
assert_eq!(
report.features.unsupported_field_kinds,
vec![FieldKindCount {
kind: FieldKind::Display("SYMBOL".to_string()),
count: 1,
}]
);
assert_eq!(
report.features.unsupported_field_reasons,
vec![FieldEvaluationReasonCount {
reason: FieldEvaluationReason::UnsupportedSwitch,
count: 1,
}]
);
assert_eq!(
model_simple_field_reason_hints(&doc, |instruction| instruction.starts_with("SYMBOL")),
vec![(
r#"SYMBOL 65 \f "Wingdings "#.to_string(),
Some(FieldUnsupportedReason::UnsupportedSwitch),
)]
);
let main_text = doc.main_text();
assert!(main_text.contains("\u{270C}"));
assert!(main_text.contains("\u{263A}"));
assert!(main_text.contains("\u{2713}"));
assert!(main_text.contains("cached malformed symbol"));
}
#[test]
fn docx_symbol_field_accepts_unquoted_multi_token_font_switch() {
let doc = Document::open(&symbol_multi_token_font_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 1);
assert_eq!(fields[0].kind, FieldKind::Display("SYMBOL".to_string()));
assert_eq!(
fields[0].instruction,
"SYMBOL 0x03BB \\u \\f Times New Roman \\* Upper"
);
assert_eq!(fields[0].result, "stale multi-token font");
assert_eq!(fields[0].computed_result.as_deref(), Some("\u{039B}"));
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
let main_text = doc.main_text();
assert!(
main_text.contains("\u{039B}") && !main_text.contains("stale multi-token font"),
"multi-token SYMBOL font operand should keep Unicode computation deterministic: {main_text:?}"
);
}
#[test]
fn docx_action_fields_compute_display_text_without_running_actions() {
let doc = Document::open(&action_field_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 11);
assert_eq!(fields[0].kind, FieldKind::Action("GOTOBUTTON".to_string()));
assert_eq!(fields[0].instruction, "GOTOBUTTON TargetBookmark \"Jump\"");
assert_eq!(fields[0].result, "stale jump");
assert_eq!(fields[0].computed_result.as_deref(), Some("Jump"));
assert_eq!(fields[1].kind, FieldKind::Action("GOTOBUTTON".to_string()));
assert_eq!(
fields[1].instruction,
"GOTOBUTTON TargetBookmark Jump Now \\* Upper"
);
assert_eq!(fields[1].result, "stale jump upper");
assert_eq!(fields[1].computed_result.as_deref(), Some("JUMP NOW"));
assert_eq!(fields[2].kind, FieldKind::Action("MACROBUTTON".to_string()));
assert_eq!(fields[2].result, "stale run");
assert_eq!(fields[2].computed_result.as_deref(), Some("Run report"));
assert_eq!(fields[3].kind, FieldKind::Action("MACROBUTTON".to_string()));
assert_eq!(
fields[3].instruction,
"MACROBUTTON RunReport Run \\* Upper Again"
);
assert_eq!(fields[3].result, "cached malformed action");
assert_eq!(fields[3].computed_result, None);
assert_eq!(fields[4].kind, FieldKind::Action("MACROBUTTON".to_string()));
assert_eq!(
fields[4].instruction,
"MACROBUTTON RunReport \\* MERGEFORMAT"
);
assert_eq!(fields[4].result, "cached target-only action");
assert_eq!(fields[4].computed_result, None);
assert_eq!(fields[5].kind, FieldKind::Action("PRINT".to_string()));
assert_eq!(fields[5].result, "Print instruction");
assert_eq!(fields[5].computed_result.as_deref(), Some(""));
assert_eq!(fields[6].kind, FieldKind::Action("PRINT".to_string()));
assert_eq!(fields[6].instruction, "PRINT status");
assert_eq!(fields[6].result, "Unquoted print instruction");
assert_eq!(fields[6].computed_result.as_deref(), Some(""));
assert_eq!(fields[7].kind, FieldKind::Action("PRINT".to_string()));
assert_eq!(fields[7].instruction, "PRINT status ready \\* MERGEFORMAT");
assert_eq!(fields[7].result, "Multi-token print instruction");
assert_eq!(fields[7].computed_result.as_deref(), Some(""));
assert_eq!(fields[8].kind, FieldKind::Action("PRINT".to_string()));
assert_eq!(
fields[8].instruction,
"PRINT \\p ReportBox \"0 0 moveto\" \\* MERGEFORMAT"
);
assert_eq!(fields[8].result, "PostScript instruction");
assert_eq!(fields[8].computed_result.as_deref(), Some(""));
assert_eq!(fields[9].kind, FieldKind::Action("PRINT".to_string()));
assert_eq!(
fields[9].instruction,
"PRINT \\pReportBox \"compact moveto\""
);
assert_eq!(fields[9].result, "Compact PostScript instruction");
assert_eq!(fields[9].computed_result.as_deref(), Some(""));
assert_eq!(fields[10].kind, FieldKind::Action("PRINT".to_string()));
assert_eq!(fields[10].instruction, "PRINT \\z \"bad\"");
assert_eq!(fields[10].result, "cached unsupported print");
assert_eq!(fields[10].computed_result, None);
let report = doc.report();
assert_eq!(
report.features.unsupported_field_kinds,
vec![
FieldKindCount {
kind: FieldKind::Action("MACROBUTTON".to_string()),
count: 2,
},
FieldKindCount {
kind: FieldKind::Action("PRINT".to_string()),
count: 1,
},
]
);
assert_eq!(
report.features.unsupported_field_reasons,
vec![
FieldEvaluationReasonCount {
reason: FieldEvaluationReason::UnsupportedSwitch,
count: 2,
},
FieldEvaluationReasonCount {
reason: FieldEvaluationReason::NoComputedResult,
count: 1,
},
]
);
assert_eq!(
model_simple_field_reason_hints(&doc, |instruction| {
instruction.starts_with("MACROBUTTON") || instruction.starts_with("PRINT")
}),
vec![
(
"MACROBUTTON RunReport Run \\* Upper Again".to_string(),
Some(FieldUnsupportedReason::UnsupportedSwitch),
),
(
"MACROBUTTON RunReport \\* MERGEFORMAT".to_string(),
Some(FieldUnsupportedReason::NoComputedResult),
),
(
"PRINT \\z \"bad\"".to_string(),
Some(FieldUnsupportedReason::UnsupportedSwitch),
),
]
);
let main_text = doc.main_text();
assert!(
main_text.contains("Jump")
&& main_text.contains("JUMP NOW")
&& main_text.contains("Run report")
&& main_text.contains("cached malformed action")
&& main_text.contains("cached target-only action")
&& main_text.contains("cached unsupported print"),
"computed action display text and cached unsupported PRINT text should appear in main text: {main_text:?}"
);
assert!(
!main_text.contains("stale jump")
&& !main_text.contains("stale jump upper")
&& !main_text.contains("stale run")
&& !main_text.contains("Print instruction")
&& !main_text.contains("Unquoted print instruction")
&& !main_text.contains("Multi-token print instruction")
&& !main_text.contains("PostScript instruction")
&& !main_text.contains("Compact PostScript instruction"),
"computed action display text and validated hidden PRINT output should replace stale cached text: {main_text:?}"
);
}
#[test]
fn docx_action_print_groups_accept_unquoted_multi_token_code() {
let doc = Document::open(&action_print_group_unquoted_code_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 2);
assert_eq!(fields[0].kind, FieldKind::Action("PRINT".to_string()));
assert_eq!(
fields[0].instruction,
"PRINT \\p ReportBox 0 0 moveto \\* MERGEFORMAT"
);
assert_eq!(fields[0].result, "cached unquoted print group");
assert_eq!(fields[0].computed_result.as_deref(), Some(""));
assert_eq!(fields[1].kind, FieldKind::Action("PRINT".to_string()));
assert_eq!(fields[1].instruction, "PRINT \\pReportBox compact moveto");
assert_eq!(fields[1].result, "cached compact unquoted print group");
assert_eq!(fields[1].computed_result.as_deref(), Some(""));
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
let main_text = doc.main_text();
assert!(
!main_text.contains("cached unquoted print group")
&& !main_text.contains("cached compact unquoted print group"),
"validated PRINT group output should replace stale cached text: {main_text:?}"
);
}
#[test]
fn docx_action_field_accepts_compact_neutral_format_switch() {
let doc = Document::open(&action_compact_format_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 1);
assert_eq!(fields[0].kind, FieldKind::Action("PRINT".to_string()));
assert_eq!(fields[0].instruction, "PRINT status ready \\*MERGEFORMAT");
assert_eq!(fields[0].result, "cached compact print");
assert_eq!(fields[0].computed_result.as_deref(), Some(""));
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
let main_text = doc.main_text();
assert!(
!main_text.contains("cached compact print"),
"validated compact PRINT output should replace stale cached text: {main_text:?}"
);
}
#[test]
fn docx_button_action_fields_accept_compact_format_switches() {
let doc = Document::open(&action_button_compact_format_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 2);
assert_eq!(fields[0].kind, FieldKind::Action("GOTOBUTTON".to_string()));
assert_eq!(
fields[0].instruction,
"GOTOBUTTON TargetBookmark Jump Now \\*Upper"
);
assert_eq!(fields[0].result, "stale compact jump");
assert_eq!(fields[0].computed_result.as_deref(), Some("JUMP NOW"));
assert_eq!(fields[1].kind, FieldKind::Action("MACROBUTTON".to_string()));
assert_eq!(
fields[1].instruction,
"MACROBUTTON RunReport \\*MERGEFORMAT"
);
assert_eq!(fields[1].result, "cached compact target-only action");
assert_eq!(fields[1].computed_result, None);
let report = doc.report();
assert_eq!(
report.features.unsupported_field_kinds,
vec![FieldKindCount {
kind: FieldKind::Action("MACROBUTTON".to_string()),
count: 1,
}]
);
assert_eq!(
report.features.unsupported_field_reasons,
vec![FieldEvaluationReasonCount {
reason: FieldEvaluationReason::NoComputedResult,
count: 1,
}]
);
let main_text = doc.main_text();
assert!(
main_text.contains("JUMP NOW")
&& main_text.contains("cached compact target-only action")
&& !main_text.contains("stale compact jump"),
"compact button action output/cached text should be stable: {main_text:?}"
);
}
#[test]
fn docx_action_fields_follow_accepted_current_view() {
let doc = Document::open(&action_accepted_current_field_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 2);
assert_eq!(fields[0].kind, FieldKind::Action("GOTOBUTTON".to_string()));
assert_eq!(
fields[0].instruction,
"GOTOBUTTON TargetBookmark \"Choice Jump\""
);
assert_eq!(fields[0].result, "stale choice jump");
assert_eq!(fields[0].computed_result.as_deref(), Some("Choice Jump"));
assert_eq!(fields[1].kind, FieldKind::Action("PRINT".to_string()));
assert_eq!(fields[1].instruction, "PRINT status ready");
assert_eq!(fields[1].result, "visible print cache");
assert_eq!(fields[1].computed_result.as_deref(), Some(""));
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
let main_text = doc.main_text();
assert!(main_text.contains("Choice Jump"), "{main_text:?}");
assert!(
!main_text.contains("stale choice jump")
&& !main_text.contains("visible print cache")
&& !main_text.contains("Deleted Jump")
&& !main_text.contains("deleted cached jump")
&& !main_text.contains("Fallback Jump")
&& !main_text.contains("fallback cached jump")
&& !main_text.contains("moved print cache"),
"accepted-current action fields should replace visible cached text and ignore non-current branches: {main_text:?}"
);
}
#[test]
fn docx_compatibility_fields_are_named_noncomputed_fields() {
let doc = Document::open(&compatibility_field_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 5);
assert_eq!(
fields[0].kind,
FieldKind::Compatibility("PRIVATE".to_string())
);
assert_eq!(fields[0].instruction, "PRIVATE");
assert_eq!(fields[0].result, "converted payload");
assert_eq!(fields[0].computed_result, None);
assert_eq!(
fields[1].kind,
FieldKind::Compatibility("ADDIN".to_string())
);
assert_eq!(fields[1].instruction, "ADDIN hidden-data");
assert_eq!(fields[1].result, "addin payload");
assert_eq!(fields[1].computed_result, None);
assert_eq!(fields[2].kind, FieldKind::Compatibility("DATA".to_string()));
assert_eq!(fields[2].instruction, "DATA legacy-data");
assert_eq!(fields[2].result, "data payload");
assert_eq!(fields[2].computed_result, None);
assert_eq!(
fields[3].kind,
FieldKind::Compatibility("GLOSSARY".to_string())
);
assert_eq!(fields[3].instruction, "GLOSSARY AutoTextName");
assert_eq!(fields[3].result, "glossary payload");
assert_eq!(fields[3].computed_result, None);
assert_eq!(
fields[4].kind,
FieldKind::Compatibility("HTMLACTIVEX".to_string())
);
assert_eq!(fields[4].instruction, "HTMLACTIVEX LegacyControl");
assert_eq!(fields[4].result, "activex payload");
assert_eq!(fields[4].computed_result, None);
let report = doc.report();
assert_eq!(
report.features.unsupported_field_kinds,
vec![
FieldKindCount {
kind: FieldKind::Compatibility("PRIVATE".to_string()),
count: 1,
},
FieldKindCount {
kind: FieldKind::Compatibility("ADDIN".to_string()),
count: 1,
},
FieldKindCount {
kind: FieldKind::Compatibility("DATA".to_string()),
count: 1,
},
FieldKindCount {
kind: FieldKind::Compatibility("GLOSSARY".to_string()),
count: 1,
},
FieldKindCount {
kind: FieldKind::Compatibility("HTMLACTIVEX".to_string()),
count: 1,
},
]
);
assert_eq!(
report.features.unsupported_field_reasons,
vec![FieldEvaluationReasonCount {
reason: FieldEvaluationReason::NoComputedResult,
count: 5,
}]
);
assert!(
doc.main_text().contains("converted payload")
&& doc.main_text().contains("addin payload")
&& doc.main_text().contains("data payload")
&& doc.main_text().contains("glossary payload")
&& doc.main_text().contains("activex payload"),
"{:?}",
doc.main_text()
);
}
#[test]
fn docx_compatibility_diagnostics_split_valid_broader_fields_from_malformed_syntax() {
let doc = Document::open(&docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:fldSimple w:instr=" PRIVATE legacy-data "><w:r><w:t>cached private payload</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" ADDIN "bad "><w:r><w:t>cached malformed addin</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
]))
.expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 2);
assert_eq!(
fields[0].kind,
FieldKind::Compatibility("PRIVATE".to_string())
);
assert_eq!(fields[0].computed_result, None);
assert_eq!(
fields[1].kind,
FieldKind::Compatibility("ADDIN".to_string())
);
assert_eq!(fields[1].instruction, r#"ADDIN "bad "#);
assert_eq!(fields[1].computed_result, None);
let report = doc.report();
assert_eq!(
report.features.unsupported_field_kinds,
vec![
FieldKindCount {
kind: FieldKind::Compatibility("PRIVATE".to_string()),
count: 1,
},
FieldKindCount {
kind: FieldKind::Compatibility("ADDIN".to_string()),
count: 1,
},
]
);
assert_eq!(
report.features.unsupported_field_reasons,
vec![
FieldEvaluationReasonCount {
reason: FieldEvaluationReason::NoComputedResult,
count: 1,
},
FieldEvaluationReasonCount {
reason: FieldEvaluationReason::UnsupportedSwitch,
count: 1,
},
]
);
assert_eq!(
model_simple_field_reason_hints(&doc, |instruction| {
instruction.starts_with("PRIVATE") || instruction.starts_with("ADDIN")
}),
vec![
(
"PRIVATE legacy-data".to_string(),
Some(FieldUnsupportedReason::NoComputedResult),
),
(
r#"ADDIN "bad "#.to_string(),
Some(FieldUnsupportedReason::UnsupportedSwitch),
),
]
);
assert!(doc.main_text().contains("cached malformed addin"));
}
#[test]
fn docx_barcode_fields_are_named_noncomputed_fields() {
let doc = Document::open(&barcode_field_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 3);
assert_eq!(
fields[0].kind,
FieldKind::Barcode("DISPLAYBARCODE".to_string())
);
assert_eq!(
fields[0].instruction,
"DISPLAYBARCODE \"https://example.com\" QR \\q H"
);
assert_eq!(fields[0].result, "QR preview");
assert_eq!(fields[0].computed_result, None);
assert_eq!(
fields[1].kind,
FieldKind::Barcode("MERGEBARCODE".to_string())
);
assert_eq!(fields[1].instruction, "MERGEBARCODE CustomerId CODE128 \\t");
assert_eq!(fields[1].result, "Merge barcode preview");
assert_eq!(fields[1].computed_result, None);
assert_eq!(fields[2].kind, FieldKind::Barcode("BARCODE".to_string()));
assert_eq!(fields[2].instruction, "BARCODE \"9781234567890\"");
assert_eq!(fields[2].result, "Legacy barcode preview");
assert_eq!(fields[2].computed_result, None);
let report = doc.report();
assert_eq!(
report.features.unsupported_field_kinds,
vec![
FieldKindCount {
kind: FieldKind::Barcode("DISPLAYBARCODE".to_string()),
count: 1,
},
FieldKindCount {
kind: FieldKind::Barcode("MERGEBARCODE".to_string()),
count: 1,
},
FieldKindCount {
kind: FieldKind::Barcode("BARCODE".to_string()),
count: 1,
},
]
);
assert_eq!(
report.features.unsupported_field_reasons,
vec![FieldEvaluationReasonCount {
reason: FieldEvaluationReason::NoComputedResult,
count: 3,
}]
);
let main_text = doc.main_text();
assert!(
main_text.contains("QR preview")
&& main_text.contains("Merge barcode preview")
&& main_text.contains("Legacy barcode preview"),
"cached barcode field results should remain in main text: {main_text:?}"
);
}
#[test]
fn docx_barcode_diagnostics_split_valid_broader_fields_from_malformed_syntax() {
let doc = Document::open(&docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:fldSimple w:instr=" DISPLAYBARCODE "https://example.com" QR \q H "><w:r><w:t>QR preview</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" DISPLAYBARCODE "https://example.com" QR \* Upper "><w:r><w:t>formatted QR preview</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" DISPLAYBARCODE "https://example.com" \q H "><w:r><w:t>cached missing barcode type</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" DISPLAYBARCODE "https://example.com" QR \q "><w:r><w:t>cached missing quality operand</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" DISPLAYBARCODE "https://example.com QR "><w:r><w:t>cached malformed barcode</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" DISPLAYBARCODE "https://example.com" QR \* "><w:r><w:t>cached dangling barcode format</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" DISPLAYBARCODE "https://example.com" QR \* BadFormat "><w:r><w:t>cached bad barcode format</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
]))
.expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 7);
assert_eq!(
fields[0].kind,
FieldKind::Barcode("DISPLAYBARCODE".to_string())
);
assert_eq!(
fields[0].instruction,
r#"DISPLAYBARCODE "https://example.com" QR \q H"#
);
assert_eq!(fields[0].computed_result, None);
assert_eq!(
fields[1].kind,
FieldKind::Barcode("DISPLAYBARCODE".to_string())
);
assert_eq!(
fields[1].instruction,
r#"DISPLAYBARCODE "https://example.com" QR \* Upper"#
);
assert_eq!(fields[1].computed_result, None);
assert_eq!(
fields[2].kind,
FieldKind::Barcode("DISPLAYBARCODE".to_string())
);
assert_eq!(
fields[2].instruction,
r#"DISPLAYBARCODE "https://example.com" \q H"#
);
assert_eq!(fields[2].computed_result, None);
assert_eq!(
fields[3].kind,
FieldKind::Barcode("DISPLAYBARCODE".to_string())
);
assert_eq!(
fields[3].instruction,
r#"DISPLAYBARCODE "https://example.com" QR \q"#
);
assert_eq!(fields[3].computed_result, None);
assert_eq!(
fields[4].kind,
FieldKind::Barcode("DISPLAYBARCODE".to_string())
);
assert_eq!(
fields[4].instruction,
r#"DISPLAYBARCODE "https://example.com QR "#
);
assert_eq!(fields[4].computed_result, None);
assert_eq!(
fields[5].kind,
FieldKind::Barcode("DISPLAYBARCODE".to_string())
);
assert_eq!(
fields[5].instruction,
r#"DISPLAYBARCODE "https://example.com" QR \*"#
);
assert_eq!(fields[5].computed_result, None);
assert_eq!(
fields[6].kind,
FieldKind::Barcode("DISPLAYBARCODE".to_string())
);
assert_eq!(
fields[6].instruction,
r#"DISPLAYBARCODE "https://example.com" QR \* BadFormat"#
);
assert_eq!(fields[6].computed_result, None);
let report = doc.report();
assert_eq!(
report.features.unsupported_field_kinds,
vec![FieldKindCount {
kind: FieldKind::Barcode("DISPLAYBARCODE".to_string()),
count: 7,
}]
);
assert_eq!(
report.features.unsupported_field_reasons,
vec![
FieldEvaluationReasonCount {
reason: FieldEvaluationReason::NoComputedResult,
count: 2,
},
FieldEvaluationReasonCount {
reason: FieldEvaluationReason::UnsupportedSwitch,
count: 5,
},
]
);
assert_eq!(
model_simple_field_reason_hints(&doc, |instruction| {
instruction.starts_with("DISPLAYBARCODE")
}),
vec![
(
r#"DISPLAYBARCODE "https://example.com" QR \q H"#.to_string(),
Some(FieldUnsupportedReason::NoComputedResult),
),
(
r#"DISPLAYBARCODE "https://example.com" QR \* Upper"#.to_string(),
Some(FieldUnsupportedReason::NoComputedResult),
),
(
r#"DISPLAYBARCODE "https://example.com" \q H"#.to_string(),
Some(FieldUnsupportedReason::UnsupportedSwitch),
),
(
r#"DISPLAYBARCODE "https://example.com" QR \q"#.to_string(),
Some(FieldUnsupportedReason::UnsupportedSwitch),
),
(
r#"DISPLAYBARCODE "https://example.com QR "#.to_string(),
Some(FieldUnsupportedReason::UnsupportedSwitch),
),
(
r#"DISPLAYBARCODE "https://example.com" QR \*"#.to_string(),
Some(FieldUnsupportedReason::UnsupportedSwitch),
),
(
r#"DISPLAYBARCODE "https://example.com" QR \* BadFormat"#.to_string(),
Some(FieldUnsupportedReason::UnsupportedSwitch),
),
]
);
assert!(doc.main_text().contains("cached missing barcode type"));
assert!(doc.main_text().contains("cached missing quality operand"));
assert!(doc.main_text().contains("cached malformed barcode"));
assert!(doc.main_text().contains("cached dangling barcode format"));
assert!(doc.main_text().contains("cached bad barcode format"));
}
#[test]
fn docx_barcode_fields_accept_compact_argument_switches() {
let doc = Document::open(&docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:fldSimple w:instr=" DISPLAYBARCODE "12345" QR \qH "><w:r><w:t>Compact QR preview</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" MERGEBARCODE Zip JPPOST \h1440 \s100 \r1 \f0x000000 \bFFFFFF \t \a "><w:r><w:t>Compact merge barcode preview</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
]))
.expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 2);
assert_eq!(
fields[0].kind,
FieldKind::Barcode("DISPLAYBARCODE".to_string())
);
assert_eq!(fields[0].instruction, r#"DISPLAYBARCODE "12345" QR \qH"#);
assert_eq!(fields[0].computed_result, None);
assert_eq!(
fields[1].kind,
FieldKind::Barcode("MERGEBARCODE".to_string())
);
assert_eq!(
fields[1].instruction,
r#"MERGEBARCODE Zip JPPOST \h1440 \s100 \r1 \f0x000000 \bFFFFFF \t \a"#
);
assert_eq!(fields[1].computed_result, None);
let report = doc.report();
assert_eq!(
report.features.unsupported_field_kinds,
vec![
FieldKindCount {
kind: FieldKind::Barcode("DISPLAYBARCODE".to_string()),
count: 1,
},
FieldKindCount {
kind: FieldKind::Barcode("MERGEBARCODE".to_string()),
count: 1,
},
]
);
assert_eq!(
report.features.unsupported_field_reasons,
vec![FieldEvaluationReasonCount {
reason: FieldEvaluationReason::NoComputedResult,
count: 2,
}]
);
let main_text = doc.main_text();
assert!(
main_text.contains("Compact QR preview")
&& main_text.contains("Compact merge barcode preview"),
"known barcode forms should preserve cached preview text: {main_text:?}"
);
}
#[test]
fn docx_legacy_form_fields_materialize_deterministic_values() {
let doc = Document::open(&legacy_form_field_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 8);
assert_eq!(fields[0].kind, FieldKind::FormField("FORMTEXT".to_string()));
assert_eq!(fields[0].instruction, "FORMTEXT");
assert_eq!(fields[0].result, "Alice");
assert_eq!(fields[0].computed_result.as_deref(), Some("Alice"));
assert_eq!(fields[1].kind, FieldKind::FormField("FORMTEXT".to_string()));
assert_eq!(fields[1].instruction, "FORMTEXT");
assert_eq!(fields[1].result, "");
assert_eq!(fields[1].computed_result.as_deref(), Some("No content."));
assert_eq!(
fields[2].kind,
FieldKind::FormField("FORMCHECKBOX".to_string())
);
assert_eq!(fields[2].result, "stale checked");
assert_eq!(fields[2].computed_result.as_deref(), Some("☒"));
assert_eq!(
fields[3].kind,
FieldKind::FormField("FORMCHECKBOX".to_string())
);
assert_eq!(fields[3].result, "stale unchecked");
assert_eq!(fields[3].computed_result.as_deref(), Some("☐"));
assert_eq!(
fields[4].kind,
FieldKind::FormField("FORMCHECKBOX".to_string())
);
assert_eq!(fields[4].result, "stale default checked");
assert_eq!(fields[4].computed_result.as_deref(), Some("☒"));
assert_eq!(
fields[5].kind,
FieldKind::FormField("FORMDROPDOWN".to_string())
);
assert_eq!(fields[5].result, "stale option");
assert_eq!(fields[5].computed_result.as_deref(), Some("Option C"));
assert_eq!(
fields[6].kind,
FieldKind::FormField("FORMDROPDOWN".to_string())
);
assert_eq!(fields[6].result, "stale default option");
assert_eq!(fields[6].computed_result.as_deref(), Some("Default B"));
assert_eq!(
fields[7].kind,
FieldKind::FormField("FORMDROPDOWN".to_string())
);
assert_eq!(fields[7].result, "stale invalid option");
assert_eq!(fields[7].computed_result.as_deref(), Some("Fallback B"));
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
let main_text = doc.main_text();
assert!(
main_text.contains("Alice")
&& main_text.contains("No content.")
&& main_text.contains("☒")
&& main_text.contains("☐")
&& main_text.contains("Option C")
&& main_text.contains("Default B")
&& main_text.contains("Fallback B"),
"computed legacy form field results should appear in main text: {main_text:?}"
);
assert!(
!main_text.contains("stale checked")
&& !main_text.contains("stale unchecked")
&& !main_text.contains("stale default checked")
&& !main_text.contains("stale option")
&& !main_text.contains("stale default option")
&& !main_text.contains("stale invalid option"),
"computed legacy form field results should replace stale cached text: {main_text:?}"
);
}
#[test]
fn docx_ref_targets_use_computed_legacy_form_results() {
let doc = Document::open(&legacy_form_ref_target_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 3);
assert_eq!(
fields[0].kind,
FieldKind::FormField("FORMDROPDOWN".to_string())
);
assert_eq!(fields[0].result, "stale prior option");
assert_eq!(fields[0].computed_result.as_deref(), Some("Prior B"));
assert_eq!(
fields[1].kind,
FieldKind::FormField("FORMDROPDOWN".to_string())
);
assert_eq!(fields[1].result, "stale target option");
assert_eq!(fields[1].computed_result.as_deref(), Some("Target B"));
assert_eq!(fields[2].kind, FieldKind::Ref);
assert_eq!(fields[2].instruction, "REF SelectedOption");
assert_eq!(fields[2].result, "cached form ref");
assert_eq!(fields[2].computed_result.as_deref(), Some("Target B"));
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
let main_text = doc.main_text();
assert!(
main_text.contains("Prior B")
&& main_text.contains("Target B")
&& !main_text.contains("stale target option")
&& !main_text.contains("cached form ref"),
"REF target scanner should reuse computed legacy form values: {main_text:?}"
);
}
#[test]
fn docx_legacy_form_field_format_switches_apply_to_dropdowns() {
let doc = Document::open(&docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:fldSimple w:instr=" FORMDROPDOWN \* Upper "><w:ffData><w:ddList><w:result w:val="1"/><w:listEntry w:val="first"/><w:listEntry w:val="chosen option"/></w:ddList></w:ffData><w:r><w:t>stale dropdown</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" FORMCHECKBOX \* MERGEFORMAT "><w:ffData><w:checkBox><w:checked w:val="true"/></w:checkBox></w:ffData><w:r><w:t>stale checkbox</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
]))
.expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 2);
assert_eq!(
fields[0].kind,
FieldKind::FormField("FORMDROPDOWN".to_string())
);
assert_eq!(fields[0].computed_result.as_deref(), Some("CHOSEN OPTION"));
assert_eq!(
fields[1].kind,
FieldKind::FormField("FORMCHECKBOX".to_string())
);
assert_eq!(fields[1].computed_result.as_deref(), Some("\u{2612}"));
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
let main_text = doc.main_text();
assert!(
main_text.contains("CHOSEN OPTION")
&& main_text.contains('\u{2612}')
&& !main_text.contains("stale dropdown")
&& !main_text.contains("stale checkbox"),
"legacy form field format switches should materialize deterministic results: {main_text:?}"
);
}
#[test]
fn docx_legacy_form_fields_accept_compact_format_switches() {
let doc = Document::open(&docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:fldSimple w:instr=" FORMDROPDOWN \*Upper "><w:ffData><w:ddList><w:result w:val="1"/><w:listEntry w:val="first"/><w:listEntry w:val="chosen option"/></w:ddList></w:ffData><w:r><w:t>stale compact dropdown</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" FORMTEXT \*Upper "><w:r><w:t>alice</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
]))
.expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 2);
assert_eq!(
fields[0].kind,
FieldKind::FormField("FORMDROPDOWN".to_string())
);
assert_eq!(fields[0].instruction, "FORMDROPDOWN \\*Upper");
assert_eq!(fields[0].computed_result.as_deref(), Some("CHOSEN OPTION"));
assert_eq!(fields[1].kind, FieldKind::FormField("FORMTEXT".to_string()));
assert_eq!(fields[1].instruction, "FORMTEXT \\*Upper");
assert_eq!(fields[1].computed_result.as_deref(), Some("ALICE"));
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
let main_text = doc.main_text();
assert!(
main_text.contains("CHOSEN OPTION")
&& main_text.contains("ALICE")
&& !main_text.contains("stale compact dropdown")
&& !main_text.contains("alice"),
"compact legacy form format switches should materialize deterministic results: {main_text:?}"
);
}
#[test]
fn docx_legacy_form_dropdown_indices_accept_whitespace() {
let doc = Document::open(&docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:fldSimple w:instr=" FORMDROPDOWN "><w:ffData><w:ddList><w:default w:val=" 0 "/><w:result w:val=" 1 "/><w:listEntry w:val="Default A"/><w:listEntry w:val="Chosen B"/></w:ddList></w:ffData><w:r><w:t>stale spaced dropdown</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
]))
.expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 1);
assert_eq!(
fields[0].kind,
FieldKind::FormField("FORMDROPDOWN".to_string())
);
assert_eq!(fields[0].result, "stale spaced dropdown");
assert_eq!(fields[0].computed_result.as_deref(), Some("Chosen B"));
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
let main_text = doc.main_text();
assert!(
main_text.contains("Chosen B") && !main_text.contains("stale spaced dropdown"),
"whitespace-padded dropdown indexes should materialize: {main_text:?}"
);
}
#[test]
fn docx_legacy_form_context_ignores_deleted_fields() {
let doc = Document::open(&legacy_form_deleted_field_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 1);
assert_eq!(
fields[0].kind,
FieldKind::FormField("FORMCHECKBOX".to_string())
);
assert_eq!(fields[0].result, "stale visible unchecked");
assert_eq!(fields[0].computed_result.as_deref(), Some("\u{2610}"));
let main_text = doc.main_text();
assert!(
main_text.contains('\u{2610}') && !main_text.contains("deleted checked"),
"deleted form metadata must not shift visible form results: {main_text:?}"
);
}
#[test]
fn docx_legacy_form_context_uses_single_alternate_content_branch() {
let doc = Document::open(&legacy_form_alternate_content_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 1);
assert_eq!(
fields[0].kind,
FieldKind::FormField("FORMDROPDOWN".to_string())
);
assert_eq!(fields[0].result, "stale option");
assert_eq!(fields[0].computed_result.as_deref(), Some("Choice option"));
let main_text = doc.main_text();
assert!(
main_text.contains("Choice option") && !main_text.contains("Fallback option"),
"computed legacy form field must use one AlternateContent branch: {main_text:?}"
);
}
#[test]
fn docx_malformed_legacy_form_fields_preserve_cached_text() {
let doc = Document::open(&docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:fldSimple w:instr=" FORMCHECKBOX "bad "><w:ffData><w:checkBox><w:checked w:val="true"/></w:checkBox></w:ffData><w:r><w:t>cached malformed checkbox</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
]))
.expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 1);
assert_eq!(
fields[0].kind,
FieldKind::FormField("FORMCHECKBOX".to_string())
);
assert_eq!(fields[0].instruction, r#"FORMCHECKBOX "bad "#);
assert_eq!(fields[0].result, "cached malformed checkbox");
assert_eq!(fields[0].computed_result, None);
let report = doc.report();
assert_eq!(
report.features.unsupported_field_kinds,
vec![FieldKindCount {
kind: FieldKind::FormField("FORMCHECKBOX".to_string()),
count: 1,
}]
);
assert_eq!(
report.features.unsupported_field_reasons,
vec![FieldEvaluationReasonCount {
reason: FieldEvaluationReason::UnsupportedSwitch,
count: 1,
}]
);
assert!(doc.main_text().contains("cached malformed checkbox"));
}
#[test]
fn docx_legacy_form_fields_report_malformed_format_switches() {
let doc = Document::open(&docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:fldSimple w:instr=" FORMTEXT \* Upper "><w:r><w:t>alice</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" FORMTEXT \* BadFormat "><w:r><w:t>cached bad format</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
]))
.expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 2);
assert_eq!(fields[0].computed_result.as_deref(), Some("ALICE"));
assert_eq!(fields[1].computed_result, None);
let report = doc.report();
assert_eq!(
report.features.unsupported_field_reasons,
vec![FieldEvaluationReasonCount {
reason: FieldEvaluationReason::UnsupportedSwitch,
count: 1,
}]
);
assert!(doc.main_text().contains("ALICE"));
assert!(doc.main_text().contains("cached bad format"));
}
#[test]
fn docx_protected_legacy_form_fields_preserve_cached_text() {
let doc = Document::open(&docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/><Override PartName="/word/settings.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.settings+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/settings.xml",
r#"<w:settings xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:documentProtection w:edit=" forms " w:enforcement="1"/></w:settings>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:r><w:fldChar w:fldCharType="begin"><w:ffData><w:checkBox><w:checked w:val="true"/></w:checkBox></w:ffData></w:fldChar></w:r><w:r><w:instrText> FORMCHECKBOX </w:instrText></w:r><w:r><w:fldChar w:fldCharType="separate"/></w:r><w:r><w:t>cached protected checked</w:t></w:r><w:r><w:fldChar w:fldCharType="end"/></w:r></w:p></w:body></w:document>"#,
),
]))
.expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 1);
assert_eq!(
fields[0].kind,
FieldKind::FormField("FORMCHECKBOX".to_string())
);
assert_eq!(fields[0].result, "cached protected checked");
assert_eq!(fields[0].computed_result, None);
let report = doc.report();
assert_eq!(
report.features.unsupported_field_kinds,
vec![FieldKindCount {
kind: FieldKind::FormField("FORMCHECKBOX".to_string()),
count: 1,
}]
);
assert_eq!(
report.features.unsupported_field_reasons,
vec![FieldEvaluationReasonCount {
reason: FieldEvaluationReason::NoComputedResult,
count: 1,
}]
);
let main_text = doc.main_text();
assert!(main_text.contains("cached protected checked"));
assert!(!main_text.contains('\u{2612}'));
}
#[test]
fn docx_protected_non_body_legacy_form_fields_preserve_cached_text() {
let doc = Document::open(&docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/><Override PartName="/word/settings.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.settings+xml"/><Override PartName="/word/header1.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.header+xml"/><Override PartName="/word/footnotes.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.footnotes+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/settings.xml",
r#"<w:settings xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:documentProtection w:edit="forms" w:enforcement="1"/></w:settings>"#,
),
(
"word/_rels/document.xml.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rIdHeader" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/header" Target="header1.xml"/><Relationship Id="rIdFootnotes" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/footnotes" Target="footnotes.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"><w:body><w:p><w:r><w:t>Body</w:t></w:r><w:r><w:footnoteReference w:id="1"/></w:r></w:p><w:sectPr><w:headerReference w:type="default" r:id="rIdHeader"/></w:sectPr></w:body></w:document>"#,
),
(
"word/header1.xml",
r#"<w:hdr xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:p><w:fldSimple w:instr=" FORMTEXT \* Upper "><w:r><w:t>alice</w:t></w:r></w:fldSimple></w:p></w:hdr>"#,
),
(
"word/footnotes.xml",
r#"<w:footnotes xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:footnote w:type="separator" w:id="-1"><w:p><w:r><w:separator/></w:r></w:p></w:footnote><w:footnote w:id="1"><w:p><w:fldSimple w:instr=" FORMTEXT \* Upper "><w:r><w:t>bob</w:t></w:r></w:fldSimple></w:p></w:footnote></w:footnotes>"#,
),
]))
.expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 2);
assert!(fields.iter().all(|field| {
field.kind == FieldKind::FormField("FORMTEXT".to_string())
&& field.computed_result.is_none()
}));
assert!(fields.iter().any(|field| field.result == "alice"));
assert!(fields.iter().any(|field| field.result == "bob"));
let report = doc.report();
assert_eq!(
report.features.unsupported_field_kinds,
vec![FieldKindCount {
kind: FieldKind::FormField("FORMTEXT".to_string()),
count: 2,
}]
);
assert_eq!(
report.features.unsupported_field_reasons,
vec![FieldEvaluationReasonCount {
reason: FieldEvaluationReason::NoComputedResult,
count: 2,
}]
);
assert!(doc.header_text().contains("alice"));
assert!(doc.footnote_text().contains("bob"));
assert!(!doc.text().contains("ALICE"));
assert!(!doc.text().contains("BOB"));
}
#[test]
fn docx_non_body_legacy_form_fields_materialize_values() {
let doc = Document::open(&docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/><Override PartName="/word/header1.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.header+xml"/><Override PartName="/word/footnotes.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.footnotes+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/_rels/document.xml.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rIdHeader" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/header" Target="header1.xml"/><Relationship Id="rIdFootnotes" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/footnotes" Target="footnotes.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"><w:body><w:p><w:r><w:t>Body</w:t></w:r><w:r><w:footnoteReference w:id="1"/></w:r></w:p><w:sectPr><w:headerReference w:type="default" r:id="rIdHeader"/></w:sectPr></w:body></w:document>"#,
),
(
"word/header1.xml",
r#"<w:hdr xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:p><w:fldSimple w:instr=" FORMCHECKBOX "><w:ffData><w:checkBox><w:checked w:val="true"/></w:checkBox></w:ffData><w:r><w:t>stale header checkbox</w:t></w:r></w:fldSimple></w:p></w:hdr>"#,
),
(
"word/footnotes.xml",
r#"<w:footnotes xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:footnote w:type="separator" w:id="-1"><w:p><w:r><w:separator/></w:r></w:p></w:footnote><w:footnote w:id="1"><w:p><w:fldSimple w:instr=" FORMDROPDOWN "><w:ffData><w:ddList><w:result w:val="1"/><w:listEntry w:val="Option A"/><w:listEntry w:val="Option B"/></w:ddList></w:ffData><w:r><w:t>stale footnote option</w:t></w:r></w:fldSimple></w:p></w:footnote></w:footnotes>"#,
),
]))
.expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 2);
assert!(fields.iter().any(|field| {
field.kind == FieldKind::FormField("FORMCHECKBOX".to_string())
&& field.result == "stale header checkbox"
&& field.computed_result.as_deref() == Some("\u{2612}")
}));
assert!(fields.iter().any(|field| {
field.kind == FieldKind::FormField("FORMDROPDOWN".to_string())
&& field.result == "stale footnote option"
&& field.computed_result.as_deref() == Some("Option B")
}));
assert!(doc.header_text().contains('\u{2612}'));
assert!(doc.footnote_text().contains("Option B"));
assert!(!doc.text().contains("stale header checkbox"));
assert!(!doc.text().contains("stale footnote option"));
}
#[test]
fn docx_non_body_table_formula_fields_materialize_values() {
let doc = Document::open(&docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/><Override PartName="/word/header1.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.header+xml"/><Override PartName="/word/footnotes.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.footnotes+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/_rels/document.xml.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rIdHeader" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/header" Target="header1.xml"/><Relationship Id="rIdFootnotes" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/footnotes" Target="footnotes.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"><w:body><w:p><w:r><w:t>Body</w:t></w:r><w:r><w:footnoteReference w:id="1"/></w:r></w:p><w:sectPr><w:headerReference w:type="default" r:id="rIdHeader"/></w:sectPr></w:body></w:document>"#,
),
(
"word/header1.xml",
r#"<w:hdr xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:tbl><w:tr><w:tc><w:p><w:r><w:t>2</w:t></w:r></w:p></w:tc><w:tc><w:p><w:r><w:t>3</w:t></w:r></w:p></w:tc><w:tc><w:p><w:fldSimple w:instr=" = SUM(LEFT) "><w:r><w:t>stale header sum</w:t></w:r></w:fldSimple></w:p></w:tc></w:tr></w:tbl></w:hdr>"#,
),
(
"word/footnotes.xml",
r#"<w:footnotes xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:footnote w:type="separator" w:id="-1"><w:p><w:r><w:separator/></w:r></w:p></w:footnote><w:footnote w:id="1"><w:tbl><w:tr><w:tc><w:p><w:r><w:t>4</w:t></w:r></w:p></w:tc><w:tc><w:p><w:r><w:t>5</w:t></w:r></w:p></w:tc><w:tc><w:p><w:fldSimple w:instr=" = SUM(LEFT) "><w:r><w:t>stale footnote sum</w:t></w:r></w:fldSimple></w:p></w:tc></w:tr></w:tbl></w:footnote></w:footnotes>"#,
),
]))
.expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 2);
assert!(fields.iter().any(|field| {
field.kind == FieldKind::Dynamic("=".to_string())
&& field.result == "stale header sum"
&& field.computed_result.as_deref() == Some("5")
}));
assert!(fields.iter().any(|field| {
field.kind == FieldKind::Dynamic("=".to_string())
&& field.result == "stale footnote sum"
&& field.computed_result.as_deref() == Some("9")
}));
assert!(doc.header_text().contains("5"));
assert!(doc.footnote_text().contains("9"));
assert!(!doc.text().contains("stale header sum"));
assert!(!doc.text().contains("stale footnote sum"));
}
#[test]
fn docx_non_body_ref_fields_materialize_local_bookmark_text() {
let doc = Document::open(&docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/><Override PartName="/word/header1.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.header+xml"/><Override PartName="/word/footnotes.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.footnotes+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/_rels/document.xml.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rIdHeader" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/header" Target="header1.xml"/><Relationship Id="rIdFootnotes" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/footnotes" Target="footnotes.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"><w:body><w:p><w:r><w:t>Body</w:t></w:r><w:r><w:footnoteReference w:id="1"/></w:r></w:p><w:sectPr><w:headerReference w:type="default" r:id="rIdHeader"/></w:sectPr></w:body></w:document>"#,
),
(
"word/header1.xml",
r#"<w:hdr xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:p><w:bookmarkStart w:id="11" w:name="HeaderTarget"/><w:r><w:t>Header Value</w:t></w:r><w:bookmarkEnd w:id="11"/></w:p><w:p><w:fldSimple w:instr=" REF HeaderTarget "><w:r><w:t>stale header ref</w:t></w:r></w:fldSimple></w:p></w:hdr>"#,
),
(
"word/footnotes.xml",
r#"<w:footnotes xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:footnote w:type="separator" w:id="-1"><w:p><w:r><w:separator/></w:r></w:p></w:footnote><w:footnote w:id="1"><w:p><w:bookmarkStart w:id="12" w:name="FootTarget"/><w:r><w:t>Foot Value</w:t></w:r><w:bookmarkEnd w:id="12"/></w:p><w:p><w:fldSimple w:instr=" REF FootTarget "><w:r><w:t>stale footnote ref</w:t></w:r></w:fldSimple></w:p></w:footnote></w:footnotes>"#,
),
]))
.expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 2);
assert!(fields.iter().any(|field| {
field.kind == FieldKind::Ref
&& field.result == "stale header ref"
&& field.computed_result.as_deref() == Some("Header Value")
}));
assert!(fields.iter().any(|field| {
field.kind == FieldKind::Ref
&& field.result == "stale footnote ref"
&& field.computed_result.as_deref() == Some("Foot Value")
}));
assert!(doc.header_text().contains("Header Value"));
assert!(doc.footnote_text().contains("Foot Value"));
assert!(!doc.text().contains("stale header ref"));
assert!(!doc.text().contains("stale footnote ref"));
}
#[test]
fn docx_non_body_style_ref_fields_materialize_local_source_text() {
let doc = Document::open(&docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/><Override PartName="/word/styles.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml"/><Override PartName="/word/header1.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.header+xml"/><Override PartName="/word/footnotes.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.footnotes+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/_rels/document.xml.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rIdHeader" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/header" Target="header1.xml"/><Relationship Id="rIdFootnotes" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/footnotes" Target="footnotes.xml"/></Relationships>"#,
),
(
"word/styles.xml",
r#"<w:styles xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:style w:type="paragraph" w:styleId="Heading1"><w:name w:val="heading 1"/></w:style></w:styles>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"><w:body><w:p><w:r><w:t>Body</w:t></w:r><w:r><w:footnoteReference w:id="1"/></w:r></w:p><w:sectPr><w:headerReference w:type="default" r:id="rIdHeader"/></w:sectPr></w:body></w:document>"#,
),
(
"word/header1.xml",
r#"<w:hdr xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:p><w:pPr><w:pStyle w:val="Heading1"/></w:pPr><w:r><w:t>Header Heading</w:t></w:r></w:p><w:p><w:fldSimple w:instr=" STYLEREF "heading 1" "><w:r><w:t>stale header style ref</w:t></w:r></w:fldSimple></w:p></w:hdr>"#,
),
(
"word/footnotes.xml",
r#"<w:footnotes xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:footnote w:type="separator" w:id="-1"><w:p><w:r><w:separator/></w:r></w:p></w:footnote><w:footnote w:id="1"><w:p><w:pPr><w:pStyle w:val="Heading1"/></w:pPr><w:r><w:t>Foot Heading</w:t></w:r></w:p><w:p><w:fldSimple w:instr=" STYLEREF "heading 1" "><w:r><w:t>stale footnote style ref</w:t></w:r></w:fldSimple></w:p></w:footnote></w:footnotes>"#,
),
]))
.expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 2);
assert!(fields.iter().any(|field| {
field.kind == FieldKind::DocumentStructure("STYLEREF".to_string())
&& field.result == "stale header style ref"
&& field.computed_result.as_deref() == Some("Header Heading")
}));
assert!(fields.iter().any(|field| {
field.kind == FieldKind::DocumentStructure("STYLEREF".to_string())
&& field.result == "stale footnote style ref"
&& field.computed_result.as_deref() == Some("Foot Heading")
}));
assert!(doc.header_text().contains("Header Heading"));
assert!(doc.footnote_text().contains("Foot Heading"));
assert!(!doc.text().contains("stale header style ref"));
assert!(!doc.text().contains("stale footnote style ref"));
}
#[test]
fn docx_non_body_numbered_ref_fields_materialize_local_number_text() {
let doc = Document::open(&docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/><Override PartName="/word/numbering.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.numbering+xml"/><Override PartName="/word/header1.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.header+xml"/><Override PartName="/word/footnotes.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.footnotes+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/_rels/document.xml.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rIdHeader" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/header" Target="header1.xml"/><Relationship Id="rIdFootnotes" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/footnotes" Target="footnotes.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"><w:body><w:p><w:r><w:t>Body</w:t></w:r><w:r><w:footnoteReference w:id="1"/></w:r></w:p><w:sectPr><w:headerReference w:type="default" r:id="rIdHeader"/></w:sectPr></w:body></w:document>"#,
),
(
"word/header1.xml",
r#"<w:hdr xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:p><w:pPr><w:numPr><w:ilvl w:val="0"/><w:numId w:val="42"/></w:numPr></w:pPr><w:bookmarkStart w:id="21" w:name="HeaderClause"/><w:r><w:t>Header Clause</w:t></w:r><w:bookmarkEnd w:id="21"/></w:p><w:p><w:fldSimple w:instr=" REF HeaderClause \n "><w:r><w:t>stale header number</w:t></w:r></w:fldSimple></w:p></w:hdr>"#,
),
(
"word/footnotes.xml",
r#"<w:footnotes xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:footnote w:type="separator" w:id="-1"><w:p><w:r><w:separator/></w:r></w:p></w:footnote><w:footnote w:id="1"><w:p><w:pPr><w:numPr><w:ilvl w:val="0"/><w:numId w:val="77"/></w:numPr></w:pPr><w:bookmarkStart w:id="22" w:name="FootClause"/><w:r><w:t>Foot Clause</w:t></w:r><w:bookmarkEnd w:id="22"/></w:p><w:p><w:fldSimple w:instr=" REF FootClause \n "><w:r><w:t>stale footnote number</w:t></w:r></w:fldSimple></w:p></w:footnote></w:footnotes>"#,
),
(
"word/numbering.xml",
r#"<w:numbering xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:abstractNum w:abstractNumId="9"><w:lvl w:ilvl="0"><w:start w:val="3"/><w:numFmt w:val="decimal"/><w:lvlText w:val="%1."/></w:lvl></w:abstractNum><w:num w:numId="42"><w:abstractNumId w:val="9"/></w:num><w:abstractNum w:abstractNumId="10"><w:lvl w:ilvl="0"><w:start w:val="8"/><w:numFmt w:val="decimal"/><w:lvlText w:val="%1."/></w:lvl></w:abstractNum><w:num w:numId="77"><w:abstractNumId w:val="10"/></w:num></w:numbering>"#,
),
]))
.expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 2);
assert!(fields.iter().any(|field| {
field.kind == FieldKind::Ref
&& field.result == "stale header number"
&& field.computed_result.as_deref() == Some("3")
}));
assert!(fields.iter().any(|field| {
field.kind == FieldKind::Ref
&& field.result == "stale footnote number"
&& field.computed_result.as_deref() == Some("8")
}));
assert!(doc.header_text().contains("3"));
assert!(doc.footnote_text().contains("8"));
assert!(!doc.text().contains("stale header number"));
assert!(!doc.text().contains("stale footnote number"));
}
#[test]
fn docx_non_body_relative_ref_fields_materialize_local_position_text() {
let doc = Document::open(&docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/><Override PartName="/word/header1.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.header+xml"/><Override PartName="/word/footnotes.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.footnotes+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/_rels/document.xml.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rIdHeader" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/header" Target="header1.xml"/><Relationship Id="rIdFootnotes" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/footnotes" Target="footnotes.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"><w:body><w:p><w:r><w:t>Body</w:t></w:r><w:r><w:footnoteReference w:id="1"/></w:r></w:p><w:sectPr><w:headerReference w:type="default" r:id="rIdHeader"/></w:sectPr></w:body></w:document>"#,
),
(
"word/header1.xml",
r#"<w:hdr xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:p><w:fldSimple w:instr=" REF HeaderLater \p "><w:r><w:t>stale header position</w:t></w:r></w:fldSimple></w:p><w:p><w:bookmarkStart w:id="31" w:name="HeaderLater"/><w:r><w:t>Header target</w:t></w:r><w:bookmarkEnd w:id="31"/></w:p></w:hdr>"#,
),
(
"word/footnotes.xml",
r#"<w:footnotes xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:footnote w:type="separator" w:id="-1"><w:p><w:r><w:separator/></w:r></w:p></w:footnote><w:footnote w:id="1"><w:p><w:bookmarkStart w:id="32" w:name="FootEarlier"/><w:r><w:t>Foot target</w:t></w:r><w:bookmarkEnd w:id="32"/></w:p><w:p><w:fldSimple w:instr=" REF FootEarlier \p "><w:r><w:t>stale footnote position</w:t></w:r></w:fldSimple></w:p></w:footnote></w:footnotes>"#,
),
]))
.expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 2);
assert!(fields.iter().any(|field| {
field.kind == FieldKind::Ref
&& field.result == "stale header position"
&& field.computed_result.as_deref() == Some("below")
}));
assert!(fields.iter().any(|field| {
field.kind == FieldKind::Ref
&& field.result == "stale footnote position"
&& field.computed_result.as_deref() == Some("above")
}));
assert!(doc.header_text().contains("below"));
assert!(doc.footnote_text().contains("above"));
assert!(!doc.text().contains("stale header position"));
assert!(!doc.text().contains("stale footnote position"));
}
#[test]
fn docx_non_body_note_ref_fields_materialize_local_note_numbers() {
let doc = Document::open(&docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/><Override PartName="/word/header1.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.header+xml"/><Override PartName="/word/footnotes.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.footnotes+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/_rels/document.xml.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rIdHeader" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/header" Target="header1.xml"/><Relationship Id="rIdFootnotes" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/footnotes" Target="footnotes.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"><w:body><w:p><w:r><w:t>Body</w:t></w:r><w:r><w:footnoteReference w:id="1"/></w:r></w:p><w:sectPr><w:headerReference w:type="default" r:id="rIdHeader"/></w:sectPr></w:body></w:document>"#,
),
(
"word/header1.xml",
r#"<w:hdr xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:p><w:bookmarkStart w:id="41" w:name="HeaderNote"/><w:r><w:footnoteReference w:id="7"/></w:r><w:bookmarkEnd w:id="41"/></w:p><w:p><w:fldSimple w:instr=" NOTEREF HeaderNote "><w:r><w:t>stale header note ref</w:t></w:r></w:fldSimple></w:p></w:hdr>"#,
),
(
"word/footnotes.xml",
r#"<w:footnotes xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:footnote w:type="separator" w:id="-1"><w:p><w:r><w:separator/></w:r></w:p></w:footnote><w:footnote w:id="1"><w:p><w:bookmarkStart w:id="42" w:name="FootNoteMark"/><w:r><w:footnoteReference w:id="8"/></w:r><w:bookmarkEnd w:id="42"/></w:p><w:p><w:fldSimple w:instr=" NOTEREF FootNoteMark "><w:r><w:t>stale footnote note ref</w:t></w:r></w:fldSimple></w:p></w:footnote></w:footnotes>"#,
),
]))
.expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 2);
assert!(fields.iter().any(|field| {
field.kind == FieldKind::NoteRef
&& field.result == "stale header note ref"
&& field.computed_result.as_deref() == Some("1")
}));
assert!(fields.iter().any(|field| {
field.kind == FieldKind::NoteRef
&& field.result == "stale footnote note ref"
&& field.computed_result.as_deref() == Some("1")
}));
assert!(doc.header_text().contains("1"));
assert!(doc.footnote_text().contains("1"));
assert!(!doc.text().contains("stale header note ref"));
assert!(!doc.text().contains("stale footnote note ref"));
}
#[test]
fn docx_non_body_section_fields_materialize_local_section_numbers() {
let doc = Document::open(&docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/><Override PartName="/word/header1.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.header+xml"/><Override PartName="/word/footnotes.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.footnotes+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/_rels/document.xml.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rIdHeader" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/header" Target="header1.xml"/><Relationship Id="rIdFootnotes" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/footnotes" Target="footnotes.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"><w:body><w:p><w:r><w:t>Body</w:t></w:r><w:r><w:footnoteReference w:id="1"/></w:r></w:p><w:sectPr><w:headerReference w:type="default" r:id="rIdHeader"/></w:sectPr></w:body></w:document>"#,
),
(
"word/header1.xml",
r#"<w:hdr xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:p><w:pPr><w:sectPr><w:type w:val="nextPage"/></w:sectPr></w:pPr></w:p><w:p><w:fldSimple w:instr=" SECTION "><w:r><w:t>stale header section</w:t></w:r></w:fldSimple></w:p></w:hdr>"#,
),
(
"word/footnotes.xml",
r#"<w:footnotes xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:footnote w:type="separator" w:id="-1"><w:p><w:r><w:separator/></w:r></w:p></w:footnote><w:footnote w:id="1"><w:p><w:pPr><w:sectPr><w:type w:val="nextPage"/></w:sectPr></w:pPr></w:p><w:p><w:fldSimple w:instr=" SECTION "><w:r><w:t>stale footnote section</w:t></w:r></w:fldSimple></w:p></w:footnote></w:footnotes>"#,
),
]))
.expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 2);
assert!(fields.iter().any(|field| {
field.kind == FieldKind::DocumentStructure("SECTION".to_string())
&& field.result == "stale header section"
&& field.computed_result.as_deref() == Some("2")
}));
assert!(fields.iter().any(|field| {
field.kind == FieldKind::DocumentStructure("SECTION".to_string())
&& field.result == "stale footnote section"
&& field.computed_result.as_deref() == Some("2")
}));
assert!(doc.header_text().contains("2"));
assert!(doc.footnote_text().contains("2"));
assert!(!doc.text().contains("stale header section"));
assert!(!doc.text().contains("stale footnote section"));
}
#[test]
fn docx_unenforced_legacy_form_protection_materializes_values() {
let doc = Document::open(&docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/><Override PartName="/word/settings.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.settings+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/settings.xml",
r#"<w:settings xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:documentProtection w:edit="forms"/></w:settings>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:fldSimple w:instr=" FORMCHECKBOX "><w:ffData><w:checkBox><w:checked w:val="true"/></w:checkBox></w:ffData><w:r><w:t>cached unenforced checked</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
]))
.expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 1);
assert_eq!(
fields[0].kind,
FieldKind::FormField("FORMCHECKBOX".to_string())
);
assert_eq!(fields[0].computed_result.as_deref(), Some("\u{2612}"));
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
let main_text = doc.main_text();
assert!(main_text.contains('\u{2612}'));
assert!(!main_text.contains("cached unenforced checked"));
}
#[test]
fn docx_protected_legacy_form_diagnostics_split_valid_cached_from_malformed_syntax() {
let doc = Document::open(&docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/><Override PartName="/word/settings.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.settings+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/settings.xml",
r#"<w:settings xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:documentProtection w:edit="forms" w:enforcement="1"/></w:settings>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:fldSimple w:instr=" FORMCHECKBOX "><w:ffData><w:checkBox><w:checked w:val="true"/></w:checkBox></w:ffData><w:r><w:t>cached protected checked</w:t></w:r></w:fldSimple></w:p><w:p><w:fldSimple w:instr=" FORMTEXT "bad "><w:r><w:t>cached malformed form text</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
]))
.expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 2);
assert_eq!(
fields[0].kind,
FieldKind::FormField("FORMCHECKBOX".to_string())
);
assert_eq!(fields[0].computed_result, None);
assert_eq!(fields[1].kind, FieldKind::FormField("FORMTEXT".to_string()));
assert_eq!(fields[1].instruction, r#"FORMTEXT "bad "#);
assert_eq!(fields[1].computed_result, None);
let report = doc.report();
assert_eq!(
report.features.unsupported_field_kinds,
vec![
FieldKindCount {
kind: FieldKind::FormField("FORMCHECKBOX".to_string()),
count: 1,
},
FieldKindCount {
kind: FieldKind::FormField("FORMTEXT".to_string()),
count: 1,
},
]
);
assert_eq!(
report.features.unsupported_field_reasons,
vec![
FieldEvaluationReasonCount {
reason: FieldEvaluationReason::NoComputedResult,
count: 1,
},
FieldEvaluationReasonCount {
reason: FieldEvaluationReason::UnsupportedSwitch,
count: 1,
},
]
);
assert_eq!(
model_simple_field_reason_hints(&doc, |instruction| instruction.starts_with("FORM")),
vec![
(
"FORMCHECKBOX".to_string(),
Some(FieldUnsupportedReason::NoComputedResult),
),
(
r#"FORMTEXT "bad "#.to_string(),
Some(FieldUnsupportedReason::UnsupportedSwitch),
),
]
);
assert!(doc.main_text().contains("cached malformed form text"));
}
#[test]
fn docx_simple_field_result_preserves_cached_inline_markers() {
let doc = Document::open(&simple_cached_result_inline_marker_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 1);
assert_eq!(fields[0].kind, FieldKind::Unknown("CUSTOM".to_string()));
assert_eq!(fields[0].instruction, "CUSTOM value");
assert_eq!(fields[0].result, "Alpha\tBeta\nGamma-Hard\u{00ad}Soft");
assert_eq!(fields[0].computed_result, None);
assert!(
doc.main_text()
.contains("Alpha\tBeta\nGamma-Hard\u{00ad}Soft"),
"{:?}",
doc.main_text()
);
}
#[test]
fn docx_simple_field_result_uses_single_alternate_content_branch() {
let doc =
Document::open(&simple_cached_result_alternate_content_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 1);
assert_eq!(fields[0].kind, FieldKind::Unknown("CUSTOM".to_string()));
assert_eq!(fields[0].instruction, "CUSTOM value");
assert_eq!(fields[0].result, "Before Choice After");
assert_eq!(fields[0].computed_result, None);
let main_text = doc.main_text();
assert!(main_text.contains("Before Choice After"), "{main_text:?}");
assert!(!main_text.contains("Fallback"), "{main_text:?}");
}
#[test]
fn docx_simple_field_result_preserves_nested_simple_field_text() {
let doc =
Document::open(&simple_cached_result_nested_simple_field_docx()).expect("fixture opens");
let fields = doc.fields();
let field = fields
.iter()
.find(|field| field.instruction == "CUSTOM outer")
.expect("outer field is recorded");
assert_eq!(field.kind, FieldKind::Unknown("CUSTOM".to_string()));
assert_eq!(field.result, "Outer Inner Tail");
assert_eq!(field.computed_result, None);
}
#[test]
fn docx_complex_field_result_preserves_cached_inline_markers() {
let doc = Document::open(&complex_cached_result_inline_marker_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 2);
assert_eq!(fields[0].kind, FieldKind::Unknown("CUSTOM".to_string()));
assert_eq!(fields[0].instruction, "CUSTOM value");
assert_eq!(fields[0].result, "One\tTwo\nThree-Hard\u{00ad}Soft");
assert_eq!(fields[0].computed_result, None);
assert_eq!(fields[1].kind, FieldKind::Unknown("CUSTOM".to_string()));
assert_eq!(fields[1].instruction, "CUSTOM markersOnly");
assert_eq!(fields[1].result, "\t\n-\u{00ad}");
assert_eq!(fields[1].computed_result, None);
assert!(
doc.main_text().contains("One\tTwo\nThree-Hard\u{00ad}Soft")
&& doc.main_text().contains("\t\n-\u{00ad}"),
"{:?}",
doc.main_text()
);
}
#[test]
fn docx_complex_field_result_preserves_expanded_inline_markers() {
let doc = Document::open(&docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:r><w:fldChar w:fldCharType="begin"/></w:r><w:r><w:instrText> CUSTOM expanded </w:instrText></w:r><w:r><w:fldChar w:fldCharType="separate"/></w:r><w:r><w:t>One</w:t><w:tab></w:tab><w:t>Two</w:t><w:br></w:br><w:t>Three</w:t><w:noBreakHyphen></w:noBreakHyphen><w:t>Hard</w:t><w:softHyphen></w:softHyphen><w:t>Soft</w:t></w:r><w:r><w:fldChar w:fldCharType="end"/></w:r></w:p></w:body></w:document>"#,
),
]))
.expect("fixture opens");
let fields = doc.fields();
let field = fields
.iter()
.find(|field| field.instruction == "CUSTOM expanded")
.expect("expanded marker field is recorded");
let expected = "One\tTwo\nThree-Hard\u{00ad}Soft";
assert_eq!(field.kind, FieldKind::Unknown("CUSTOM".to_string()));
assert_eq!(field.result, expected);
assert_eq!(field.computed_result, None);
assert_eq!(doc.main_text(), expected);
}
#[test]
fn docx_complex_field_preserves_custom_xml_wrapped_result() {
let doc = Document::open(&docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:r><w:fldChar w:fldCharType="begin"/></w:r><w:r><w:instrText> CUSTOM outer </w:instrText></w:r><w:r><w:fldChar w:fldCharType="separate"/></w:r><w:customXml w:element="answer" w:uri="urn:rwml:test"><w:customXmlPr><w:attr w:name="kind" w:val="fixture"/></w:customXmlPr><w:r><w:t>stale custom xml</w:t></w:r></w:customXml><w:r><w:fldChar w:fldCharType="end"/></w:r></w:p></w:body></w:document>"#,
),
]))
.expect("fixture opens");
let fields = doc.fields();
let field = fields
.iter()
.find(|field| field.instruction == "CUSTOM outer")
.expect("outer field is recorded");
assert_eq!(field.kind, FieldKind::Unknown("CUSTOM".to_string()));
assert_eq!(field.result, "stale custom xml");
assert_eq!(field.computed_result, None);
assert_eq!(doc.main_text(), "stale custom xml");
assert_eq!(
model_simple_field_reason_hints(&doc, |instruction| instruction == "CUSTOM outer"),
vec![("CUSTOM outer".to_string(), None)]
);
}
#[test]
fn docx_computed_complex_field_replaces_marker_only_cached_result() {
let doc = Document::open(&docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:r><w:fldChar w:fldCharType="begin"/></w:r><w:r><w:instrText> QUOTE "Fresh" </w:instrText></w:r><w:r><w:fldChar w:fldCharType="separate"/></w:r><w:r><w:tab/><w:br/><w:noBreakHyphen/><w:softHyphen/></w:r><w:r><w:fldChar w:fldCharType="end"/></w:r></w:p></w:body></w:document>"#,
),
]))
.expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 1);
assert_eq!(fields[0].instruction, r#"QUOTE "Fresh""#);
assert_eq!(fields[0].result, "\t\n-\u{00ad}");
assert_eq!(fields[0].computed_result.as_deref(), Some("Fresh"));
assert_eq!(doc.main_text(), "Fresh");
}
#[test]
fn docx_computed_complex_field_replaces_run_alternate_content_field_result() {
let doc = Document::open(&docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"><w:body><w:p><w:r><w:fldChar w:fldCharType="begin"/></w:r><w:r><w:instrText> QUOTE "Outer" </w:instrText></w:r><w:r><w:fldChar w:fldCharType="separate"/></w:r><w:r><mc:AlternateContent><mc:Choice Requires="wps"><w:fldSimple w:instr=" QUOTE "Inner" "><w:r><w:t>stale inner</w:t></w:r></w:fldSimple></mc:Choice><mc:Fallback><w:r><w:t>Fallback inner</w:t></w:r></mc:Fallback></mc:AlternateContent></w:r><w:r><w:fldChar w:fldCharType="end"/></w:r></w:p></w:body></w:document>"#,
),
]))
.expect("fixture opens");
let fields = doc.fields();
assert!(fields.iter().any(|field| {
field.instruction == r#"QUOTE "Outer""# && field.computed_result.as_deref() == Some("Outer")
}));
assert_eq!(doc.main_text(), "Outer");
}
#[test]
fn docx_complex_field_preserves_run_alternate_content_hyperlink_result() {
let doc = Document::open(&docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/_rels/document.xml.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rIdLink" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink" Target="https://example.com" TargetMode="External"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"><w:body><w:p><w:r><w:fldChar w:fldCharType="begin"/></w:r><w:r><w:instrText> CUSTOM outer </w:instrText></w:r><w:r><w:fldChar w:fldCharType="separate"/></w:r><w:r><mc:AlternateContent><mc:Choice Requires="wps"><w:hyperlink r:id="rIdLink"><w:r><w:t>stale link</w:t></w:r></w:hyperlink></mc:Choice><mc:Fallback><w:r><w:t>fallback link</w:t></w:r></mc:Fallback></mc:AlternateContent></w:r><w:r><w:fldChar w:fldCharType="end"/></w:r></w:p></w:body></w:document>"#,
),
]))
.expect("fixture opens");
let fields = doc.fields();
let field = fields
.iter()
.find(|field| field.instruction == "CUSTOM outer")
.expect("outer field is recorded");
assert_eq!(field.kind, FieldKind::Unknown("CUSTOM".to_string()));
assert_eq!(field.result, "stale link");
assert_eq!(field.computed_result, None);
assert_eq!(doc.main_text(), "stale link");
assert_eq!(
model_simple_field_reason_hints(&doc, |instruction| instruction == "CUSTOM outer"),
vec![("CUSTOM outer".to_string(), None)]
);
}
#[test]
fn docx_complex_field_preserves_run_alternate_content_content_control_result() {
let doc = Document::open(&docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"><w:body><w:p><w:r><w:fldChar w:fldCharType="begin"/></w:r><w:r><w:instrText> CUSTOM outer </w:instrText></w:r><w:r><w:fldChar w:fldCharType="separate"/></w:r><w:r><mc:AlternateContent><mc:Choice Requires="wps"><w:sdt><w:sdtPr><w:tag w:val=" cached-result "/></w:sdtPr><w:sdtContent><w:r><w:t>stale control</w:t></w:r></w:sdtContent></w:sdt></mc:Choice><mc:Fallback><w:r><w:t>fallback control</w:t></w:r></mc:Fallback></mc:AlternateContent></w:r><w:r><w:fldChar w:fldCharType="end"/></w:r></w:p></w:body></w:document>"#,
),
]))
.expect("fixture opens");
let fields = doc.fields();
let field = fields
.iter()
.find(|field| field.instruction == "CUSTOM outer")
.expect("outer field is recorded");
assert_eq!(field.kind, FieldKind::Unknown("CUSTOM".to_string()));
assert_eq!(field.result, "stale control");
assert_eq!(field.computed_result, None);
assert_eq!(doc.main_text(), "stale control");
let [Block::Paragraph(paragraph)] = &doc.model().blocks[..] else {
panic!("expected one paragraph");
};
let [run] = ¶graph.runs[..] else {
panic!("expected one cached result run");
};
assert_eq!(
run.content_control
.as_ref()
.and_then(|control| control.tag.as_deref()),
Some("cached-result")
);
assert_eq!(
model_simple_field_reason_hints(&doc, |instruction| instruction == "CUSTOM outer"),
vec![("CUSTOM outer".to_string(), None)]
);
}
#[test]
fn docx_complex_field_preserves_run_alternate_content_nested_run_result() {
let doc = Document::open(&docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"><w:body><w:p><w:r><w:fldChar w:fldCharType="begin"/></w:r><w:r><w:instrText> CUSTOM outer </w:instrText></w:r><w:r><w:fldChar w:fldCharType="separate"/></w:r><w:r><mc:AlternateContent><mc:Choice Requires="wps"><w:r><w:t>stale nested run</w:t></w:r></mc:Choice><mc:Fallback><w:r><w:t>fallback nested run</w:t></w:r></mc:Fallback></mc:AlternateContent></w:r><w:r><w:fldChar w:fldCharType="end"/></w:r></w:p></w:body></w:document>"#,
),
]))
.expect("fixture opens");
let fields = doc.fields();
let field = fields
.iter()
.find(|field| field.instruction == "CUSTOM outer")
.expect("outer field is recorded");
assert_eq!(field.kind, FieldKind::Unknown("CUSTOM".to_string()));
assert_eq!(field.result, "stale nested run");
assert_eq!(field.computed_result, None);
assert_eq!(doc.main_text(), "stale nested run");
assert_eq!(
model_simple_field_reason_hints(&doc, |instruction| instruction == "CUSTOM outer"),
vec![("CUSTOM outer".to_string(), None)]
);
}
#[test]
fn docx_complex_field_preserves_run_alternate_content_inserted_result() {
let doc = Document::open(&docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"><w:body><w:p><w:r><w:fldChar w:fldCharType="begin"/></w:r><w:r><w:instrText> CUSTOM outer </w:instrText></w:r><w:r><w:fldChar w:fldCharType="separate"/></w:r><w:r><mc:AlternateContent><mc:Choice Requires="wps"><w:ins w:id="7" w:author="Editor"><w:r><w:t>stale inserted run</w:t></w:r></w:ins></mc:Choice><mc:Fallback><w:r><w:t>fallback inserted run</w:t></w:r></mc:Fallback></mc:AlternateContent></w:r><w:r><w:fldChar w:fldCharType="end"/></w:r></w:p></w:body></w:document>"#,
),
]))
.expect("fixture opens");
let fields = doc.fields();
let field = fields
.iter()
.find(|field| field.instruction == "CUSTOM outer")
.expect("outer field is recorded");
assert_eq!(field.kind, FieldKind::Unknown("CUSTOM".to_string()));
assert_eq!(field.result, "stale inserted run");
assert_eq!(field.computed_result, None);
assert_eq!(doc.main_text(), "stale inserted run");
assert_eq!(
model_simple_field_reason_hints(&doc, |instruction| instruction == "CUSTOM outer"),
vec![("CUSTOM outer".to_string(), None)]
);
}
#[test]
fn docx_computed_complex_field_replaces_paragraph_simple_field_result() {
let doc = Document::open(&docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:r><w:fldChar w:fldCharType="begin"/></w:r><w:r><w:instrText> QUOTE "Outer" </w:instrText></w:r><w:r><w:fldChar w:fldCharType="separate"/></w:r><w:fldSimple w:instr=" QUOTE "Inner" "><w:r><w:t>stale inner</w:t></w:r></w:fldSimple><w:r><w:fldChar w:fldCharType="end"/></w:r></w:p></w:body></w:document>"#,
),
]))
.expect("fixture opens");
let fields = doc.fields();
assert!(fields.iter().any(|field| {
field.instruction == r#"QUOTE "Outer""# && field.computed_result.as_deref() == Some("Outer")
}));
assert_eq!(doc.main_text(), "Outer");
}
#[test]
fn docx_computed_complex_field_replaces_paragraph_hyperlink_result() {
let doc = Document::open(&docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/_rels/document.xml.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rIdLink" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink" Target="https://example.com" TargetMode="External"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"><w:body><w:p><w:r><w:fldChar w:fldCharType="begin"/></w:r><w:r><w:instrText> QUOTE "Outer" </w:instrText></w:r><w:r><w:fldChar w:fldCharType="separate"/></w:r><w:hyperlink r:id="rIdLink"><w:r><w:t>stale link</w:t></w:r></w:hyperlink><w:r><w:fldChar w:fldCharType="end"/></w:r></w:p></w:body></w:document>"#,
),
]))
.expect("fixture opens");
let fields = doc.fields();
assert!(fields.iter().any(|field| {
field.instruction == r#"QUOTE "Outer""# && field.computed_result.as_deref() == Some("Outer")
}));
assert_eq!(doc.main_text(), "Outer");
let [Block::Paragraph(paragraph)] = &doc.model().blocks[..] else {
panic!("expected one paragraph");
};
let [run] = ¶graph.runs[..] else {
panic!("expected one computed run");
};
assert_eq!(run.text, "Outer");
assert!(matches!(run.field, FieldRole::Other));
}
#[test]
fn docx_field_results_preserve_supported_symbols() {
let doc = Document::open(&cached_field_result_symbol_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 2);
assert_eq!(fields[0].kind, FieldKind::Unknown("CUSTOM".to_string()));
assert_eq!(fields[0].instruction, "CUSTOM simple");
assert_eq!(fields[0].result, "Simple \u{2022} result");
assert_eq!(fields[0].computed_result, None);
assert_eq!(fields[1].kind, FieldKind::Unknown("CUSTOM".to_string()));
assert_eq!(fields[1].instruction, "CUSTOM complex");
assert_eq!(fields[1].result, "Complex \u{2022} result");
assert_eq!(fields[1].computed_result, None);
assert!(
doc.main_text().contains("Simple \u{2022} result")
&& doc.main_text().contains("Complex \u{2022} result"),
"{:?}",
doc.main_text()
);
}
#[test]
fn docx_complex_field_marks_all_split_cached_result_runs() {
let doc = Document::open(&complex_split_cached_result_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 1);
assert_eq!(fields[0].kind, FieldKind::Unknown("CUSTOM".to_string()));
assert_eq!(fields[0].instruction, "CUSTOM split");
assert_eq!(fields[0].result, "Alpha Beta");
assert_eq!(fields[0].computed_result, None);
let model = doc.model();
let Block::Paragraph(paragraph) = &model.blocks[0] else {
panic!("expected paragraph model");
};
let split_result_runs: Vec<_> = paragraph
.runs
.iter()
.filter(|run| run.text == "Alpha " || run.text == "Beta")
.collect();
assert_eq!(split_result_runs.len(), 2);
assert!(split_result_runs.iter().all(|run| matches!(
&run.field,
rwml::FieldRole::Simple { instruction } if instruction == "CUSTOM split"
)));
}
#[test]
fn docx_nested_complex_fields_preserve_outer_cached_result() {
let doc = Document::open(&nested_complex_field_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 2);
assert_eq!(fields[0].kind, FieldKind::MergeField);
assert_eq!(fields[0].instruction, "MERGEFIELD InnerName");
assert_eq!(fields[0].result, "Inner Value");
assert_eq!(fields[1].kind, FieldKind::Unknown("CUSTOM".to_string()));
assert_eq!(fields[1].instruction, "CUSTOM outer");
assert_eq!(fields[1].result, "Before Inner Value After");
}
#[test]
fn docx_nested_complex_with_nested_simple_field_preserves_outer_cached_result() {
let doc = Document::open(&nested_complex_with_simple_field_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 2);
assert_eq!(fields[0].kind, FieldKind::MergeField);
assert_eq!(fields[0].instruction, "MERGEFIELD InnerName");
assert_eq!(fields[0].result, "Inner Value");
assert_eq!(fields[1].kind, FieldKind::Unknown("CUSTOM".to_string()));
assert_eq!(fields[1].instruction, "CUSTOM outer");
assert_eq!(fields[1].result, "Before Inner Value After");
}
#[test]
fn docx_toc_field_computes_unambiguous_heading_outline_range() {
let doc = Document::open(&toc_heading_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 1);
assert_eq!(fields[0].kind, FieldKind::Toc);
assert_eq!(fields[0].instruction, "TOC \\o \"1-2\"");
assert_eq!(fields[0].result, "stale toc");
assert_eq!(
fields[0].computed_result.as_deref(),
Some("Executive Summary\n Risks")
);
let main_text = doc.main_text();
assert!(
!main_text.contains("stale toc"),
"resolved TOC fields should display computed heading text in the read model: {main_text:?}"
);
assert_eq!(main_text.matches("Executive Summary").count(), 2);
assert_eq!(main_text.matches("Risks").count(), 2);
assert_eq!(main_text.matches("Excluded Detail").count(), 1);
}
#[test]
fn docx_toc_heading_source_text_uses_computed_simple_field_results() {
let doc = Document::open(&toc_heading_simple_field_source_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 2);
assert_eq!(fields[0].kind, FieldKind::Dynamic("QUOTE".to_string()));
assert_eq!(fields[0].instruction, r#"QUOTE "Risk""#);
assert_eq!(fields[0].result, "stale heading quote");
assert_eq!(fields[0].computed_result.as_deref(), Some("Risk"));
assert_eq!(fields[1].kind, FieldKind::Toc);
assert_eq!(fields[1].instruction, "TOC \\o \"1-1\"");
assert_eq!(fields[1].result, "stale simple-field heading toc");
assert_eq!(
fields[1].computed_result.as_deref(),
Some("Executive Risk Review")
);
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
let main_text = doc.main_text();
assert!(
main_text.contains("Executive Risk Review")
&& !main_text.contains("stale heading quote")
&& !main_text.contains("stale simple-field heading toc"),
"TOC source text should use computed simple-field heading text: {main_text:?}"
);
}
#[test]
fn docx_toc_heading_source_text_uses_computed_legacy_form_results() {
let doc = Document::open(&toc_heading_legacy_form_source_docx()).expect("fixture opens");
let fields = doc.fields();
let form_fields = fields
.iter()
.filter(|field| field.kind == FieldKind::FormField("FORMDROPDOWN".to_string()))
.collect::<Vec<_>>();
assert_eq!(form_fields.len(), 2);
assert_eq!(form_fields[0].result, "stale prior form");
assert_eq!(form_fields[0].computed_result.as_deref(), Some("99"));
assert_eq!(form_fields[1].result, "stale source form");
assert_eq!(form_fields[1].computed_result.as_deref(), Some("7"));
let toc_fields = fields
.iter()
.filter(|field| field.kind == FieldKind::Toc)
.collect::<Vec<_>>();
assert_eq!(toc_fields.len(), 2);
assert_eq!(toc_fields[0].instruction, "TOC \\o \"1-1\"");
assert_eq!(
toc_fields[0].computed_result.as_deref(),
Some("Choice 7 ready")
);
assert_eq!(toc_fields[1].instruction, "TOC \\o \"1-1\" \\* Upper");
assert_eq!(
toc_fields[1].computed_result.as_deref(),
Some("CHOICE 7 READY")
);
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
let main_text = doc.main_text();
assert!(
main_text.contains("Choice 7 ready")
&& main_text.contains("CHOICE 7 READY")
&& !main_text.contains("stale source form")
&& !main_text.contains("stale legacy form toc source")
&& !main_text.contains("stale upper legacy form toc source"),
"TOC source text should use computed legacy form heading text: {main_text:?}"
);
}
#[test]
fn docx_toc_heading_source_text_uses_computed_numbering_field_results() {
let doc = Document::open(&toc_heading_numbering_field_source_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 2);
assert_eq!(fields[0].kind, FieldKind::Numbering("AUTONUM".to_string()));
assert_eq!(fields[0].instruction, "AUTONUM");
assert_eq!(fields[0].result, "99");
assert_eq!(fields[0].computed_result.as_deref(), Some("1"));
assert_eq!(fields[1].kind, FieldKind::Toc);
assert_eq!(fields[1].instruction, "TOC \\o \"1-1\"");
assert_eq!(fields[1].result, "stale numbering-source toc");
assert_eq!(
fields[1].computed_result.as_deref(),
Some("Clause 1 Overview")
);
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
let main_text = doc.main_text();
assert!(
main_text.contains("Clause 1 Overview")
&& !main_text.contains("Clause 99 Overview")
&& !main_text.contains("stale numbering-source toc"),
"TOC source text should use computed AUTONUM heading text: {main_text:?}"
);
}
#[test]
fn docx_toc_heading_source_text_uses_computed_listnum_field_results() {
let doc = Document::open(&toc_heading_listnum_field_source_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 2);
assert_eq!(fields[0].kind, FieldKind::Numbering("LISTNUM".to_string()));
assert_eq!(fields[0].instruction, "LISTNUM NumberDefault");
assert_eq!(fields[0].result, "99");
assert_eq!(fields[0].computed_result.as_deref(), Some("1"));
assert_eq!(fields[1].kind, FieldKind::Toc);
assert_eq!(fields[1].instruction, "TOC \\o \"1-1\"");
assert_eq!(fields[1].result, "stale listnum-source toc");
assert_eq!(
fields[1].computed_result.as_deref(),
Some("Clause 1 Overview")
);
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
let main_text = doc.main_text();
assert!(
main_text.contains("Clause 1 Overview")
&& !main_text.contains("Clause 99 Overview")
&& !main_text.contains("stale listnum-source toc"),
"TOC source text should use computed LISTNUM heading text: {main_text:?}"
);
}
#[test]
fn docx_toc_heading_source_text_uses_computed_formula_field_results() {
let doc = Document::open(&toc_heading_formula_field_source_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 2);
assert_eq!(fields[0].kind, FieldKind::Dynamic("=".to_string()));
assert_eq!(fields[0].instruction, "= 6 * 7");
assert_eq!(fields[0].result, "99");
assert_eq!(fields[0].computed_result.as_deref(), Some("42"));
assert_eq!(fields[1].kind, FieldKind::Toc);
assert_eq!(fields[1].instruction, "TOC \\o \"1-1\"");
assert_eq!(fields[1].result, "stale formula-source toc");
assert_eq!(fields[1].computed_result.as_deref(), Some("Total 42 Due"));
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
let main_text = doc.main_text();
assert!(
main_text.contains("Total 42 Due")
&& !main_text.contains("Total 99 Due")
&& !main_text.contains("stale formula-source toc"),
"TOC source text should use computed formula heading text: {main_text:?}"
);
}
#[test]
fn docx_toc_heading_source_text_uses_computed_complex_field_results() {
let doc = Document::open(&toc_heading_complex_field_source_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 2);
assert_eq!(fields[0].kind, FieldKind::Dynamic("QUOTE".to_string()));
assert_eq!(fields[0].instruction, r#"QUOTE "Risk""#);
assert_eq!(fields[0].result, "stale heading quote");
assert_eq!(fields[0].computed_result.as_deref(), Some("Risk"));
assert_eq!(fields[1].kind, FieldKind::Toc);
assert_eq!(fields[1].instruction, "TOC \\o \"1-1\"");
assert_eq!(fields[1].result, "stale complex-field heading toc");
assert_eq!(
fields[1].computed_result.as_deref(),
Some("Executive Risk Review")
);
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
let main_text = doc.main_text();
assert!(
main_text.contains("Executive Risk Review")
&& !main_text.contains("stale heading quote")
&& !main_text.contains("stale complex-field heading toc"),
"TOC source text should use computed complex-field heading text: {main_text:?}"
);
}
#[test]
fn docx_toc_heading_source_text_uses_computed_set_field_results() {
let doc = Document::open(&toc_heading_set_field_source_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 2);
assert_eq!(fields[0].kind, FieldKind::Dynamic("SET".to_string()));
assert_eq!(fields[0].instruction, r#"SET Marker "Ready""#);
assert_eq!(fields[0].result, "stale heading set");
assert_eq!(fields[0].computed_result.as_deref(), Some(""));
assert_eq!(fields[1].kind, FieldKind::Toc);
assert_eq!(fields[1].instruction, "TOC \\o \"1-1\"");
assert_eq!(fields[1].result, "stale set-source toc");
assert_eq!(
fields[1].computed_result.as_deref(),
Some("Executive Review")
);
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
let main_text = doc.main_text();
assert!(
main_text.contains("Executive")
&& main_text.contains("Review")
&& !main_text.contains("stale heading set")
&& !main_text.contains("stale set-source toc"),
"TOC source text should drop the SET field's cached result: {main_text:?}"
);
}
#[test]
fn docx_toc_heading_source_text_uses_computed_ref_field_results() {
let doc = Document::open(&toc_heading_ref_field_source_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 2);
assert_eq!(fields[0].kind, FieldKind::Ref);
assert_eq!(fields[0].instruction, "REF ChapTitle");
assert_eq!(fields[0].result, "stale ref");
assert_eq!(fields[0].computed_result.as_deref(), Some("Live Chapter"));
assert_eq!(fields[1].kind, FieldKind::Toc);
assert_eq!(fields[1].instruction, "TOC \\o \"1-1\"");
assert_eq!(fields[1].result, "stale toc");
assert_eq!(
fields[1].computed_result.as_deref(),
Some("Section Live Chapter")
);
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
let main_text = doc.main_text();
assert!(
main_text.contains("Section Live Chapter") && !main_text.contains("stale ref"),
"TOC source text should use the computed REF bookmark text: {main_text:?}"
);
}
#[test]
fn docx_toc_heading_source_text_uses_computed_note_ref_field_results() {
let doc = Document::open(&toc_heading_note_ref_field_source_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 3);
assert_eq!(fields[0].kind, FieldKind::NoteRef);
assert_eq!(fields[0].instruction, "NOTEREF FootOne");
assert_eq!(fields[0].result, "stale heading note");
assert_eq!(fields[0].computed_result.as_deref(), Some("1"));
assert_eq!(fields[1].kind, FieldKind::NoteRef);
assert_eq!(fields[1].instruction, "NOTEREF FootOne \\p");
assert_eq!(fields[1].result, "stale heading relative note");
assert_eq!(fields[1].computed_result.as_deref(), Some("above"));
assert_eq!(fields[2].kind, FieldKind::Toc);
assert_eq!(fields[2].instruction, "TOC \\o \"1-1\"");
assert_eq!(fields[2].result, "stale note-ref toc");
assert_eq!(
fields[2].computed_result.as_deref(),
Some("Section 1 / above Review")
);
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
let main_text = doc.main_text();
assert!(
main_text.contains("Section 1 / above Review")
&& !main_text.contains("stale heading note")
&& !main_text.contains("stale heading relative note")
&& !main_text.contains("stale note-ref toc"),
"TOC source text should use the computed NOTEREF note number: {main_text:?}"
);
}
#[test]
fn docx_toc_heading_source_text_uses_computed_ref_note_mark_field_results() {
let doc =
Document::open(&toc_heading_ref_note_mark_field_source_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 2);
assert_eq!(fields[0].kind, FieldKind::Ref);
assert_eq!(fields[0].instruction, "REF FootOne \\f");
assert_eq!(fields[0].result, "stale heading ref note");
assert_eq!(fields[0].computed_result.as_deref(), Some("2"));
assert_eq!(fields[1].kind, FieldKind::Toc);
assert_eq!(fields[1].instruction, "TOC \\o \"1-1\"");
assert_eq!(fields[1].result, "stale ref-note toc");
assert_eq!(
fields[1].computed_result.as_deref(),
Some("Section 2 Review")
);
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
let main_text = doc.main_text();
assert!(
main_text.contains("Section 2 Review")
&& !main_text.contains("stale heading ref note")
&& !main_text.contains("stale ref-note toc"),
"TOC source text should use the computed REF note-reference mark: {main_text:?}"
);
}
#[test]
fn docx_toc_heading_source_ref_cursor_counts_plain_refs_before_ref_note_marks() {
let doc =
Document::open(&toc_heading_mixed_ref_note_mark_source_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 3);
assert_eq!(fields[0].kind, FieldKind::Ref);
assert_eq!(fields[0].instruction, "REF ChapTitle");
assert_eq!(fields[0].computed_result.as_deref(), Some("Live Chapter"));
assert_eq!(fields[1].kind, FieldKind::Ref);
assert_eq!(fields[1].instruction, "REF FootOne \\f");
assert_eq!(fields[1].computed_result.as_deref(), Some("3"));
assert_eq!(fields[2].kind, FieldKind::Toc);
assert_eq!(fields[2].instruction, "TOC \\o \"1-1\"");
assert_eq!(fields[2].result, "stale mixed-ref toc");
assert_eq!(
fields[2].computed_result.as_deref(),
Some("Section Live Chapter 3 Review")
);
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
let main_text = doc.main_text();
assert!(
main_text.contains("Section Live Chapter 3 Review")
&& !main_text.contains("stale heading ref")
&& !main_text.contains("stale heading ref note")
&& !main_text.contains("stale mixed-ref toc"),
"TOC source text should advance the REF cursor for plain REF source fields: {main_text:?}"
);
}
#[test]
fn docx_toc_heading_source_text_uses_computed_document_info_results() {
let doc =
Document::open(&toc_heading_document_info_field_source_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 2);
assert_eq!(fields[0].kind, FieldKind::DocumentInfo("TITLE".to_string()));
assert_eq!(fields[0].instruction, "TITLE");
assert_eq!(fields[0].result, "stale toc title");
assert_eq!(fields[0].computed_result.as_deref(), Some("Quarter Plan"));
assert_eq!(fields[1].kind, FieldKind::Toc);
assert_eq!(fields[1].instruction, "TOC \\o \"1-1\"");
assert_eq!(fields[1].result, "stale document-info toc source");
assert_eq!(
fields[1].computed_result.as_deref(),
Some("Topic Quarter Plan Review")
);
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
let main_text = doc.main_text();
assert!(
main_text.contains("Topic Quarter Plan Review")
&& !main_text.contains("stale toc title")
&& !main_text.contains("stale document-info toc source"),
"TOC source text should use computed document-info field output: {main_text:?}"
);
}
#[test]
fn docx_toc_heading_source_text_uses_computed_section_field_results() {
let doc = Document::open(&toc_heading_section_field_source_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 2);
assert_eq!(
fields[0].kind,
FieldKind::DocumentStructure("SECTION".to_string())
);
assert_eq!(fields[0].instruction, "SECTION");
assert_eq!(fields[0].result, "99");
assert_eq!(fields[0].computed_result.as_deref(), Some("1"));
assert_eq!(fields[1].kind, FieldKind::Toc);
assert_eq!(fields[1].instruction, "TOC \\o \"1-1\"");
assert_eq!(fields[1].result, "stale section toc source");
assert_eq!(
fields[1].computed_result.as_deref(),
Some("Section 1 Review")
);
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
let main_text = doc.main_text();
assert!(
main_text.contains("Section 1 Review")
&& !main_text.contains("Section 99 Review")
&& !main_text.contains("stale section toc source"),
"TOC source text should use computed SECTION field output: {main_text:?}"
);
}
#[test]
fn docx_toc_heading_source_text_keeps_known_field_names_cached() {
let doc = Document::open(&toc_heading_known_field_name_bookmark_source_docx())
.expect("fixture opens");
let fields = doc.fields();
let source = fields
.iter()
.find(|field| field.instruction == "PAGEREF")
.expect("known source field is recorded");
assert_eq!(source.kind, FieldKind::PageRef);
assert_eq!(source.result, "known field source");
let toc = fields
.iter()
.find(|field| field.instruction == "TOC \\o \"1-1\"")
.expect("TOC field is recorded");
assert_eq!(
toc.computed_result.as_deref(),
Some("Heading known field source ready")
);
let main_text = doc.main_text();
assert!(
main_text.contains("Heading known field source ready")
&& !main_text.contains("stale known field source toc"),
"TOC source text should keep known field cached text instead of bookmark text: {main_text:?}"
);
}
#[test]
fn docx_toc_heading_source_text_resolves_bookmark_comparison_operands() {
let doc = Document::open(&toc_heading_bookmark_comparison_field_source_docx())
.expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 5);
assert_eq!(fields[0].kind, FieldKind::Dynamic("IF".to_string()));
assert_eq!(
fields[0].instruction,
r#"IF InvoiceTier = "Gold" "ship" "hold""#
);
assert_eq!(fields[0].result, "stale source if");
assert_eq!(fields[0].computed_result.as_deref(), Some("ship"));
assert_eq!(fields[1].kind, FieldKind::Dynamic("COMPARE".to_string()));
assert_eq!(fields[1].instruction, "COMPARE InvoiceTotal >= 40");
assert_eq!(fields[1].result, "stale source compare");
assert_eq!(fields[1].computed_result.as_deref(), Some("1"));
assert_eq!(fields[2].kind, FieldKind::Dynamic("NEXTIF".to_string()));
assert_eq!(fields[2].instruction, r#"NEXTIF InvoiceTier = "Gold""#);
assert_eq!(fields[2].result, "stale source nextif");
assert_eq!(fields[2].computed_result.as_deref(), Some(""));
assert_eq!(fields[3].kind, FieldKind::Dynamic("SKIPIF".to_string()));
assert_eq!(fields[3].instruction, "SKIPIF InvoiceTotal < 40");
assert_eq!(fields[3].result, "stale source skipif");
assert_eq!(fields[3].computed_result.as_deref(), Some(""));
assert_eq!(fields[4].kind, FieldKind::Toc);
assert_eq!(fields[4].instruction, "TOC \\o \"1-1\"");
assert_eq!(fields[4].result, "stale bookmark-comparison-source toc");
assert_eq!(
fields[4].computed_result.as_deref(),
Some("Status ship 1 ready")
);
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
let main_text = doc.main_text();
assert!(
main_text.contains("Status ship 1 ready")
&& !main_text.contains("stale source if")
&& !main_text.contains("stale source compare")
&& !main_text.contains("stale source nextif")
&& !main_text.contains("stale source skipif")
&& !main_text.contains("stale bookmark-comparison-source toc"),
"TOC source text should use document-bookmark-backed comparison fields: {main_text:?}"
);
}
#[test]
fn docx_toc_heading_source_text_resolves_prior_set_field_results() {
let doc = Document::open(&toc_heading_set_ref_field_source_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 3);
assert_eq!(fields[0].kind, FieldKind::Dynamic("SET".to_string()));
assert_eq!(fields[0].instruction, r#"SET Marker "Ready""#);
assert_eq!(fields[0].result, "stale set");
assert_eq!(fields[0].computed_result.as_deref(), Some(""));
assert_eq!(fields[1].kind, FieldKind::Ref);
assert_eq!(fields[1].instruction, "REF Marker");
assert_eq!(fields[1].result, "stale ref");
assert_eq!(fields[1].computed_result.as_deref(), Some("Ready"));
assert_eq!(fields[2].kind, FieldKind::Toc);
assert_eq!(fields[2].instruction, "TOC \\o \"1-1\"");
assert_eq!(fields[2].result, "stale set-ref-source toc");
assert_eq!(fields[2].computed_result.as_deref(), Some("Status Ready"));
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
let main_text = doc.main_text();
assert!(
main_text.contains("Status Ready")
&& !main_text.contains("Status stale ref")
&& !main_text.contains("stale set-ref-source toc"),
"TOC source text should resolve source-order SET-backed REF text: {main_text:?}"
);
}
#[test]
fn docx_toc_heading_source_text_resolves_prior_paragraph_set_field_results() {
let doc =
Document::open(&toc_heading_prior_set_ref_field_source_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 3);
assert_eq!(fields[0].kind, FieldKind::Dynamic("SET".to_string()));
assert_eq!(fields[0].instruction, r#"SET Marker "Ready""#);
assert_eq!(fields[0].result, "stale prior set");
assert_eq!(fields[0].computed_result.as_deref(), Some(""));
assert_eq!(fields[1].kind, FieldKind::Ref);
assert_eq!(fields[1].instruction, "REF Marker");
assert_eq!(fields[1].result, "stale ref");
assert_eq!(fields[1].computed_result.as_deref(), Some("Ready"));
assert_eq!(fields[2].kind, FieldKind::Toc);
assert_eq!(fields[2].instruction, "TOC \\o \"1-1\"");
assert_eq!(fields[2].result, "stale prior-set-ref-source toc");
assert_eq!(fields[2].computed_result.as_deref(), Some("Status Ready"));
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
let main_text = doc.main_text();
assert!(
main_text.contains("Status Ready")
&& !main_text.contains("Status stale ref")
&& !main_text.contains("stale prior set")
&& !main_text.contains("stale prior-set-ref-source toc"),
"TOC source text should resolve prior-paragraph SET-backed REF text: {main_text:?}"
);
}
#[test]
fn docx_toc_ignores_old_paragraph_property_revisions() {
let doc = Document::open(&toc_property_revision_heading_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 1);
assert_eq!(fields[0].kind, FieldKind::Toc);
assert_eq!(fields[0].instruction, "TOC \\o \"1-1\"");
assert_eq!(fields[0].result, "stale current toc");
assert_eq!(
fields[0].computed_result.as_deref(),
Some("Current Heading")
);
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
let main_text = doc.main_text();
assert!(main_text.contains("Former heading only"));
assert!(main_text.contains("Current Heading"));
assert!(!main_text.contains("stale current toc"));
}
#[test]
fn docx_complex_toc_field_computes_heading_outline_range() {
let doc = Document::open(&complex_toc_heading_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 1);
assert_eq!(fields[0].kind, FieldKind::Toc);
assert_eq!(fields[0].instruction, "TOC \\o \"1-2\" \\* Upper");
assert_eq!(fields[0].result, "stale complex toc");
assert_eq!(
fields[0].computed_result.as_deref(),
Some("EXECUTIVE SUMMARY\n RISKS")
);
let main_text = doc.main_text();
assert!(
!main_text.contains("stale complex toc"),
"resolved complex TOC fields should display computed heading text: {main_text:?}"
);
assert_eq!(main_text.matches("EXECUTIVE SUMMARY").count(), 1);
assert_eq!(main_text.matches("RISKS").count(), 1);
}
#[test]
fn docx_toc_field_normalizes_inline_tabs_and_breaks_in_heading_text() {
let doc = Document::open(&toc_heading_inline_break_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 1);
assert_eq!(fields[0].kind, FieldKind::Toc);
assert_eq!(fields[0].instruction, "TOC \\o \"1-1\"");
assert_eq!(fields[0].result, "stale inline toc");
assert_eq!(
fields[0].computed_result.as_deref(),
Some("Executive Summary Detail-Follow-up")
);
let main_text = doc.main_text();
assert!(
!main_text.contains("stale inline toc"),
"resolved TOC fields should display computed heading text with normalized inline markers: {main_text:?}"
);
assert!(
main_text.contains("Executive Summary Detail-Follow-up"),
"{main_text:?}"
);
}
#[test]
fn docx_toc_field_ignores_hidden_result_markers_in_heading_text() {
let doc = Document::open(&toc_heading_hidden_result_markers_docx()).expect("fixture opens");
let fields = doc.fields();
let field = fields
.iter()
.find(|field| field.result == "stale outer toc")
.expect("outer TOC field is recorded");
assert_eq!(field.kind, FieldKind::Toc);
assert_eq!(field.instruction, "TOC \\o \"1-1\"");
assert_eq!(field.computed_result.as_deref(), Some("Executive 1"));
let main_text = doc.main_text();
assert!(
main_text.contains("Executive 1"),
"resolved TOC should retain the visible heading text: {main_text:?}"
);
assert!(
!main_text.contains("stale hidden seq result") && !main_text.contains("stale outer toc"),
"resolved TOC should not display hidden cached result text: {main_text:?}"
);
}
#[test]
fn docx_toc_field_preserves_supported_symbols_in_heading_text() {
let doc = Document::open(&toc_heading_symbol_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 1);
assert_eq!(fields[0].kind, FieldKind::Toc);
assert_eq!(fields[0].instruction, "TOC \\o \"1-1\"");
assert_eq!(fields[0].result, "stale symbol toc");
assert_eq!(fields[0].computed_result.as_deref(), Some("Risk • Control"));
let main_text = doc.main_text();
assert!(
main_text.contains("Risk • Control") && !main_text.contains("stale symbol toc"),
"resolved TOC fields should preserve supported heading symbols: {main_text:?}"
);
}
#[test]
fn docx_toc_source_text_preserves_non_empty_supported_symbols() {
let doc = Document::open(&toc_non_empty_symbol_source_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 4);
assert_eq!(fields[0].kind, FieldKind::Sequence);
assert_eq!(fields[0].instruction, "SEQ Figure");
assert_eq!(fields[0].computed_result.as_deref(), Some("1"));
let heading_toc = fields
.iter()
.find(|field| field.instruction == "TOC \\o \"1-1\"")
.expect("heading TOC field is parsed");
assert_eq!(
heading_toc.computed_result.as_deref(),
Some("Risk • Control")
);
let caption_toc = fields
.iter()
.find(|field| field.instruction == "TOC \\c Figure")
.expect("caption TOC field is parsed");
assert_eq!(
caption_toc.computed_result.as_deref(),
Some("Figure 1: Risk • Control")
);
let caption_text_toc = fields
.iter()
.find(|field| field.instruction == "TOC \\a Figure")
.expect("caption-text TOC field is parsed");
assert_eq!(
caption_text_toc.computed_result.as_deref(),
Some("Risk • Control")
);
let main_text = doc.main_text();
assert!(
!main_text.contains("stale non-empty symbol heading toc")
&& !main_text.contains("stale non-empty symbol caption toc")
&& !main_text.contains("stale non-empty symbol caption text toc"),
"resolved TOC fields should replace stale cached text: {main_text:?}"
);
assert!(
main_text.contains("Figure 1: Risk • Control"),
"resolved TOC caption text should preserve non-empty supported symbols: {main_text:?}"
);
}
#[test]
fn docx_bare_toc_field_defaults_to_heading_levels_one_through_three() {
let doc = Document::open(&bare_toc_heading_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 1);
assert_eq!(fields[0].kind, FieldKind::Toc);
assert_eq!(fields[0].instruction, "TOC");
assert_eq!(fields[0].result, "stale bare toc");
assert_eq!(
fields[0].computed_result.as_deref(),
Some("Executive Summary\n Risks\n Mitigation")
);
let main_text = doc.main_text();
assert!(
!main_text.contains("stale bare toc"),
"bare TOC fields should display computed heading text in the read model: {main_text:?}"
);
assert_eq!(main_text.matches("Executive Summary").count(), 2);
assert_eq!(main_text.matches("Risks").count(), 2);
assert_eq!(main_text.matches("Mitigation").count(), 2);
assert_eq!(main_text.matches("Excluded Detail").count(), 1);
}
#[test]
fn docx_default_toc_with_neutral_switches_uses_default_heading_levels() {
let doc = Document::open(&default_neutral_toc_heading_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 6);
assert_eq!(fields[0].kind, FieldKind::Toc);
assert_eq!(fields[0].instruction, "TOC \\h \\z");
assert_eq!(fields[0].result, "stale neutral default toc");
assert_eq!(
fields[0].computed_result.as_deref(),
Some("Executive Summary\n Risks\n Mitigation")
);
assert_eq!(fields[1].kind, FieldKind::Toc);
assert_eq!(fields[1].instruction, "TOC \\n \"1-3\"");
assert_eq!(fields[1].result, "stale no-page default toc");
assert_eq!(
fields[1].computed_result.as_deref(),
Some("Executive Summary\n Risks\n Mitigation")
);
assert_eq!(fields[2].kind, FieldKind::Toc);
assert_eq!(fields[2].instruction, "TOC \\p \"-\"");
assert_eq!(fields[2].result, "stale separator default toc");
assert_eq!(
fields[2].computed_result.as_deref(),
Some("Executive Summary\n Risks\n Mitigation")
);
assert_eq!(fields[3].kind, FieldKind::Toc);
assert_eq!(fields[3].instruction, "TOC \\s chapter \\d \"-\"");
assert_eq!(fields[3].result, "stale sequence default toc");
assert_eq!(
fields[3].computed_result.as_deref(),
Some("Executive Summary\n Risks\n Mitigation")
);
assert_eq!(fields[4].kind, FieldKind::Toc);
assert_eq!(fields[4].instruction, "TOC \\* Upper");
assert_eq!(fields[4].result, "stale upper default toc");
assert_eq!(
fields[4].computed_result.as_deref(),
Some("EXECUTIVE SUMMARY\n RISKS\n MITIGATION")
);
assert_eq!(fields[5].kind, FieldKind::Toc);
assert_eq!(fields[5].instruction, "TOC \\* MERGEFORMAT");
assert_eq!(fields[5].result, "stale mergeformat default toc");
assert_eq!(
fields[5].computed_result.as_deref(),
Some("Executive Summary\n Risks\n Mitigation")
);
let main_text = doc.main_text();
assert!(
!main_text.contains("stale neutral default toc"),
"neutral-only TOC fields should display computed default heading text: {main_text:?}"
);
assert!(
!main_text.contains("stale no-page default toc"),
"no-page TOC fields should display computed default heading text: {main_text:?}"
);
assert!(
!main_text.contains("stale separator default toc"),
"separator TOC fields should display computed default heading text: {main_text:?}"
);
assert!(
!main_text.contains("stale sequence default toc"),
"sequence TOC fields should display computed default heading text: {main_text:?}"
);
assert!(
!main_text.contains("stale upper default toc"),
"formatted TOC fields should display computed default heading text: {main_text:?}"
);
assert!(
!main_text.contains("stale mergeformat default toc"),
"mergeformat TOC fields should display computed default heading text: {main_text:?}"
);
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
}
#[test]
fn docx_toc_field_with_neutral_switches_computes_heading_outline_range() {
let doc = Document::open(&toc_neutral_switch_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 1);
assert_eq!(fields[0].kind, FieldKind::Toc);
assert_eq!(fields[0].instruction, "TOC \\o \"1-2\" \\h \\z \\w \\x");
assert_eq!(fields[0].result, "stale neutral toc");
assert_eq!(
fields[0].computed_result.as_deref(),
Some("Executive Summary\n Risks")
);
let main_text = doc.main_text();
assert!(
!main_text.contains("stale neutral toc"),
"neutral TOC switches should still display computed heading text in the read model: {main_text:?}"
);
assert_eq!(main_text.matches("Executive Summary").count(), 2);
assert_eq!(main_text.matches("Risks").count(), 2);
}
#[test]
fn docx_toc_field_applies_general_format_switches() {
let doc = Document::open(&toc_general_format_switch_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 4);
assert_eq!(fields[0].kind, FieldKind::Toc);
assert_eq!(fields[0].instruction, "TOC \\o \"1-2\" \\* Upper");
assert_eq!(fields[0].result, "stale upper toc");
assert_eq!(
fields[0].computed_result.as_deref(),
Some("EXECUTIVE SUMMARY\n RISK REVIEW")
);
assert_eq!(fields[1].kind, FieldKind::Toc);
assert_eq!(fields[1].instruction, "TOC \\o \"1-2\" \\* Caps");
assert_eq!(fields[1].result, "stale caps toc");
assert_eq!(
fields[1].computed_result.as_deref(),
Some("Executive Summary\n Risk Review")
);
assert_eq!(fields[2].kind, FieldKind::Toc);
assert_eq!(fields[2].instruction, "TOC \\o \"1-2\" \\* MERGEFORMAT");
assert_eq!(fields[2].result, "stale mergeformat toc");
assert_eq!(
fields[2].computed_result.as_deref(),
Some("executive summary\n risk review")
);
assert_eq!(fields[3].kind, FieldKind::Toc);
assert_eq!(fields[3].instruction, "TOC \\o \"1-2\" \\* MERGEFORMATINET");
assert_eq!(fields[3].result, "stale web-format toc");
assert_eq!(
fields[3].computed_result.as_deref(),
Some("executive summary\n risk review")
);
let main_text = doc.main_text();
assert!(
!main_text.contains("stale upper toc")
&& !main_text.contains("stale caps toc")
&& !main_text.contains("stale mergeformat toc")
&& !main_text.contains("stale web-format toc"),
"TOC general format switches should display computed field text: {main_text:?}"
);
assert!(main_text.contains("EXECUTIVE SUMMARY"), "{main_text:?}");
assert!(main_text.contains("Executive Summary"), "{main_text:?}");
assert!(main_text.contains("executive summary"), "{main_text:?}");
}
#[test]
fn docx_toc_field_with_no_page_number_switch_computes_heading_outline_range() {
let doc = Document::open(&toc_no_page_numbers_switch_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 1);
assert_eq!(fields[0].kind, FieldKind::Toc);
assert_eq!(fields[0].instruction, "TOC \\o \"1-2\" \\n \"1-2\"");
assert_eq!(fields[0].result, "stale no-page toc");
assert_eq!(
fields[0].computed_result.as_deref(),
Some("Executive Summary\n Risks")
);
let main_text = doc.main_text();
assert!(
!main_text.contains("stale no-page toc"),
"TOC \\n should not block computed heading text in the read model: {main_text:?}"
);
assert_eq!(main_text.matches("Executive Summary").count(), 2);
assert_eq!(main_text.matches("Risks").count(), 2);
}
#[test]
fn docx_toc_field_with_entry_page_separator_switch_computes_heading_text() {
let doc = Document::open(&toc_entry_page_separator_switch_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 1);
assert_eq!(fields[0].kind, FieldKind::Toc);
assert_eq!(fields[0].instruction, "TOC \\o \"1-2\" \\p \"-\"");
assert_eq!(fields[0].result, "stale separator toc");
assert_eq!(
fields[0].computed_result.as_deref(),
Some("Executive Summary\n Risks")
);
let main_text = doc.main_text();
assert!(
!main_text.contains("stale separator toc"),
"TOC \\p changes only the omitted page-number separator and should keep computed heading text: {main_text:?}"
);
assert_eq!(main_text.matches("Executive Summary").count(), 2);
assert_eq!(main_text.matches("Risks").count(), 2);
}
#[test]
fn docx_toc_field_with_sequence_page_separator_switch_computes_heading_text() {
let doc = Document::open(&toc_sequence_page_separator_switch_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 1);
assert_eq!(fields[0].kind, FieldKind::Toc);
assert_eq!(
fields[0].instruction,
"TOC \\o \"1-2\" \\s chapter \\d \"-\""
);
assert_eq!(fields[0].result, "stale sequence separator toc");
assert_eq!(
fields[0].computed_result.as_deref(),
Some("Executive Summary\n Risks")
);
let main_text = doc.main_text();
assert!(
!main_text.contains("stale sequence separator toc"),
"TOC \\s and \\d change only omitted page-number prefixes/separators and should keep computed heading text: {main_text:?}"
);
assert_eq!(main_text.matches("Executive Summary").count(), 2);
assert_eq!(main_text.matches("Risks").count(), 2);
}
#[test]
fn docx_toc_u_field_computes_explicit_outline_levels_only() {
let doc = Document::open(&toc_outline_level_switch_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 1);
assert_eq!(fields[0].kind, FieldKind::Toc);
assert_eq!(fields[0].instruction, "TOC \\u");
assert_eq!(fields[0].result, "stale outline toc");
assert_eq!(
fields[0].computed_result.as_deref(),
Some("Outline Heading")
);
let main_text = doc.main_text();
assert!(
!main_text.contains("stale outline toc"),
"TOC \\u should display computed outline-level text in the read model: {main_text:?}"
);
assert_eq!(main_text.matches("Style Heading").count(), 1);
assert!(main_text.contains("Outline Heading"), "{main_text:?}");
}
#[test]
fn docx_toc_o_u_field_combines_heading_styles_and_outline_levels() {
let doc = Document::open(&toc_heading_and_outline_switch_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 1);
assert_eq!(fields[0].kind, FieldKind::Toc);
assert_eq!(fields[0].instruction, "TOC \\o \"1-2\" \\u");
assert_eq!(fields[0].result, "stale combined toc");
assert_eq!(
fields[0].computed_result.as_deref(),
Some("Style Heading\nOutline Heading")
);
let main_text = doc.main_text();
assert!(
!main_text.contains("stale combined toc"),
"TOC \\o plus \\u should display computed heading and outline text in the read model: {main_text:?}"
);
assert_eq!(main_text.matches("Style Heading").count(), 2);
assert_eq!(main_text.matches("Outline Heading").count(), 2);
}
#[test]
fn docx_toc_b_field_limits_computation_to_bookmark_scope() {
let doc = Document::open(&toc_bookmark_scope_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 1);
assert_eq!(fields[0].kind, FieldKind::Toc);
assert_eq!(fields[0].instruction, "TOC \\o \"1-2\" \\b ScopedToc");
assert_eq!(fields[0].result, "stale scoped toc");
assert_eq!(
fields[0].computed_result.as_deref(),
Some("Scoped Heading\n Scoped Detail")
);
let main_text = doc.main_text();
assert!(
!main_text.contains("stale scoped toc"),
"resolved TOC \\b fields should display scoped computed heading text: {main_text:?}"
);
assert_eq!(main_text.matches("Outside Heading").count(), 1);
assert_eq!(main_text.matches("Scoped Heading").count(), 2);
assert_eq!(main_text.matches("Scoped Detail").count(), 2);
assert_eq!(main_text.matches("Trailing Heading").count(), 1);
}
#[test]
fn docx_toc_b_field_limits_tc_entries_to_bookmark_scope() {
let doc = Document::open(&toc_bookmark_scoped_tc_field_switch_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 3);
assert_eq!(fields[0].kind, FieldKind::TocEntry);
assert_eq!(fields[0].instruction, "TC \"Outside Manual\" \\f m \\l 1");
assert_eq!(fields[0].result, "stale outside tc");
assert_eq!(fields[0].computed_result.as_deref(), Some(""));
assert_eq!(fields[1].kind, FieldKind::TocEntry);
assert_eq!(fields[1].instruction, "TC \"Scoped Manual\" \\f m \\l 2");
assert_eq!(fields[1].result, "stale scoped tc");
assert_eq!(fields[1].computed_result.as_deref(), Some(""));
assert_eq!(fields[2].kind, FieldKind::Toc);
assert_eq!(fields[2].instruction, "TOC \\b ScopedToc \\f m");
assert_eq!(fields[2].result, "stale scoped tc toc");
assert_eq!(
fields[2].computed_result.as_deref(),
Some(" Scoped Manual")
);
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
let main_text = doc.main_text();
assert!(
!main_text.contains("stale outside tc")
&& !main_text.contains("stale scoped tc")
&& !main_text.contains("stale scoped tc toc"),
"scoped TC marker fields and TOC should display computed text: {main_text:?}"
);
assert!(
main_text.contains("Scoped Manual"),
"scoped TC entry should materialize through TOC \\b plus \\f: {main_text:?}"
);
assert!(
!main_text.contains("Outside Manual"),
"TOC \\b should exclude out-of-scope matching TC entries: {main_text:?}"
);
}
#[test]
fn docx_toc_b_field_without_inclusion_switch_uses_default_heading_levels_in_scope() {
let doc = Document::open(&toc_bookmark_only_scope_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 1);
assert_eq!(fields[0].kind, FieldKind::Toc);
assert_eq!(fields[0].instruction, "TOC \\b ScopedToc");
assert_eq!(fields[0].result, "stale bookmark-only toc");
assert_eq!(
fields[0].computed_result.as_deref(),
Some("Scoped Heading\n Scoped Detail")
);
let main_text = doc.main_text();
assert!(
!main_text.contains("stale bookmark-only toc"),
"standalone TOC \\b should display scoped default heading text: {main_text:?}"
);
assert_eq!(main_text.matches("Outside Heading").count(), 1);
assert_eq!(main_text.matches("Scoped Heading").count(), 2);
assert_eq!(main_text.matches("Scoped Detail").count(), 2);
assert_eq!(main_text.matches("Scoped Deep Heading").count(), 1);
}
#[test]
fn docx_toc_fields_accept_compact_operand_switches() {
let doc = Document::open(&compact_toc_operand_switch_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 3);
assert_eq!(fields[0].kind, FieldKind::TocEntry);
assert_eq!(fields[0].instruction, "TC \"Manual Entry\" \\fm \\l2");
assert_eq!(fields[0].computed_result.as_deref(), Some(""));
assert_eq!(fields[1].kind, FieldKind::Toc);
assert_eq!(fields[1].instruction, "TOC \\fm \\l2-3");
assert_eq!(fields[1].result, "stale compact tc toc");
assert_eq!(fields[1].computed_result.as_deref(), Some("Manual Entry"));
assert_eq!(fields[2].kind, FieldKind::Toc);
assert_eq!(
fields[2].instruction,
"TOC \\o\"1-2\" \\bScopedToc \\*Upper"
);
assert_eq!(fields[2].result, "stale compact scoped toc");
assert_eq!(
fields[2].computed_result.as_deref(),
Some("SCOPED HEADING\n SCOPED DETAIL")
);
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
let main_text = doc.main_text();
assert!(
!main_text.contains("stale compact tc toc")
&& !main_text.contains("stale compact scoped toc"),
"compact TOC operand switches should display computed text: {main_text:?}"
);
assert!(main_text.contains("Manual Entry"), "{main_text:?}");
assert!(main_text.contains("SCOPED HEADING"), "{main_text:?}");
assert!(main_text.contains("SCOPED DETAIL"), "{main_text:?}");
assert_eq!(main_text.matches("Outside Heading").count(), 1);
}
#[test]
fn docx_toc_o_field_without_range_includes_all_heading_levels() {
let doc = Document::open(&toc_outline_without_range_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 1);
assert_eq!(fields[0].kind, FieldKind::Toc);
assert_eq!(fields[0].instruction, "TOC \\o");
assert_eq!(fields[0].result, "stale open-outline toc");
assert_eq!(
fields[0].computed_result.as_deref(),
Some("Executive Summary\n Appendix Detail")
);
let main_text = doc.main_text();
assert!(
!main_text.contains("stale open-outline toc"),
"TOC \\o without an explicit range should display every heading level: {main_text:?}"
);
assert_eq!(main_text.matches("Executive Summary").count(), 2);
assert_eq!(main_text.matches("Appendix Detail").count(), 2);
}
#[test]
fn docx_toc_b_field_with_missing_bookmark_keeps_cached_text() {
let doc = Document::open(&missing_toc_bookmark_scope_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 1);
assert_eq!(fields[0].kind, FieldKind::Toc);
assert_eq!(fields[0].instruction, "TOC \\o \"1-1\" \\b MissingScope");
assert_eq!(fields[0].result, "stale missing scope toc");
assert_eq!(fields[0].computed_result, None);
let main_text = doc.main_text();
assert!(
main_text.contains("stale missing scope toc"),
"TOC \\b with a missing scope should keep cached result text: {main_text:?}"
);
}
#[test]
fn docx_toc_b_existing_empty_scope_computes_empty_result() {
let doc = Document::open(&toc_scope_gap_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 2);
assert_eq!(fields[0].kind, FieldKind::Toc);
assert_eq!(fields[0].instruction, "TOC \\b PlainText");
assert_eq!(fields[0].result, "cached empty toc");
assert_eq!(fields[0].computed_result.as_deref(), Some(""));
assert_eq!(fields[1].kind, FieldKind::Toc);
assert_eq!(fields[1].instruction, "TOC \\b MissingScope");
assert_eq!(fields[1].result, "cached missing toc scope");
assert_eq!(fields[1].computed_result, None);
let report = doc.report();
assert_eq!(
report.features.unsupported_field_kinds,
vec![FieldKindCount {
kind: FieldKind::Toc,
count: 1,
}]
);
assert_eq!(
report.features.unsupported_field_reasons,
vec![FieldEvaluationReasonCount {
reason: FieldEvaluationReason::UnresolvedBookmark,
count: 1,
}]
);
assert_eq!(
model_simple_field_reason_hints(&doc, |instruction| instruction.starts_with("TOC")),
vec![(
"TOC \\b MissingScope".to_string(),
Some(FieldUnsupportedReason::UnresolvedBookmark),
)]
);
let main_text = doc.main_text();
assert!(
!main_text.contains("cached empty toc") && main_text.contains("cached missing toc scope"),
"TOC \\b with an existing empty scope should compute empty text while missing scopes keep cached text: {main_text:?}"
);
}
#[test]
fn docx_toc_field_with_unsupported_switch_keeps_cached_text() {
let doc = Document::open(&unsupported_toc_switch_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 1);
assert_eq!(fields[0].kind, FieldKind::Toc);
assert_eq!(fields[0].instruction, "TOC \\q");
assert_eq!(fields[0].result, "cached bad toc switch");
assert_eq!(fields[0].computed_result, None);
let report = doc.report();
assert_eq!(
report.features.unsupported_field_kinds,
vec![FieldKindCount {
kind: FieldKind::Toc,
count: 1,
}]
);
assert_eq!(
report.features.unsupported_field_reasons,
vec![FieldEvaluationReasonCount {
reason: FieldEvaluationReason::UnsupportedSwitch,
count: 1,
}]
);
assert_eq!(
model_simple_field_reason_hints(&doc, |instruction| instruction.starts_with("TOC")),
vec![(
"TOC \\q".to_string(),
Some(FieldUnsupportedReason::UnsupportedSwitch),
)]
);
let main_text = doc.main_text();
assert!(
main_text.contains("cached bad toc switch"),
"unsupported TOC switches should keep cached result text: {main_text:?}"
);
}
#[test]
fn docx_toc_field_accepts_unquoted_multi_token_custom_style_switch() {
let doc = Document::open(&toc_unquoted_multi_token_custom_style_switch_docx())
.expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 1);
assert_eq!(fields[0].kind, FieldKind::Toc);
assert_eq!(
fields[0].instruction,
"TOC \\o \"1-1\" \\t Custom Heading,2 \\* Upper"
);
assert_eq!(fields[0].result, "stale unquoted custom toc");
assert_eq!(
fields[0].computed_result.as_deref(),
Some("EXECUTIVE SUMMARY\n CUSTOM FINDING")
);
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
let main_text = doc.main_text();
assert!(
!main_text.contains("stale unquoted custom toc"),
"TOC \\t should preserve switch-delimited unquoted custom style names: {main_text:?}"
);
assert_eq!(main_text.matches("EXECUTIVE SUMMARY").count(), 1);
assert_eq!(main_text.matches("CUSTOM FINDING").count(), 1);
}
#[test]
fn docx_toc_field_with_custom_style_switch_computes_matching_entries() {
let doc = Document::open(&toc_custom_style_switch_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 1);
assert_eq!(fields[0].kind, FieldKind::Toc);
assert_eq!(
fields[0].instruction,
"TOC \\o \"1-1\" \\t \"CustomHeading,2\""
);
assert_eq!(fields[0].result, "stale custom toc");
assert_eq!(
fields[0].computed_result.as_deref(),
Some("Executive Summary\n Custom Finding")
);
let main_text = doc.main_text();
assert!(
!main_text.contains("stale custom toc"),
"TOC \\t should display computed heading and custom-style entries: {main_text:?}"
);
assert_eq!(main_text.matches("Executive Summary").count(), 2);
assert_eq!(main_text.matches("Custom Finding").count(), 2);
}
#[test]
fn docx_toc_field_with_quoted_custom_style_switch_keeps_style_name_spaces() {
let doc = Document::open(&toc_quoted_custom_style_switch_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 1);
assert_eq!(fields[0].kind, FieldKind::Toc);
assert_eq!(
fields[0].instruction,
"TOC \\o \"1-1\" \\t \"Custom Heading,2\""
);
assert_eq!(fields[0].result, "stale quoted custom toc");
assert_eq!(
fields[0].computed_result.as_deref(),
Some("Executive Summary\n Custom Finding")
);
let main_text = doc.main_text();
assert!(
!main_text.contains("stale quoted custom toc"),
"TOC \\t should preserve quoted custom style names with spaces: {main_text:?}"
);
assert_eq!(main_text.matches("Executive Summary").count(), 2);
assert_eq!(main_text.matches("Custom Finding").count(), 2);
}
#[test]
fn docx_toc_field_with_unmatched_custom_style_switch_keeps_heading_computation() {
let doc = Document::open(&advanced_toc_switch_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 1);
assert_eq!(fields[0].kind, FieldKind::Toc);
assert_eq!(
fields[0].instruction,
"TOC \\o \"1-2\" \\t \"CustomHeading,1\""
);
assert_eq!(fields[0].result, "stale advanced toc");
assert_eq!(
fields[0].computed_result.as_deref(),
Some("Executive Summary")
);
let main_text = doc.main_text();
assert!(
!main_text.contains("stale advanced toc"),
"unmatched TOC \\t styles should not block computable heading text: {main_text:?}"
);
assert!(main_text.contains("Executive Summary"), "{main_text:?}");
}
#[test]
fn docx_toc_field_with_tc_switch_computes_matching_tc_entries() {
let doc = Document::open(&toc_tc_field_switch_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 3);
assert_eq!(fields[0].kind, FieldKind::TocEntry);
assert_eq!(fields[0].instruction, "TC \"Manual Entry\" \\f m \\l 2");
assert_eq!(fields[0].result, "stale manual tc");
assert_eq!(fields[0].computed_result.as_deref(), Some(""));
assert_eq!(fields[1].kind, FieldKind::TocEntry);
assert_eq!(fields[1].instruction, "TC \"Other Entry\" \\f x \\l 1");
assert_eq!(fields[1].result, "stale other tc");
assert_eq!(fields[1].computed_result.as_deref(), Some(""));
let toc = fields
.iter()
.find(|field| field.kind == FieldKind::Toc)
.expect("TOC field is parsed");
assert_eq!(toc.instruction, "TOC \\f m");
assert_eq!(toc.result, "stale tc toc");
assert_eq!(toc.computed_result.as_deref(), Some(" Manual Entry"));
let main_text = doc.main_text();
assert!(
!main_text.contains("stale tc toc"),
"TOC \\f should display computed TC entry text in the read model: {main_text:?}"
);
assert!(
!main_text.contains("stale manual tc") && !main_text.contains("stale other tc"),
"TC marker fields should not leak cached marker text into main text: {main_text:?}"
);
assert!(main_text.contains("Manual Entry"), "{main_text:?}");
assert!(
!main_text.contains("Other Entry"),
"TOC \\f identifier should filter non-matching TC entries: {main_text:?}"
);
}
#[test]
fn docx_toc_entry_applies_text_format_tail_to_marker_text() {
let doc = Document::open(&toc_tc_format_tail_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 3);
assert_eq!(fields[0].kind, FieldKind::TocEntry);
assert_eq!(
fields[0].instruction,
"TC \"manual entry\" \\f m \\l 2 \\* Upper"
);
assert_eq!(fields[0].result, "stale formatted tc");
assert_eq!(fields[0].computed_result.as_deref(), Some(""));
assert_eq!(fields[1].kind, FieldKind::TocEntry);
assert_eq!(
fields[1].instruction,
"TC \"other entry\" \\f x \\l 1 \\* Caps"
);
assert_eq!(fields[1].computed_result.as_deref(), Some(""));
let toc = fields
.iter()
.find(|field| field.kind == FieldKind::Toc)
.expect("TOC field is parsed");
assert_eq!(toc.instruction, "TOC \\f m");
assert_eq!(toc.result, "stale formatted tc toc");
assert_eq!(toc.computed_result.as_deref(), Some(" MANUAL ENTRY"));
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
let main_text = doc.main_text();
assert!(
main_text.contains("MANUAL ENTRY")
&& !main_text.contains("stale formatted tc")
&& !main_text.contains("stale other formatted tc")
&& !main_text.contains("stale formatted tc toc"),
"formatted TC marker fields should stay hidden and feed formatted TOC text: {main_text:?}"
);
assert!(
!main_text.contains("Other Entry") && !main_text.contains("Other entry"),
"TOC \\f should still filter non-matching formatted TC entries: {main_text:?}"
);
}
#[test]
fn docx_toc_entry_accepts_unquoted_multi_token_marker_text() {
let doc = Document::open(&toc_tc_unquoted_multi_token_text_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 2);
assert_eq!(fields[0].kind, FieldKind::TocEntry);
assert_eq!(
fields[0].instruction,
"TC Manual Appendix Entry \\f m \\l 2"
);
assert_eq!(fields[0].result, "cached unquoted tc");
assert_eq!(fields[0].computed_result.as_deref(), Some(""));
assert_eq!(fields[1].kind, FieldKind::Toc);
assert_eq!(fields[1].instruction, "TOC \\f m");
assert_eq!(fields[1].result, "stale unquoted tc toc");
assert_eq!(
fields[1].computed_result.as_deref(),
Some(" Manual Appendix Entry")
);
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
let main_text = doc.main_text();
assert!(
main_text.contains("Manual Appendix Entry")
&& !main_text.contains("cached unquoted tc")
&& !main_text.contains("stale unquoted tc toc"),
"unquoted multi-token TC marker text should stay hidden and feed TOC \\f: {main_text:?}"
);
}
#[test]
fn docx_toc_entries_ignore_deleted_tc_fields() {
let doc = Document::open(&toc_deleted_tc_field_switch_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 2);
assert_eq!(fields[0].kind, FieldKind::TocEntry);
assert_eq!(fields[0].instruction, "TC \"Visible Entry\" \\f m \\l 1");
assert_eq!(fields[0].computed_result.as_deref(), Some(""));
let toc = fields
.iter()
.find(|field| field.kind == FieldKind::Toc)
.expect("TOC field is parsed");
assert_eq!(toc.computed_result.as_deref(), Some("Visible Entry"));
let main_text = doc.main_text();
assert!(
main_text.contains("Visible Entry")
&& !main_text.contains("Deleted Entry")
&& !main_text.contains("Moved Entry"),
"TOC entries must follow accepted-current revision wrappers: {main_text:?}"
);
}
#[test]
fn docx_toc_entries_use_single_alternate_content_branch() {
let doc = Document::open(&toc_alternate_content_heading_docx()).expect("fixture opens");
let fields = doc.fields();
let toc = fields
.iter()
.find(|field| field.kind == FieldKind::Toc)
.expect("TOC field is parsed");
assert_eq!(toc.computed_result.as_deref(), Some("Choice Inline"));
let main_text = doc.main_text();
assert!(
main_text.contains("Choice Inline")
&& !main_text.contains("Fallback Heading")
&& !main_text.contains("Fallback Inline"),
"TOC entries must use one AlternateContent branch: {main_text:?}"
);
}
#[test]
fn docx_toc_heading_styles_use_single_styles_alternate_content_branch() {
let doc = Document::open(&toc_styles_alternate_content_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 1);
assert_eq!(fields[0].kind, FieldKind::Toc);
assert_eq!(fields[0].instruction, "TOC \\o \"1-1\"");
assert_eq!(fields[0].result, "stale styles toc");
assert_eq!(fields[0].computed_result.as_deref(), Some("Choice Heading"));
let main_text = doc.main_text();
assert!(
main_text.contains("Choice Heading")
&& main_text.contains("Fallback Ghost")
&& !main_text.contains("stale styles toc"),
"TOC must use only selected-branch styles while preserving body text: {main_text:?}"
);
}
#[test]
fn docx_invalid_toc_entry_reports_unsupported_switch() {
let doc = Document::open(&invalid_toc_entry_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 1);
assert_eq!(fields[0].kind, FieldKind::TocEntry);
assert_eq!(fields[0].instruction, "TC \\l 2");
assert_eq!(fields[0].result, "cached invalid tc");
assert_eq!(fields[0].computed_result, None);
let report = doc.report();
assert_eq!(
report.features.unsupported_field_kinds,
vec![FieldKindCount {
kind: FieldKind::TocEntry,
count: 1,
}]
);
assert_eq!(
report.features.unsupported_field_reasons,
vec![FieldEvaluationReasonCount {
reason: FieldEvaluationReason::UnsupportedSwitch,
count: 1,
}]
);
assert_eq!(
model_simple_field_reason_hints(&doc, |instruction| instruction.starts_with("TC")),
vec![(
"TC \\l 2".to_string(),
Some(FieldUnsupportedReason::UnsupportedSwitch),
)]
);
let main_text = doc.main_text();
assert!(
main_text.contains("cached invalid tc"),
"unsupported TC marker should preserve cached text: {main_text:?}"
);
}
#[test]
fn docx_toc_c_field_computes_matching_seq_caption_entries() {
let doc = Document::open(&toc_sequence_caption_switch_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 3);
assert_eq!(fields[0].kind, FieldKind::Sequence);
assert_eq!(fields[0].instruction, "SEQ Figure");
assert_eq!(fields[0].result, "1");
assert_eq!(fields[0].computed_result.as_deref(), Some("1"));
assert_eq!(fields[1].kind, FieldKind::Sequence);
assert_eq!(fields[1].instruction, "SEQ Table");
assert_eq!(fields[1].result, "1");
assert_eq!(fields[1].computed_result.as_deref(), Some("1"));
let toc = fields
.iter()
.find(|field| field.kind == FieldKind::Toc)
.expect("TOC field is parsed");
assert_eq!(toc.instruction, "TOC \\c \"Figure\"");
assert_eq!(toc.result, "stale figures toc");
assert_eq!(toc.computed_result.as_deref(), Some("Figure 1: Mercury"));
let main_text = doc.main_text();
assert!(
!main_text.contains("stale figures toc"),
"TOC \\c should display computed SEQ caption entries in the read model: {main_text:?}"
);
assert_eq!(main_text.matches("Figure 1: Mercury").count(), 2);
assert_eq!(main_text.matches("Table 1: Invoices").count(), 1);
}
#[test]
fn docx_toc_c_field_uses_computed_seq_numbers_for_dirty_caption_entries() {
let doc = Document::open(&toc_dirty_sequence_caption_switch_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 3);
assert_eq!(fields[0].kind, FieldKind::Sequence);
assert_eq!(fields[0].instruction, "SEQ Figure");
assert_eq!(fields[0].result, "9");
assert_eq!(fields[0].computed_result.as_deref(), Some("1"));
assert_eq!(fields[1].kind, FieldKind::Sequence);
assert_eq!(fields[1].instruction, "SEQ Figure");
assert_eq!(fields[1].result, "99");
assert_eq!(fields[1].computed_result.as_deref(), Some("2"));
let toc = fields
.iter()
.find(|field| field.kind == FieldKind::Toc)
.expect("TOC field is parsed");
assert_eq!(toc.instruction, "TOC \\c Figure");
assert_eq!(toc.result, "stale dirty figures toc");
assert_eq!(
toc.computed_result.as_deref(),
Some("Figure 1: Mercury\nFigure 2: Venus")
);
let main_text = doc.main_text();
assert!(
!main_text.contains("stale dirty figures toc"),
"TOC \\c should use computed SEQ caption numbers in the read model: {main_text:?}"
);
assert_eq!(main_text.matches("Figure 1: Mercury").count(), 2);
assert_eq!(main_text.matches("Figure 2: Venus").count(), 2);
}
#[test]
fn docx_toc_c_field_uses_computed_complex_seq_numbers_for_dirty_caption_entries() {
let doc =
Document::open(&toc_dirty_complex_sequence_caption_switch_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 3);
assert_eq!(fields[0].kind, FieldKind::Sequence);
assert_eq!(fields[0].instruction, "SEQ Figure");
assert_eq!(fields[0].result, "9");
assert_eq!(fields[0].computed_result.as_deref(), Some("1"));
assert_eq!(fields[1].kind, FieldKind::Sequence);
assert_eq!(fields[1].instruction, "SEQ Figure");
assert_eq!(fields[1].result, "99");
assert_eq!(fields[1].computed_result.as_deref(), Some("2"));
let toc = fields
.iter()
.find(|field| field.kind == FieldKind::Toc)
.expect("TOC field is parsed");
assert_eq!(toc.instruction, "TOC \\c Figure");
assert_eq!(toc.result, "stale dirty complex figures toc");
assert_eq!(
toc.computed_result.as_deref(),
Some("Figure 1: Mercury\nFigure 2: Venus")
);
let main_text = doc.main_text();
assert!(
!main_text.contains("stale dirty complex figures toc"),
"TOC \\c should use computed complex SEQ caption numbers in the read model: {main_text:?}"
);
assert_eq!(main_text.matches("Figure 1: Mercury").count(), 2);
assert_eq!(main_text.matches("Figure 2: Venus").count(), 2);
}
#[test]
fn docx_toc_a_field_computes_matching_seq_caption_text_without_label() {
let doc = Document::open(&toc_sequence_caption_text_switch_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 3);
assert_eq!(fields[0].kind, FieldKind::Sequence);
assert_eq!(fields[0].instruction, "SEQ Figure");
assert_eq!(fields[0].result, "8");
assert_eq!(fields[0].computed_result.as_deref(), Some("1"));
assert_eq!(fields[1].kind, FieldKind::Sequence);
assert_eq!(fields[1].instruction, "SEQ Table");
assert_eq!(fields[1].result, "2");
assert_eq!(fields[1].computed_result.as_deref(), Some("1"));
let toc = fields
.iter()
.find(|field| field.kind == FieldKind::Toc)
.expect("TOC field is parsed");
assert_eq!(toc.instruction, "TOC \\a Figure");
assert_eq!(toc.result, "stale caption-text toc");
assert_eq!(toc.computed_result.as_deref(), Some("Mercury"));
let main_text = doc.main_text();
assert!(
!main_text.contains("stale caption-text toc"),
"TOC \\a should display computed SEQ caption text in the read model: {main_text:?}"
);
assert_eq!(main_text.matches("Figure 1: Mercury").count(), 1);
assert_eq!(main_text.matches("Mercury").count(), 2);
assert_eq!(main_text.matches("Table 1: Invoices").count(), 1);
}
#[test]
fn docx_toc_caption_fields_use_seq_heading_reset_numbers() {
let doc =
Document::open(&toc_sequence_heading_reset_caption_switch_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 4);
assert_eq!(fields[0].kind, FieldKind::Sequence);
assert_eq!(fields[0].instruction, "SEQ Figure \\s 1");
assert_eq!(fields[0].result, "9");
assert_eq!(fields[0].computed_result.as_deref(), Some("1"));
assert_eq!(fields[1].kind, FieldKind::Sequence);
assert_eq!(fields[1].instruction, "SEQ Figure \\s1");
assert_eq!(fields[1].result, "99");
assert_eq!(fields[1].computed_result.as_deref(), Some("1"));
let caption_toc = fields
.iter()
.find(|field| field.instruction == "TOC \\c Figure")
.expect("TOC \\c field is parsed");
assert_eq!(
caption_toc.computed_result.as_deref(),
Some("Figure 1: Mercury\nFigure 1: Venus")
);
let caption_text_toc = fields
.iter()
.find(|field| field.instruction == "TOC \\a Figure")
.expect("TOC \\a field is parsed");
assert_eq!(
caption_text_toc.computed_result.as_deref(),
Some("Mercury\nVenus")
);
let main_text = doc.main_text();
assert!(
!main_text.contains("stale heading-reset figures toc")
&& !main_text.contains("stale heading-reset captions toc"),
"TOC caption fields should display computed SEQ heading-reset entries: {main_text:?}"
);
assert_eq!(main_text.matches("Figure 1: Mercury").count(), 2);
assert_eq!(main_text.matches("Figure 1: Venus").count(), 2);
}
#[test]
fn docx_ref_field_computes_unambiguous_bookmark_text() {
let doc = Document::open(&ref_bookmark_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 2);
assert_eq!(fields[0].kind, FieldKind::Ref);
assert_eq!(fields[0].instruction, "REF Figure1");
assert_eq!(fields[0].result, "stale cached text");
assert_eq!(fields[0].computed_result.as_deref(), Some("Figure 1"));
assert!(
!doc.main_text().contains("stale cached text"),
"resolved REF fields should display computed bookmark text in the read model"
);
assert_eq!(fields[1].kind, FieldKind::Ref);
assert_eq!(fields[1].instruction, "REF MissingBookmark");
assert_eq!(fields[1].computed_result, None);
}
#[test]
fn docx_ref_field_computes_empty_bookmark_text() {
let doc = Document::open(&ref_empty_bookmark_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 3);
assert!(fields.iter().all(|field| field.kind == FieldKind::Ref));
assert_eq!(fields[0].instruction, "REF EmptyTarget");
assert_eq!(fields[0].result, "stale empty ref");
assert_eq!(fields[0].computed_result.as_deref(), Some(""));
assert_eq!(fields[1].instruction, "REF EmptyTarget \\* Upper");
assert_eq!(fields[1].result, "stale empty upper ref");
assert_eq!(fields[1].computed_result.as_deref(), Some(""));
assert_eq!(fields[2].instruction, "REF MissingTarget");
assert_eq!(fields[2].result, "cached missing ref");
assert_eq!(fields[2].computed_result, None);
let report = doc.report();
assert_eq!(
report.features.unsupported_field_kinds,
vec![FieldKindCount {
kind: FieldKind::Ref,
count: 1,
}]
);
assert_eq!(
report.features.unsupported_field_reasons,
vec![FieldEvaluationReasonCount {
reason: FieldEvaluationReason::UnresolvedBookmark,
count: 1,
}]
);
let main_text = doc.main_text();
assert!(
!main_text.contains("stale empty ref")
&& !main_text.contains("stale empty upper ref")
&& main_text.contains("cached missing ref"),
"empty REF targets should render as empty computed text while missing targets stay cached: {main_text:?}"
);
}
#[test]
fn docx_ref_targets_use_computed_nested_simple_field_results() {
let doc = Document::open(&nested_simple_field_ref_bookmark_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 2);
assert_eq!(fields[0].kind, FieldKind::Dynamic("QUOTE".to_string()));
assert_eq!(fields[0].instruction, r#"QUOTE "Current target""#);
assert_eq!(fields[0].result, "stale nested quote");
assert_eq!(fields[0].computed_result.as_deref(), Some("Current target"));
assert_eq!(fields[1].kind, FieldKind::Ref);
assert_eq!(fields[1].instruction, "REF ComputedText");
assert_eq!(fields[1].result, "stale outer ref");
assert_eq!(fields[1].computed_result.as_deref(), Some("Current target"));
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
let main_text = doc.main_text();
assert!(
main_text.contains("Current target")
&& !main_text.contains("stale nested quote")
&& !main_text.contains("stale outer ref"),
"REF targets should use deterministic nested simple-field output, not stale cached text: {main_text:?}"
);
}
#[test]
fn docx_ref_targets_use_computed_nested_note_ref_field_results() {
let doc = Document::open(&nested_note_ref_field_ref_bookmark_docx()).expect("fixture opens");
let fields = doc.fields();
let note_ref = fields
.iter()
.find(|field| field.instruction == "NOTEREF FootOne")
.expect("nested NOTEREF field is recorded");
assert_eq!(note_ref.kind, FieldKind::NoteRef);
assert_eq!(note_ref.result, "stale target note");
assert_eq!(note_ref.computed_result.as_deref(), Some("1"));
let relative_note_ref = fields
.iter()
.find(|field| field.instruction == "NOTEREF FootOne \\p")
.expect("relative nested NOTEREF field is recorded");
assert_eq!(relative_note_ref.kind, FieldKind::NoteRef);
assert_eq!(relative_note_ref.result, "stale target relative note");
assert_eq!(relative_note_ref.computed_result.as_deref(), Some("above"));
let reference = fields
.iter()
.find(|field| field.instruction == "REF ComputedNoteText")
.expect("outer REF field is recorded");
assert_eq!(reference.kind, FieldKind::Ref);
assert_eq!(reference.result, "stale outer note target ref");
assert_eq!(reference.computed_result.as_deref(), Some("1 / above"));
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
let main_text = doc.main_text();
assert!(
main_text.contains("1 / above")
&& !main_text.contains("stale target note")
&& !main_text.contains("stale target relative note")
&& !main_text.contains("stale outer note target ref"),
"REF targets should use computed NOTEREF source field output: {main_text:?}"
);
}
#[test]
fn docx_ref_targets_use_computed_nested_ref_note_mark_field_results() {
let doc =
Document::open(&nested_ref_note_mark_field_ref_bookmark_docx()).expect("fixture opens");
let fields = doc.fields();
let note_ref_mark = fields
.iter()
.find(|field| field.instruction == "REF FootOne \\f")
.expect("nested REF note-mark field is recorded");
assert_eq!(note_ref_mark.kind, FieldKind::Ref);
assert_eq!(note_ref_mark.result, "stale target ref note mark");
assert_eq!(note_ref_mark.computed_result.as_deref(), Some("2"));
let reference = fields
.iter()
.find(|field| field.instruction == "REF ComputedRefNoteMark")
.expect("outer REF field is recorded");
assert_eq!(reference.kind, FieldKind::Ref);
assert_eq!(reference.result, "stale outer ref note target");
assert_eq!(reference.computed_result.as_deref(), Some("2"));
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
let main_text = doc.main_text();
assert!(
main_text.contains("2\n2")
&& !main_text.contains("stale target ref note mark")
&& !main_text.contains("stale outer ref note target"),
"REF targets should use computed REF note-mark source field output: {main_text:?}"
);
}
#[test]
fn docx_ref_targets_use_computed_nested_empty_simple_field_results() {
let doc =
Document::open(&nested_empty_simple_field_ref_bookmark_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 2);
assert_eq!(fields[0].kind, FieldKind::Dynamic("QUOTE".to_string()));
assert_eq!(fields[0].instruction, r#"QUOTE "Current target""#);
assert_eq!(fields[0].result, "");
assert_eq!(fields[0].computed_result.as_deref(), Some("Current target"));
assert_eq!(fields[1].kind, FieldKind::Ref);
assert_eq!(fields[1].instruction, "REF ComputedText");
assert_eq!(fields[1].result, "stale empty outer ref");
assert_eq!(fields[1].computed_result.as_deref(), Some("Current target"));
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
let main_text = doc.main_text();
assert!(
main_text.contains("Current target") && !main_text.contains("stale empty outer ref"),
"REF targets should use deterministic empty simple-field output, not omit source text: {main_text:?}"
);
}
#[test]
fn docx_ref_targets_compute_document_info_field_results() {
let doc = Document::open(&document_info_ref_target_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 2);
assert_eq!(fields[0].kind, FieldKind::DocumentInfo("TITLE".to_string()));
assert_eq!(fields[0].instruction, "TITLE");
assert_eq!(fields[0].result, "stale nested title");
assert_eq!(fields[0].computed_result.as_deref(), Some("Quarter Plan"));
assert_eq!(fields[1].kind, FieldKind::Ref);
assert_eq!(fields[1].instruction, "REF ComputedTitle");
assert_eq!(fields[1].result, "stale title ref");
assert_eq!(fields[1].computed_result.as_deref(), Some("Quarter Plan"));
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
let main_text = doc.main_text();
assert!(
main_text.contains("Quarter Plan")
&& !main_text.contains("stale nested title")
&& !main_text.contains("stale title ref"),
"REF targets should use computed document-info source text, not stale cached text: {main_text:?}"
);
}
#[test]
fn docx_source_scanners_use_computed_revision_number_results() {
let doc = Document::open(&revision_number_source_scanners_docx()).expect("fixture opens");
let fields = doc.fields();
let revision_fields = fields
.iter()
.filter(|field| field.kind == FieldKind::DocumentStructure("REVNUM".to_string()))
.collect::<Vec<_>>();
assert_eq!(revision_fields.len(), 3);
assert!(revision_fields
.iter()
.all(|field| field.computed_result.as_deref() == Some("12")));
let reference = fields
.iter()
.find(|field| field.instruction == "REF ComputedRevision")
.expect("REF field is recorded");
assert_eq!(reference.kind, FieldKind::Ref);
assert_eq!(reference.result, "stale revision ref");
assert_eq!(reference.computed_result.as_deref(), Some("12"));
let style_ref = fields
.iter()
.find(|field| field.instruction == "STYLEREF \"heading 1\"")
.expect("STYLEREF field is recorded");
assert_eq!(
style_ref.kind,
FieldKind::DocumentStructure("STYLEREF".to_string())
);
assert_eq!(style_ref.result, "stale revision style source");
assert_eq!(
style_ref.computed_result.as_deref(),
Some("Release 12 Notes")
);
let toc = fields
.iter()
.find(|field| field.kind == FieldKind::Toc)
.expect("TOC field is recorded");
assert_eq!(toc.instruction, "TOC \\o \"1-1\"");
assert_eq!(toc.result, "stale revision toc source");
assert_eq!(toc.computed_result.as_deref(), Some("Release 12 Notes"));
let formula = fields
.iter()
.find(|field| field.instruction == r#"= SUM(LEFT)"#)
.expect("table formula field is recorded");
assert_eq!(formula.kind, FieldKind::Dynamic("=".to_string()));
assert_eq!(formula.result, "stale revision source sum");
assert_eq!(formula.computed_result.as_deref(), Some("12"));
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
let main_text = doc.main_text();
assert!(
main_text.contains("12")
&& main_text.contains("Release 12 Notes")
&& !main_text.contains("stale ref revision")
&& !main_text.contains("stale revision ref")
&& !main_text.contains("stale style revision")
&& !main_text.contains("stale revision style source")
&& !main_text.contains("stale revision toc source")
&& !main_text.contains("stale revision source sum")
&& !main_text.contains("99"),
"source scanners should use computed REVNUM output: {main_text:?}"
);
}
#[test]
fn docx_ref_targets_compute_empty_simple_fields_inside_field_results() {
let doc = Document::open(&nested_empty_simple_field_inside_ref_target_result_docx())
.expect("fixture opens");
let fields = doc.fields();
let ref_field = fields
.iter()
.find(|field| field.instruction == "REF ComputedText")
.expect("REF field is parsed");
assert_eq!(ref_field.kind, FieldKind::Ref);
assert_eq!(ref_field.result, "stale nested empty result ref");
assert_eq!(
ref_field.computed_result.as_deref(),
Some("Prefix Inner target Suffix")
);
let main_text = doc.main_text();
assert!(
main_text.contains("Prefix Inner target Suffix")
&& !main_text.contains("stale nested empty result ref"),
"REF targets should compute empty simple fields consumed inside another field result: {main_text:?}"
);
}
#[test]
fn docx_ref_targets_compute_simple_fields_inside_field_results() {
let doc = Document::open(&nested_simple_field_inside_ref_target_result_docx())
.expect("fixture opens");
let fields = doc.fields();
let ref_field = fields
.iter()
.find(|field| field.instruction == "REF ComputedText")
.expect("REF field is parsed");
assert_eq!(ref_field.kind, FieldKind::Ref);
assert_eq!(ref_field.result, "stale nested result ref");
assert_eq!(
ref_field.computed_result.as_deref(),
Some("Prefix Inner target Suffix")
);
let main_text = doc.main_text();
assert!(
main_text.contains("Prefix Inner target Suffix")
&& !main_text.contains("stale nested result ref"),
"REF targets should compute non-empty simple fields consumed inside another field result: {main_text:?}"
);
}
#[test]
fn docx_ref_targets_compute_complex_fields_inside_simple_field_results() {
let doc = Document::open(&nested_complex_field_inside_ref_target_result_docx())
.expect("fixture opens");
let fields = doc.fields();
let ref_field = fields
.iter()
.find(|field| field.instruction == "REF ComputedText")
.expect("REF field is parsed");
assert_eq!(ref_field.kind, FieldKind::Ref);
assert_eq!(ref_field.result, "stale nested complex result ref");
assert_eq!(
ref_field.computed_result.as_deref(),
Some("Prefix Inner target Suffix")
);
let main_text = doc.main_text();
assert!(
main_text.contains("Prefix Inner target Suffix")
&& !main_text.contains("stale nested complex result ref"),
"REF targets should compute complex fields consumed inside a simple field result: {main_text:?}"
);
}
#[test]
fn docx_ref_targets_use_computed_nested_complex_field_results() {
let doc = Document::open(&nested_complex_field_ref_bookmark_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 2);
assert_eq!(fields[0].kind, FieldKind::Dynamic("QUOTE".to_string()));
assert_eq!(fields[0].instruction, r#"QUOTE "Complex target""#);
assert_eq!(fields[0].result, "stale complex quote");
assert_eq!(fields[0].computed_result.as_deref(), Some("Complex target"));
assert_eq!(fields[1].kind, FieldKind::Ref);
assert_eq!(fields[1].instruction, "REF ComputedText");
assert_eq!(fields[1].result, "stale outer ref");
assert_eq!(fields[1].computed_result.as_deref(), Some("Complex target"));
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
let main_text = doc.main_text();
assert!(
main_text.contains("Complex target")
&& !main_text.contains("stale complex quote")
&& !main_text.contains("stale outer ref"),
"REF targets should use deterministic nested complex-field output, not stale cached text: {main_text:?}"
);
}
#[test]
fn docx_ref_targets_use_computed_nested_sequence_field_results() {
let doc = Document::open(&nested_sequence_field_ref_bookmark_docx()).expect("fixture opens");
let fields = doc.fields();
let sequence_fields = fields
.iter()
.filter(|field| field.kind == FieldKind::Sequence)
.collect::<Vec<_>>();
assert_eq!(sequence_fields.len(), 3);
assert_eq!(sequence_fields[0].instruction, "SEQ Item");
assert_eq!(sequence_fields[0].computed_result.as_deref(), Some("1"));
assert_eq!(sequence_fields[1].instruction, "SEQ Item");
assert_eq!(sequence_fields[1].result, "99");
assert_eq!(sequence_fields[1].computed_result.as_deref(), Some("2"));
assert_eq!(sequence_fields[2].instruction, "SEQ Item");
assert_eq!(sequence_fields[2].result, "98");
assert_eq!(sequence_fields[2].computed_result.as_deref(), Some("3"));
let ref_fields = fields
.iter()
.filter(|field| field.kind == FieldKind::Ref)
.collect::<Vec<_>>();
assert_eq!(ref_fields.len(), 2);
assert_eq!(ref_fields[0].instruction, "REF SimpleSeq");
assert_eq!(ref_fields[0].result, "stale simple sequence ref");
assert_eq!(ref_fields[0].computed_result.as_deref(), Some("2"));
assert_eq!(ref_fields[1].instruction, "REF ComplexSeq");
assert_eq!(ref_fields[1].result, "stale complex sequence ref");
assert_eq!(ref_fields[1].computed_result.as_deref(), Some("3"));
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
let main_text = doc.main_text();
assert!(
main_text.contains("1\n2\n3\n2\n3")
&& !main_text.contains("99")
&& !main_text.contains("98")
&& !main_text.contains("stale simple sequence ref")
&& !main_text.contains("stale complex sequence ref"),
"REF targets should use computed nested SEQ field output, not stale cached text: {main_text:?}"
);
}
#[test]
fn docx_ref_targets_use_computed_nested_numbering_field_results() {
let doc = Document::open(&nested_numbering_field_ref_bookmark_docx()).expect("fixture opens");
let fields = doc.fields();
let numbering_fields = fields
.iter()
.filter(|field| field.kind == FieldKind::Numbering("AUTONUM".to_string()))
.collect::<Vec<_>>();
assert_eq!(numbering_fields.len(), 3);
assert_eq!(numbering_fields[0].instruction, "AUTONUM");
assert_eq!(numbering_fields[0].computed_result.as_deref(), Some("1"));
assert_eq!(numbering_fields[1].instruction, "AUTONUM");
assert_eq!(numbering_fields[1].result, "99");
assert_eq!(numbering_fields[1].computed_result.as_deref(), Some("2"));
assert_eq!(numbering_fields[2].instruction, "AUTONUM");
assert_eq!(numbering_fields[2].result, "98");
assert_eq!(numbering_fields[2].computed_result.as_deref(), Some("3"));
let ref_fields = fields
.iter()
.filter(|field| field.kind == FieldKind::Ref)
.collect::<Vec<_>>();
assert_eq!(ref_fields.len(), 2);
assert_eq!(ref_fields[0].instruction, "REF SimpleAuto");
assert_eq!(ref_fields[0].result, "stale simple autonum ref");
assert_eq!(ref_fields[0].computed_result.as_deref(), Some("2"));
assert_eq!(ref_fields[1].instruction, "REF ComplexAuto");
assert_eq!(ref_fields[1].result, "stale complex autonum ref");
assert_eq!(ref_fields[1].computed_result.as_deref(), Some("3"));
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
let main_text = doc.main_text();
assert!(
main_text.contains("1\n2\n3\n2\n3")
&& !main_text.contains("99")
&& !main_text.contains("98")
&& !main_text.contains("stale simple autonum ref")
&& !main_text.contains("stale complex autonum ref"),
"REF targets should use computed nested AUTONUM field output, not stale cached text: {main_text:?}"
);
}
#[test]
fn docx_ref_targets_use_computed_nested_listnum_field_results() {
let doc = Document::open(&nested_listnum_field_ref_bookmark_docx()).expect("fixture opens");
let fields = doc.fields();
let listnum_fields = fields
.iter()
.filter(|field| field.kind == FieldKind::Numbering("LISTNUM".to_string()))
.collect::<Vec<_>>();
assert_eq!(listnum_fields.len(), 3);
assert_eq!(listnum_fields[0].instruction, "LISTNUM NumberDefault");
assert_eq!(listnum_fields[0].computed_result.as_deref(), Some("1"));
assert_eq!(listnum_fields[1].instruction, "LISTNUM NumberDefault");
assert_eq!(listnum_fields[1].result, "99");
assert_eq!(listnum_fields[1].computed_result.as_deref(), Some("2"));
assert_eq!(listnum_fields[2].instruction, "LISTNUM NumberDefault");
assert_eq!(listnum_fields[2].result, "98");
assert_eq!(listnum_fields[2].computed_result.as_deref(), Some("3"));
let ref_fields = fields
.iter()
.filter(|field| field.kind == FieldKind::Ref)
.collect::<Vec<_>>();
assert_eq!(ref_fields.len(), 2);
assert_eq!(ref_fields[0].instruction, "REF SimpleList");
assert_eq!(ref_fields[0].result, "stale simple listnum ref");
assert_eq!(ref_fields[0].computed_result.as_deref(), Some("2"));
assert_eq!(ref_fields[1].instruction, "REF ComplexList");
assert_eq!(ref_fields[1].result, "stale complex listnum ref");
assert_eq!(ref_fields[1].computed_result.as_deref(), Some("3"));
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
let main_text = doc.main_text();
assert!(
main_text.contains("1\n2\n3\n2\n3")
&& !main_text.contains("99")
&& !main_text.contains("98")
&& !main_text.contains("stale simple listnum ref")
&& !main_text.contains("stale complex listnum ref"),
"REF targets should use computed nested LISTNUM field output, not stale cached text: {main_text:?}"
);
}
#[test]
fn docx_ref_targets_resolve_bookmark_operands_in_nested_field_results() {
let doc =
Document::open(&nested_bookmark_operand_field_ref_bookmark_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 2);
assert_eq!(fields[0].kind, FieldKind::Dynamic("=".to_string()));
assert_eq!(fields[0].instruction, "= InvoiceSubtotal + 8");
assert_eq!(fields[0].result, "stale nested formula");
assert_eq!(fields[0].computed_result.as_deref(), Some("48"));
assert_eq!(fields[1].kind, FieldKind::Ref);
assert_eq!(fields[1].instruction, "REF ComputedTotal");
assert_eq!(fields[1].result, "stale total ref");
assert_eq!(fields[1].computed_result.as_deref(), Some("48"));
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
let main_text = doc.main_text();
assert!(
main_text.contains("40")
&& main_text.contains("48")
&& !main_text.contains("stale nested formula")
&& !main_text.contains("stale total ref"),
"REF targets should compute nested field results with prior bookmark operands: {main_text:?}"
);
}
#[test]
fn docx_ref_targets_resolve_prior_set_operands_in_nested_field_results() {
let doc = Document::open(&nested_set_operand_field_ref_bookmark_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 3);
assert_eq!(fields[0].kind, FieldKind::Dynamic("SET".to_string()));
assert_eq!(fields[0].instruction, "SET ClientTotal 40");
assert_eq!(fields[0].result, "cached set total");
assert_eq!(fields[0].computed_result.as_deref(), Some(""));
assert_eq!(fields[1].kind, FieldKind::Dynamic("=".to_string()));
assert_eq!(fields[1].instruction, "= ClientTotal + 8");
assert_eq!(fields[1].result, "stale set nested formula");
assert_eq!(fields[1].computed_result.as_deref(), Some("48"));
assert_eq!(fields[2].kind, FieldKind::Ref);
assert_eq!(fields[2].instruction, "REF ComputedTotal");
assert_eq!(fields[2].result, "stale set total ref");
assert_eq!(fields[2].computed_result.as_deref(), Some("48"));
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
let main_text = doc.main_text();
assert!(
main_text.contains("48")
&& !main_text.contains("cached set total")
&& !main_text.contains("stale set nested formula")
&& !main_text.contains("stale set total ref"),
"REF targets should compute nested field results with prior SET operands: {main_text:?}"
);
}
#[test]
fn docx_ref_targets_resolve_prior_complex_set_operands_in_nested_field_results() {
let doc = Document::open(&nested_complex_set_operand_field_ref_bookmark_docx())
.expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 3);
assert_eq!(fields[0].kind, FieldKind::Dynamic("SET".to_string()));
assert_eq!(fields[0].instruction, "SET ClientTotal 40");
assert_eq!(fields[0].result, "cached complex set total");
assert_eq!(fields[0].computed_result.as_deref(), Some(""));
assert_eq!(fields[1].kind, FieldKind::Dynamic("=".to_string()));
assert_eq!(fields[1].instruction, "= ClientTotal + 8");
assert_eq!(fields[1].result, "stale complex set nested formula");
assert_eq!(fields[1].computed_result.as_deref(), Some("48"));
assert_eq!(fields[2].kind, FieldKind::Ref);
assert_eq!(fields[2].instruction, "REF ComputedTotal");
assert_eq!(fields[2].result, "stale complex set total ref");
assert_eq!(fields[2].computed_result.as_deref(), Some("48"));
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
let main_text = doc.main_text();
assert!(
main_text.contains("48")
&& !main_text.contains("cached complex set total")
&& !main_text.contains("stale complex set nested formula")
&& !main_text.contains("stale complex set total ref"),
"REF targets should compute nested field results with prior complex SET operands: {main_text:?}"
);
}
#[test]
fn docx_ref_targets_keep_known_field_names_cached() {
let doc = Document::open(&known_field_name_bookmark_ref_target_docx()).expect("fixture opens");
let fields = doc.fields();
let source = fields
.iter()
.find(|field| field.instruction == "PAGEREF")
.expect("known target field is recorded");
assert_eq!(source.kind, FieldKind::PageRef);
assert_eq!(source.result, "known field target");
let reference = fields
.iter()
.find(|field| field.instruction == "REF ComputedTarget")
.expect("REF field is recorded");
assert_eq!(reference.kind, FieldKind::Ref);
assert_eq!(reference.result, "stale known field target ref");
assert_eq!(
reference.computed_result.as_deref(),
Some("known field target")
);
let main_text = doc.main_text();
assert!(
main_text.contains("known field target")
&& !main_text.contains("stale known field target ref"),
"REF target text should keep known field cached text instead of bookmark text: {main_text:?}"
);
}
#[test]
fn docx_ref_targets_hide_toc_entry_marker_fields() {
let doc = Document::open(&toc_entry_marker_ref_target_docx()).expect("fixture opens");
let fields = doc.fields();
let marker = fields
.iter()
.find(|field| field.instruction == r#"TC "Hidden" \f m \l 1"#)
.expect("TC marker is recorded");
assert_eq!(marker.kind, FieldKind::TocEntry);
assert_eq!(marker.result, "stale tc marker");
assert_eq!(marker.computed_result.as_deref(), Some(""));
let reference = fields
.iter()
.find(|field| field.instruction == "REF ComputedTarget")
.expect("REF field is recorded");
assert_eq!(reference.kind, FieldKind::Ref);
assert_eq!(reference.result, "stale tc target ref");
assert_eq!(reference.computed_result.as_deref(), Some("Alpha Beta"));
let main_text = doc.main_text();
assert!(
main_text.contains("Alpha Beta")
&& !main_text.contains("stale tc marker")
&& !main_text.contains("stale tc target ref"),
"REF target text should hide TC marker fields instead of leaking cached marker text: {main_text:?}"
);
}
#[test]
fn docx_ref_targets_resolve_nested_ref_field_results() {
let doc = Document::open(&nested_ref_field_ref_bookmark_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 4);
assert_eq!(fields[0].kind, FieldKind::Ref);
assert_eq!(fields[0].instruction, "REF BaseText \\* Upper");
assert_eq!(fields[0].result, "stale nested explicit ref");
assert_eq!(fields[0].computed_result.as_deref(), Some("CURRENT BASE"));
assert_eq!(fields[1].kind, FieldKind::Ref);
assert_eq!(fields[1].instruction, "BaseText \\* FirstCap");
assert_eq!(fields[1].result, "stale nested direct ref");
assert_eq!(fields[1].computed_result.as_deref(), Some("Current base"));
assert_eq!(fields[2].kind, FieldKind::Ref);
assert_eq!(fields[2].instruction, "REF ComputedExplicit");
assert_eq!(fields[2].result, "stale outer explicit ref");
assert_eq!(fields[2].computed_result.as_deref(), Some("CURRENT BASE"));
assert_eq!(fields[3].kind, FieldKind::Ref);
assert_eq!(fields[3].instruction, "REF ComputedDirect");
assert_eq!(fields[3].result, "stale outer direct ref");
assert_eq!(fields[3].computed_result.as_deref(), Some("Current base"));
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
let main_text = doc.main_text();
assert!(
main_text.contains("current base")
&& main_text.contains("CURRENT BASE")
&& main_text.contains("Current base")
&& !main_text.contains("stale nested explicit ref")
&& !main_text.contains("stale nested direct ref")
&& !main_text.contains("stale outer explicit ref")
&& !main_text.contains("stale outer direct ref"),
"REF targets should compute nested REF/direct bookmark fields: {main_text:?}"
);
}
#[test]
fn docx_ref_targets_ignore_deleted_bookmark_text() {
let doc = Document::open(&ref_deleted_bookmark_text_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 1);
assert_eq!(fields[0].kind, FieldKind::Ref);
assert_eq!(fields[0].instruction, "REF ClauseText");
assert_eq!(fields[0].computed_result.as_deref(), Some("Visible clause"));
let main_text = doc.main_text();
assert!(
main_text.contains("Visible clause")
&& !main_text.contains("deleted clause")
&& !main_text.contains("moved clause")
&& !main_text.contains("stale deleted ref"),
"computed REF bookmark text must follow accepted-current wrappers: {main_text:?}"
);
}
#[test]
fn docx_ref_targets_use_single_alternate_content_branch() {
let doc = Document::open(&ref_alternate_content_bookmark_text_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 1);
assert_eq!(fields[0].kind, FieldKind::Ref);
assert_eq!(fields[0].instruction, "REF AltText");
assert_eq!(fields[0].computed_result.as_deref(), Some("Choice clause"));
let main_text = doc.main_text();
assert!(
main_text.contains("Choice clause")
&& !main_text.contains("Fallback clause")
&& !main_text.contains("stale alternate ref"),
"computed REF bookmark text must use one AlternateContent branch: {main_text:?}"
);
}
#[test]
fn docx_complex_ref_field_displays_computed_bookmark_text() {
let doc = Document::open(&complex_ref_bookmark_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 1);
assert_eq!(fields[0].kind, FieldKind::Ref);
assert_eq!(fields[0].instruction, "REF Figure1");
assert_eq!(fields[0].result, "stale complex ref");
assert_eq!(fields[0].computed_result.as_deref(), Some("Figure 1"));
let main_text = doc.main_text();
assert!(
!main_text.contains("stale complex ref"),
"resolved complex REF fields should display computed bookmark text in the read model: {main_text:?}"
);
assert!(main_text.contains("Figure 1"), "{main_text:?}");
}
#[test]
fn docx_complex_direct_bookmark_field_displays_computed_bookmark_text() {
let doc = Document::open(&complex_direct_bookmark_ref_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 1);
assert_eq!(fields[0].kind, FieldKind::Ref);
assert_eq!(fields[0].instruction, "Figure1 \\* Upper");
assert_eq!(fields[0].result, "stale complex direct ref");
assert_eq!(fields[0].computed_result.as_deref(), Some("FIGURE ONE"));
let main_text = doc.main_text();
assert!(
!main_text.contains("stale complex direct ref"),
"resolved complex direct bookmark field should display computed bookmark text: {main_text:?}"
);
assert!(main_text.contains("FIGURE ONE"), "{main_text:?}");
}
#[test]
fn docx_ref_field_preserves_paragraph_breaks_in_bookmark_text() {
let doc = Document::open(&multi_paragraph_ref_bookmark_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 1);
assert_eq!(fields[0].kind, FieldKind::Ref);
assert_eq!(fields[0].instruction, "REF ClauseText");
assert_eq!(fields[0].result, "stale multi ref");
assert_eq!(
fields[0].computed_result.as_deref(),
Some("First paragraph.\nSecond paragraph.")
);
let main_text = doc.main_text();
assert!(
!main_text.contains("stale multi ref"),
"resolved multi-paragraph REF fields should display computed bookmark text in the read model: {main_text:?}"
);
assert!(
main_text.contains("First paragraph.\nSecond paragraph."),
"{main_text:?}"
);
}
#[test]
fn docx_ref_field_preserves_inline_tabs_and_breaks_in_bookmark_text() {
let doc = Document::open(&inline_break_ref_bookmark_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 1);
assert_eq!(fields[0].kind, FieldKind::Ref);
assert_eq!(fields[0].instruction, "REF InlineText");
assert_eq!(fields[0].result, "stale inline ref");
assert_eq!(
fields[0].computed_result.as_deref(),
Some("Alpha\tBeta\nGamma-Delta")
);
let main_text = doc.main_text();
assert!(
!main_text.contains("stale inline ref"),
"resolved inline-break REF fields should display computed bookmark text in the read model: {main_text:?}"
);
assert!(
main_text.contains("Alpha\tBeta\nGamma-Delta"),
"{main_text:?}"
);
}
#[test]
fn docx_ref_field_preserves_supported_symbols_in_bookmark_text() {
let doc = Document::open(&symbol_ref_bookmark_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 1);
assert_eq!(fields[0].kind, FieldKind::Ref);
assert_eq!(fields[0].instruction, "REF SymbolText");
assert_eq!(fields[0].result, "stale symbol ref");
assert_eq!(fields[0].computed_result.as_deref(), Some("Alpha • Beta"));
let main_text = doc.main_text();
assert!(
!main_text.contains("stale symbol ref"),
"resolved symbol REF fields should display computed bookmark text in the read model: {main_text:?}"
);
assert!(main_text.contains("Alpha • Beta"), "{main_text:?}");
}
#[test]
fn docx_ref_field_computes_hidden_word_bookmark_text() {
let doc = Document::open(&hidden_ref_bookmark_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 1);
assert_eq!(fields[0].kind, FieldKind::Ref);
assert_eq!(fields[0].instruction, "REF _Ref123456789");
assert_eq!(fields[0].result, "stale hidden ref");
assert_eq!(fields[0].computed_result.as_deref(), Some("Table 2"));
let main_text = doc.main_text();
assert!(
!main_text.contains("stale hidden ref"),
"resolved hidden-bookmark REF fields should display computed bookmark text in the read model: {main_text:?}"
);
assert!(main_text.contains("Table 2"), "{main_text:?}");
}
#[test]
fn docx_direct_bookmark_field_is_treated_as_ref_when_bookmark_exists() {
let doc = Document::open(&direct_bookmark_ref_field_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 1);
assert_eq!(fields[0].kind, FieldKind::Ref);
assert_eq!(fields[0].instruction, "Figure1");
assert_eq!(fields[0].result, "stale direct ref");
assert_eq!(fields[0].computed_result.as_deref(), Some("Figure 1"));
let main_text = doc.main_text();
assert!(
!main_text.contains("stale direct ref"),
"direct bookmark fields should display computed bookmark text in the read model: {main_text:?}"
);
assert!(main_text.contains("Figure 1"), "{main_text:?}");
}
#[test]
fn docx_known_field_names_are_not_computed_as_direct_bookmarks() {
let doc =
Document::open(&known_field_name_direct_bookmark_collision_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 1);
assert_eq!(fields[0].kind, FieldKind::PageRef);
assert_eq!(fields[0].instruction, "PAGEREF");
assert_eq!(fields[0].result, "cached known page ref");
assert_eq!(fields[0].computed_result, None);
let main_text = doc.main_text();
assert!(
main_text.contains("cached known page ref"),
"known field cached text should not be replaced by same-named bookmark text: {main_text:?}"
);
}
#[test]
fn docx_direct_bookmark_field_applies_supported_ref_switches() {
let doc = Document::open(&direct_bookmark_ref_switch_field_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 5);
assert_eq!(fields[0].kind, FieldKind::Ref);
assert_eq!(fields[0].instruction, "Figure1 \\* Upper");
assert_eq!(fields[0].result, "stale direct upper");
assert_eq!(fields[0].computed_result.as_deref(), Some("FIGURE ONE"));
assert_eq!(fields[1].kind, FieldKind::Ref);
assert_eq!(fields[1].instruction, "Figure1 \\*FirstCap");
assert_eq!(fields[1].result, "stale direct first-cap");
assert_eq!(fields[1].computed_result.as_deref(), Some("Figure one"));
assert_eq!(fields[2].kind, FieldKind::Ref);
assert_eq!(fields[2].instruction, "Figure1 \\h");
assert_eq!(fields[2].result, "stale direct hyperlink");
assert_eq!(fields[2].computed_result.as_deref(), Some("figure one"));
assert_eq!(fields[3].kind, FieldKind::Ref);
assert_eq!(fields[3].instruction, "Figure1 \\d \"-\"");
assert_eq!(fields[3].result, "direct sequence separator");
assert_eq!(fields[3].computed_result.as_deref(), Some("figure one"));
assert_eq!(fields[4].kind, FieldKind::Ref);
assert_eq!(fields[4].instruction, "Figure1 \\f");
assert_eq!(fields[4].result, "direct note mark");
assert_eq!(fields[4].computed_result, None);
assert_eq!(
model_simple_field_reason_hints(&doc, |instruction| instruction.starts_with("Figure1 \\")),
vec![(
"Figure1 \\f".to_string(),
Some(FieldUnsupportedReason::NoComputedResult),
)]
);
let main_text = doc.main_text();
assert!(
!main_text.contains("stale direct upper")
&& !main_text.contains("stale direct first-cap")
&& !main_text.contains("stale direct hyperlink")
&& !main_text.contains("direct sequence separator")
&& main_text.contains("direct note mark"),
"direct bookmark fields with supported REF switches should display computed bookmark text: {main_text:?}"
);
assert!(main_text.contains("FIGURE ONE"), "{main_text:?}");
assert!(main_text.contains("Figure one"), "{main_text:?}");
assert!(main_text.contains("figure one"), "{main_text:?}");
}
#[test]
fn docx_ref_fields_apply_number_formats_to_plain_and_direct_bookmarks() {
let doc = Document::open(&bookmark_ref_number_format_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 3);
assert!(fields.iter().all(|field| field.kind == FieldKind::Ref));
assert_eq!(fields[0].instruction, "REF InvoiceTotal \\* CardText");
assert_eq!(fields[0].result, "stale cardtext ref");
assert_eq!(fields[0].computed_result.as_deref(), Some("twenty-one"));
assert_eq!(fields[1].instruction, "InvoiceTotal \\* Ordinal");
assert_eq!(fields[1].result, "stale direct ordinal");
assert_eq!(fields[1].computed_result.as_deref(), Some("21st"));
assert_eq!(fields[2].instruction, "InvoiceTotal \\* CardText \\* Upper");
assert_eq!(fields[2].result, "stale direct uppercase cardtext");
assert_eq!(fields[2].computed_result.as_deref(), Some("TWENTY-ONE"));
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
let main_text = doc.main_text();
assert!(
main_text.contains("twenty-one")
&& main_text.contains("21st")
&& main_text.contains("TWENTY-ONE")
&& !main_text.contains("stale cardtext ref")
&& !main_text.contains("stale direct ordinal")
&& !main_text.contains("stale direct uppercase cardtext"),
"computed numeric bookmark REF formats should replace stale cached text: {main_text:?}"
);
}
#[test]
fn docx_direct_bookmark_p_field_computes_relative_source_position() {
let doc = Document::open(&direct_relative_ref_switch_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 2);
assert_eq!(fields[0].kind, FieldKind::Ref);
assert_eq!(fields[0].instruction, "LaterBookmark \\p");
assert_eq!(fields[0].result, "stale direct below");
assert_eq!(fields[0].computed_result.as_deref(), Some("below"));
assert_eq!(fields[1].kind, FieldKind::Ref);
assert_eq!(fields[1].instruction, "Figure1 \\p");
assert_eq!(fields[1].result, "stale direct above");
assert_eq!(fields[1].computed_result.as_deref(), Some("above"));
let main_text = doc.main_text();
assert!(
!main_text.contains("stale direct below") && !main_text.contains("stale direct above"),
"direct bookmark \\p fields should display computed source-order relative text: {main_text:?}"
);
assert!(main_text.contains("below"), "{main_text:?}");
assert!(main_text.contains("above"), "{main_text:?}");
}
#[test]
fn docx_ref_field_applies_upper_lower_format_switches() {
let doc = Document::open(&ref_text_format_switch_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 5);
assert_eq!(fields[0].kind, FieldKind::Ref);
assert_eq!(fields[0].instruction, "REF Figure1 \\* Upper");
assert_eq!(fields[0].result, "stale upper ref");
assert_eq!(fields[0].computed_result.as_deref(), Some("FIGURE ONE"));
assert_eq!(fields[1].kind, FieldKind::Ref);
assert_eq!(fields[1].instruction, "REF Figure1 \\*Lower");
assert_eq!(fields[1].result, "stale lower ref");
assert_eq!(fields[1].computed_result.as_deref(), Some("figure one"));
assert_eq!(fields[2].kind, FieldKind::Ref);
assert_eq!(fields[2].instruction, "REF Figure1 \\* Caps");
assert_eq!(fields[2].result, "stale caps ref");
assert_eq!(fields[2].computed_result.as_deref(), Some("Figure One"));
assert_eq!(fields[3].kind, FieldKind::Ref);
assert_eq!(fields[3].instruction, "REF Figure1 \\*FirstCap");
assert_eq!(fields[3].result, "stale first-cap ref");
assert_eq!(fields[3].computed_result.as_deref(), Some("Figure one"));
assert_eq!(fields[4].kind, FieldKind::Ref);
assert_eq!(fields[4].instruction, "REF Figure1 \\* MERGEFORMATINET");
assert_eq!(fields[4].result, "stale web-format ref");
assert_eq!(fields[4].computed_result.as_deref(), Some("figure one"));
let main_text = doc.main_text();
assert!(
!main_text.contains("stale upper ref")
&& !main_text.contains("stale lower ref")
&& !main_text.contains("stale caps ref")
&& !main_text.contains("stale first-cap ref")
&& !main_text.contains("stale web-format ref"),
"resolved REF format switches should display computed bookmark text in the read model: {main_text:?}"
);
assert!(main_text.contains("FIGURE ONE"), "{main_text:?}");
assert!(main_text.contains("figure one"), "{main_text:?}");
assert!(main_text.contains("Figure One"), "{main_text:?}");
assert!(main_text.contains("Figure one"), "{main_text:?}");
}
#[test]
fn docx_ref_field_with_broader_switch_keeps_cached_text() {
let doc = Document::open(&broader_ref_switch_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 1);
assert_eq!(fields[0].kind, FieldKind::Ref);
assert_eq!(fields[0].instruction, "REF Figure1 \\f");
assert_eq!(fields[0].result, "note mark");
assert_eq!(fields[0].computed_result, None);
let main_text = doc.main_text();
assert!(
main_text.contains("note mark"),
"broader REF switch fields should keep cached result text in the read model: {main_text:?}"
);
}
#[test]
fn docx_ref_gap_cases_compute_text_neutral_separator_and_keep_other_cached_text() {
let doc = Document::open(&ref_gap_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 3);
assert!(fields.iter().all(|field| field.kind == FieldKind::Ref));
assert_eq!(fields[0].instruction, "REF PlainText \\f");
assert_eq!(fields[0].result, "cached non-note ref mark");
assert_eq!(fields[0].computed_result, None);
assert_eq!(fields[1].instruction, "REF PlainText \\d-");
assert_eq!(fields[1].result, "cached ref separator");
assert_eq!(fields[1].computed_result.as_deref(), Some("Plain target"));
assert_eq!(fields[2].instruction, "REF MissingRef");
assert_eq!(fields[2].result, "cached missing ref");
assert_eq!(fields[2].computed_result, None);
let report = doc.report();
assert_eq!(
report.features.unsupported_field_kinds,
vec![FieldKindCount {
kind: FieldKind::Ref,
count: 2,
}]
);
assert_eq!(
report.features.unsupported_field_reasons,
vec![
FieldEvaluationReasonCount {
reason: FieldEvaluationReason::NoComputedResult,
count: 1,
},
FieldEvaluationReasonCount {
reason: FieldEvaluationReason::UnresolvedBookmark,
count: 1,
},
]
);
assert_eq!(
model_simple_field_reason_hints(&doc, |instruction| instruction.starts_with("REF ")),
vec![
(
"REF PlainText \\f".to_string(),
Some(FieldUnsupportedReason::NoComputedResult),
),
(
"REF MissingRef".to_string(),
Some(FieldUnsupportedReason::UnresolvedBookmark),
),
]
);
let main_text = doc.main_text();
assert!(
main_text.contains("cached non-note ref mark")
&& !main_text.contains("cached ref separator")
&& main_text.contains("Plain target")
&& main_text.contains("cached missing ref"),
"text-neutral REF \\d should compute while remaining REF gaps preserve cached text: {main_text:?}"
);
}
#[test]
fn docx_note_ref_field_computes_bookmarked_note_marks_and_relative_position() {
let doc = Document::open(¬e_ref_field_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 10);
assert!(fields.iter().all(|field| field.kind == FieldKind::NoteRef));
assert_eq!(fields[0].instruction, "NOTEREF LaterNote \\p");
assert_eq!(fields[0].result, "stale below note");
assert_eq!(fields[0].computed_result.as_deref(), Some("below"));
assert_eq!(fields[1].instruction, "NOTEREF LaterNote \\p \\* Upper");
assert_eq!(fields[1].result, "stale uppercase below note");
assert_eq!(fields[1].computed_result.as_deref(), Some("BELOW"));
assert_eq!(fields[2].instruction, "NOTEREF FootOne \\h");
assert_eq!(fields[2].computed_result.as_deref(), Some("1"));
assert_eq!(fields[3].instruction, "FTNREF FootOne");
assert_eq!(fields[3].computed_result.as_deref(), Some("1"));
assert_eq!(fields[4].instruction, "NOTEREF FootOne \\f \\* MERGEFORMAT");
assert_eq!(fields[4].computed_result.as_deref(), Some("1"));
assert_eq!(fields[5].instruction, "NOTEREF FootOne \\h\\f");
assert_eq!(fields[5].computed_result.as_deref(), Some("1"));
assert_eq!(fields[6].instruction, "NOTEREF FootOne \\p");
assert_eq!(fields[6].computed_result.as_deref(), Some("above"));
assert_eq!(fields[7].instruction, "NOTEREF EndOne");
assert_eq!(fields[7].computed_result.as_deref(), Some("1"));
assert_eq!(fields[8].instruction, "NOTEREF LaterNote");
assert_eq!(fields[8].result, "stale complex note mark");
assert_eq!(fields[8].computed_result.as_deref(), Some("2"));
assert_eq!(fields[9].instruction, "NOTEREF MissingNote");
assert_eq!(fields[9].computed_result, None);
let report = doc.report();
assert_eq!(
report.features.unsupported_field_kinds,
vec![FieldKindCount {
kind: FieldKind::NoteRef,
count: 1,
}]
);
assert_eq!(
report.features.unsupported_field_reasons,
vec![FieldEvaluationReasonCount {
reason: FieldEvaluationReason::UnresolvedBookmark,
count: 1,
}]
);
let main_text = doc.main_text();
assert!(
!main_text.contains("stale below note")
&& !main_text.contains("stale uppercase below note")
&& !main_text.contains("stale note mark")
&& !main_text.contains("stale legacy note mark")
&& !main_text.contains("stale formatted note mark")
&& !main_text.contains("stale compact note mark")
&& !main_text.contains("stale above note")
&& !main_text.contains("stale endnote mark")
&& !main_text.contains("stale complex note mark"),
"resolved NOTEREF fields should display computed note text: {main_text:?}"
);
assert!(main_text.contains("below"), "{main_text:?}");
assert!(main_text.contains("BELOW"), "{main_text:?}");
assert!(main_text.contains("above"), "{main_text:?}");
assert!(main_text.contains("stale missing note"), "{main_text:?}");
}
#[test]
fn docx_note_ref_gap_cases_keep_cached_text() {
let doc = Document::open(¬e_ref_gap_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 3);
assert!(fields.iter().all(|field| field.kind == FieldKind::NoteRef));
assert_eq!(fields[0].instruction, "NOTEREF PlainText");
assert_eq!(fields[0].result, "cached plain note ref");
assert_eq!(fields[0].computed_result, None);
assert_eq!(fields[1].instruction, "NOTEREF MissingNote");
assert_eq!(fields[1].result, "cached missing note ref");
assert_eq!(fields[1].computed_result, None);
assert_eq!(fields[2].instruction, "NOTEREF PlainText \\x");
assert_eq!(fields[2].result, "cached bad note ref switch");
assert_eq!(fields[2].computed_result, None);
let report = doc.report();
assert_eq!(
report.features.unsupported_field_kinds,
vec![FieldKindCount {
kind: FieldKind::NoteRef,
count: 3,
}]
);
assert_eq!(
report.features.unsupported_field_reasons,
vec![
FieldEvaluationReasonCount {
reason: FieldEvaluationReason::NoComputedResult,
count: 1,
},
FieldEvaluationReasonCount {
reason: FieldEvaluationReason::UnresolvedBookmark,
count: 1,
},
FieldEvaluationReasonCount {
reason: FieldEvaluationReason::UnsupportedSwitch,
count: 1,
},
]
);
assert_eq!(
model_simple_field_reason_hints(&doc, |instruction| instruction.starts_with("NOTEREF")),
vec![
(
"NOTEREF PlainText".to_string(),
Some(FieldUnsupportedReason::NoComputedResult),
),
(
"NOTEREF MissingNote".to_string(),
Some(FieldUnsupportedReason::UnresolvedBookmark),
),
(
"NOTEREF PlainText \\x".to_string(),
Some(FieldUnsupportedReason::UnsupportedSwitch),
),
]
);
let main_text = doc.main_text();
assert!(
main_text.contains("cached plain note ref")
&& main_text.contains("cached missing note ref")
&& main_text.contains("cached bad note ref switch"),
"NOTEREF gap cases should preserve cached result text: {main_text:?}"
);
}
#[test]
fn docx_note_ref_ignores_stale_note_mark_inside_computed_field_result() {
let doc =
Document::open(¬e_ref_stale_computed_field_result_marker_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 2);
assert_eq!(fields[0].kind, FieldKind::Dynamic("QUOTE".to_string()));
assert_eq!(fields[0].instruction, r#"QUOTE "Plain text""#);
assert_eq!(fields[0].computed_result.as_deref(), Some("Plain text"));
assert_eq!(fields[1].kind, FieldKind::NoteRef);
assert_eq!(fields[1].instruction, "NOTEREF ComputedNote");
assert_eq!(fields[1].result, "cached stale note ref");
assert_eq!(fields[1].computed_result, None);
let report = doc.report();
assert_eq!(
report.features.unsupported_field_kinds,
vec![FieldKindCount {
kind: FieldKind::NoteRef,
count: 1,
}]
);
assert_eq!(
report.features.unsupported_field_reasons,
vec![FieldEvaluationReasonCount {
reason: FieldEvaluationReason::NoComputedResult,
count: 1,
}]
);
assert_eq!(
model_simple_field_reason_hints(&doc, |instruction| instruction.starts_with("NOTEREF")),
vec![(
"NOTEREF ComputedNote".to_string(),
Some(FieldUnsupportedReason::NoComputedResult),
)]
);
let main_text = doc.main_text();
assert!(
main_text.contains("Plain text")
&& main_text.contains("cached stale note ref")
&& !main_text.contains('1'),
"NOTEREF should not resolve a note mark hidden inside a computed field result: {main_text:?}"
);
}
#[test]
fn docx_note_ref_uses_empty_document_info_result_for_marker_scan() {
let doc =
Document::open(¬e_ref_empty_document_info_result_marker_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 2);
assert_eq!(fields[0].kind, FieldKind::DocumentInfo("TITLE".to_string()));
assert_eq!(fields[0].instruction, "TITLE");
assert_eq!(fields[0].result, "stale note title");
assert_eq!(fields[0].computed_result.as_deref(), Some(""));
assert_eq!(fields[1].kind, FieldKind::NoteRef);
assert_eq!(fields[1].instruction, "NOTEREF ComputedNote");
assert_eq!(fields[1].result, "cached stale document-info note ref");
assert_eq!(fields[1].computed_result, None);
let report = doc.report();
assert_eq!(
report.features.unsupported_field_kinds,
vec![FieldKindCount {
kind: FieldKind::NoteRef,
count: 1,
}]
);
assert_eq!(
report.features.unsupported_field_reasons,
vec![FieldEvaluationReasonCount {
reason: FieldEvaluationReason::NoComputedResult,
count: 1,
}]
);
let main_text = doc.main_text();
assert!(
main_text.contains("cached stale document-info note ref")
&& !main_text.contains("stale note title")
&& !main_text.contains('1'),
"NOTEREF should not resolve a note mark hidden inside a computed document-info result: {main_text:?}"
);
}
#[test]
fn docx_note_ref_ignores_stale_note_mark_inside_computed_ref_result() {
let doc = Document::open(¬e_ref_stale_ref_result_marker_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 2);
assert_eq!(fields[0].kind, FieldKind::Ref);
assert_eq!(fields[0].instruction, "REF EmptyTarget");
assert_eq!(fields[0].computed_result.as_deref(), Some(""));
assert_eq!(fields[1].kind, FieldKind::NoteRef);
assert_eq!(fields[1].instruction, "NOTEREF ComputedNote");
assert_eq!(fields[1].result, "cached stale ref note ref");
assert_eq!(fields[1].computed_result, None);
let report = doc.report();
assert_eq!(
report.features.unsupported_field_kinds,
vec![FieldKindCount {
kind: FieldKind::NoteRef,
count: 1,
}]
);
assert_eq!(
report.features.unsupported_field_reasons,
vec![FieldEvaluationReasonCount {
reason: FieldEvaluationReason::NoComputedResult,
count: 1,
}]
);
let main_text = doc.main_text();
assert!(
main_text.contains("cached stale ref note ref")
&& !main_text.contains('\u{0002}')
&& !main_text.contains('1'),
"NOTEREF should not resolve a note mark hidden inside a computed REF result: {main_text:?}"
);
}
#[test]
fn docx_note_ref_ignores_stale_note_mark_inside_computed_direct_bookmark_result() {
let doc = Document::open(¬e_ref_stale_direct_bookmark_result_marker_docx())
.expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 2);
assert_eq!(fields[0].kind, FieldKind::Ref);
assert_eq!(fields[0].instruction, "EmptyTarget");
assert_eq!(fields[0].computed_result.as_deref(), Some(""));
assert_eq!(fields[1].kind, FieldKind::NoteRef);
assert_eq!(fields[1].instruction, "NOTEREF ComputedNote");
assert_eq!(fields[1].result, "cached stale direct note ref");
assert_eq!(fields[1].computed_result, None);
let report = doc.report();
assert_eq!(
report.features.unsupported_field_kinds,
vec![FieldKindCount {
kind: FieldKind::NoteRef,
count: 1,
}]
);
assert_eq!(
report.features.unsupported_field_reasons,
vec![FieldEvaluationReasonCount {
reason: FieldEvaluationReason::NoComputedResult,
count: 1,
}]
);
let main_text = doc.main_text();
assert!(
main_text.contains("cached stale direct note ref")
&& !main_text.contains('\u{0002}')
&& !main_text.contains('1'),
"NOTEREF should not resolve a note mark hidden inside a computed direct bookmark result: {main_text:?}"
);
}
#[test]
fn docx_note_ref_ignores_stale_note_mark_inside_computed_complex_field_result() {
let doc = Document::open(¬e_ref_stale_complex_computed_field_result_marker_docx())
.expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 2);
assert_eq!(fields[0].kind, FieldKind::Dynamic("QUOTE".to_string()));
assert_eq!(fields[0].instruction, r#"QUOTE "Plain text""#);
assert_eq!(fields[0].computed_result.as_deref(), Some("Plain text"));
assert_eq!(fields[1].kind, FieldKind::NoteRef);
assert_eq!(fields[1].instruction, "NOTEREF ComputedNote");
assert_eq!(fields[1].result, "cached stale complex note ref");
assert_eq!(fields[1].computed_result, None);
let report = doc.report();
assert_eq!(
report.features.unsupported_field_kinds,
vec![FieldKindCount {
kind: FieldKind::NoteRef,
count: 1,
}]
);
assert_eq!(
report.features.unsupported_field_reasons,
vec![FieldEvaluationReasonCount {
reason: FieldEvaluationReason::NoComputedResult,
count: 1,
}]
);
assert_eq!(
model_simple_field_reason_hints(&doc, |instruction| instruction.starts_with("NOTEREF")),
vec![(
"NOTEREF ComputedNote".to_string(),
Some(FieldUnsupportedReason::NoComputedResult),
)]
);
let main_text = doc.main_text();
assert!(
main_text.contains("Plain text")
&& main_text.contains("cached stale complex note ref")
&& !main_text.contains('1'),
"NOTEREF should not resolve a note mark hidden inside a computed complex field result: {main_text:?}"
);
}
#[test]
fn docx_note_ref_context_uses_single_alternate_content_branch() {
let doc = Document::open(¬e_ref_alternate_content_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 2);
assert!(fields.iter().all(|field| field.kind == FieldKind::NoteRef));
assert_eq!(fields[0].instruction, "NOTEREF FootOne");
assert_eq!(fields[0].computed_result.as_deref(), Some("1"));
assert_eq!(fields[1].instruction, "NOTEREF FootOne \\p");
assert_eq!(fields[1].computed_result.as_deref(), Some("above"));
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
let main_text = doc.main_text();
assert!(main_text.contains("1"), "{main_text:?}");
assert!(main_text.contains("above"), "{main_text:?}");
assert!(!main_text.contains("stale alternate"), "{main_text:?}");
}
#[test]
fn docx_note_ref_applies_number_format_switches() {
let doc = Document::open(¬e_ref_number_format_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 2);
assert!(fields.iter().all(|field| field.kind == FieldKind::NoteRef));
assert_eq!(fields[0].instruction, "NOTEREF LaterNote \\* roman");
assert_eq!(fields[0].computed_result.as_deref(), Some("ii"));
assert_eq!(
fields[1].instruction,
"NOTEREF FootOne \\* OrdText \\* Upper"
);
assert_eq!(fields[1].computed_result.as_deref(), Some("FIRST"));
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
let main_text = doc.main_text();
assert!(main_text.contains("ii"), "{main_text:?}");
assert!(main_text.contains("FIRST"), "{main_text:?}");
assert!(!main_text.contains("stale roman note"), "{main_text:?}");
assert!(!main_text.contains("stale ordinal note"), "{main_text:?}");
}
#[test]
fn docx_note_body_fields_are_exposed() {
let doc = Document::open(¬e_body_field_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 2);
assert_eq!(fields[0].kind, FieldKind::Filename);
assert_eq!(fields[0].instruction, "FILENAME \\p");
assert_eq!(fields[0].result, "note.docx");
assert_eq!(fields[1].kind, FieldKind::Page);
assert_eq!(fields[1].instruction, "PAGE");
assert_eq!(fields[1].result, "4");
assert_eq!(doc.footnote_text(), "note.docx");
assert_eq!(doc.endnote_text(), "4");
}
#[test]
fn docx_ref_f_field_computes_bookmarked_note_reference_marks() {
let doc = Document::open(&ref_note_switch_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 5);
assert!(fields.iter().all(|field| field.kind == FieldKind::Ref));
assert_eq!(fields[0].instruction, "REF FootOne \\f");
assert_eq!(fields[0].result, "stale foot ref mark");
assert_eq!(fields[0].computed_result.as_deref(), Some("3"));
assert_eq!(fields[1].instruction, "FootOne \\f");
assert_eq!(fields[1].result, "stale direct foot ref mark");
assert_eq!(fields[1].computed_result.as_deref(), Some("4"));
assert_eq!(fields[2].instruction, "REF EndOne \\h \\f \\* MERGEFORMAT");
assert_eq!(fields[2].result, "stale end ref mark");
assert_eq!(fields[2].computed_result.as_deref(), Some("2"));
assert_eq!(fields[3].instruction, "REF FootOne \\f");
assert_eq!(fields[3].result, "stale complex foot ref mark");
assert_eq!(fields[3].computed_result.as_deref(), Some("5"));
assert_eq!(fields[4].instruction, "REF FootOne \\f \\* roman");
assert_eq!(fields[4].result, "stale roman foot ref mark");
assert_eq!(fields[4].computed_result.as_deref(), Some("vi"));
let main_text = doc.main_text();
assert!(
!main_text.contains("stale foot ref mark")
&& !main_text.contains("stale direct foot ref mark")
&& !main_text.contains("stale end ref mark")
&& !main_text.contains("stale complex foot ref mark")
&& !main_text.contains("stale roman foot ref mark"),
"resolved REF \\f fields should display computed note reference marks: {main_text:?}"
);
}
#[test]
fn docx_ref_f_field_computes_bookmarked_comment_reference_marks() {
let doc = Document::open(&ref_comment_reference_mark_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 2);
assert!(fields.iter().all(|field| field.kind == FieldKind::Ref));
assert_eq!(fields[0].instruction, "REF CommentOne \\f");
assert_eq!(fields[0].result, "stale comment one");
assert_eq!(fields[0].computed_result.as_deref(), Some("3"));
assert_eq!(fields[1].instruction, "CommentTwo \\f \\* ROMAN");
assert_eq!(fields[1].result, "stale comment two");
assert_eq!(fields[1].computed_result.as_deref(), Some("IV"));
let main_text = doc.main_text();
assert!(
!main_text.contains("stale comment one") && !main_text.contains("stale comment two"),
"resolved REF \\f comment markers should replace stale cached text: {main_text:?}"
);
}
#[test]
fn docx_ref_f_field_computes_bookmarked_comment_range_reference_marks() {
let doc = Document::open(&ref_comment_range_reference_mark_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 1);
assert_eq!(fields[0].kind, FieldKind::Ref);
assert_eq!(fields[0].instruction, "REF CommentedRange \\f");
assert_eq!(fields[0].result, "stale range comment");
assert_eq!(fields[0].computed_result.as_deref(), Some("2"));
let main_text = doc.main_text();
assert!(
main_text.contains("2") && !main_text.contains("stale range comment"),
"resolved REF \\f comment-range targets should replace stale cached text: {main_text:?}"
);
}
#[test]
fn docx_ref_f_field_computes_bookmarks_inside_comment_ranges() {
let doc =
Document::open(&ref_inside_comment_range_reference_mark_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 1);
assert_eq!(fields[0].kind, FieldKind::Ref);
assert_eq!(fields[0].instruction, "REF InsideComment \\f");
assert_eq!(fields[0].result, "stale inside comment");
assert_eq!(fields[0].computed_result.as_deref(), Some("2"));
let main_text = doc.main_text();
assert!(
main_text.contains("2") && !main_text.contains("stale inside comment"),
"resolved REF \\f inside-comment targets should replace stale cached text: {main_text:?}"
);
}
#[cfg(feature = "render")]
#[test]
fn docx_ref_f_computed_note_and_comment_marks_are_not_model_render_warnings() {
for fixture in [
ref_note_switch_docx(),
ref_comment_reference_mark_docx(),
ref_comment_range_reference_mark_docx(),
ref_inside_comment_range_reference_mark_docx(),
] {
let doc = Document::open(&fixture).expect("fixture opens");
assert!(doc
.fields()
.iter()
.all(|field| field.kind == FieldKind::Ref && field.computed_result.is_some()));
let rendered = rwml::render_pdf_with_report(&doc.model());
assert_eq!(rendered.report.unsupported.fields, 0);
assert!(rendered.report.unsupported.field_kinds.is_empty());
assert!(rendered
.report
.unsupported
.unsupported_field_reasons
.is_empty());
}
}
#[test]
fn docx_ref_n_field_computes_numbered_bookmark_paragraph() {
let doc = Document::open(&numbered_ref_switch_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 5);
assert!(fields.iter().all(|field| field.kind == FieldKind::Ref));
assert_eq!(fields[0].instruction, "REF Clause \\n");
assert_eq!(fields[0].result, "stale number");
assert_eq!(fields[0].computed_result.as_deref(), Some("3"));
assert_eq!(fields[1].instruction, "REF Clause \\n \\p");
assert_eq!(fields[1].result, "stale number relative");
assert_eq!(fields[1].computed_result.as_deref(), Some("3 above"));
assert_eq!(fields[2].instruction, "REF Clause \\n\\p");
assert_eq!(fields[2].result, "stale compact number relative");
assert_eq!(fields[2].computed_result.as_deref(), Some("3 above"));
assert_eq!(fields[3].instruction, "Clause \\n");
assert_eq!(fields[3].result, "stale direct number");
assert_eq!(fields[3].computed_result.as_deref(), Some("3"));
assert_eq!(fields[4].instruction, "Clause \\n\\t");
assert_eq!(fields[4].result, "stale compact direct numeric");
assert_eq!(fields[4].computed_result.as_deref(), Some("3"));
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
let main_text = doc.main_text();
assert!(
!main_text.contains("stale number")
&& !main_text.contains("stale number relative")
&& !main_text.contains("stale compact number relative")
&& !main_text.contains("stale direct number")
&& !main_text.contains("stale compact direct numeric"),
"REF \\n fields should display computed numbered-paragraph text: {main_text:?}"
);
assert!(main_text.contains("Numbered clause"), "{main_text:?}");
assert!(main_text.contains("3"), "{main_text:?}");
assert!(main_text.contains("3 above"), "{main_text:?}");
}
#[test]
fn docx_ref_numbering_uses_single_alternate_content_branch() {
let doc = Document::open(&alternate_content_numbered_ref_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 1);
assert_eq!(fields[0].kind, FieldKind::Ref);
assert_eq!(fields[0].instruction, "REF AltClause \\n");
assert_eq!(fields[0].result, "stale alt number");
assert_eq!(fields[0].computed_result.as_deref(), Some("2"));
let main_text = doc.main_text();
assert!(
main_text.contains("2") && !main_text.contains("stale alt number"),
"REF \\n should not double-count Choice/Fallback numbered paragraphs: {main_text:?}"
);
}
#[test]
fn docx_ref_numbering_uses_single_numbering_alternate_content_branch() {
let doc = Document::open(&numbering_alternate_content_ref_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 1);
assert_eq!(fields[0].kind, FieldKind::Ref);
assert_eq!(fields[0].instruction, "REF NumberingChoice \\n");
assert_eq!(fields[0].result, "stale numbering alternate");
assert_eq!(fields[0].computed_result.as_deref(), Some("5"));
let main_text = doc.main_text();
assert!(
main_text.contains("5") && !main_text.contains("stale numbering alternate"),
"REF \\n should use selected numbering.xml AlternateContent definitions: {main_text:?}"
);
}
#[test]
fn docx_ref_numbering_ignores_old_paragraph_property_revisions() {
let doc = Document::open(&ref_numbering_property_revision_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 3);
assert!(fields.iter().all(|field| field.kind == FieldKind::Ref));
assert_eq!(fields[0].instruction, "REF OldClause \\n");
assert_eq!(fields[0].result, "cached old number");
assert_eq!(fields[0].computed_result, None);
assert_eq!(fields[1].instruction, "REF CurrentClause \\n");
assert_eq!(fields[1].result, "stale current number");
assert_eq!(fields[1].computed_result.as_deref(), Some("1"));
assert_eq!(fields[2].instruction, "REF CurrentClause \\r");
assert_eq!(fields[2].result, "cached relative old context");
assert_eq!(fields[2].computed_result, None);
let report = doc.report();
assert_eq!(
report.features.unsupported_field_kinds,
vec![FieldKindCount {
kind: FieldKind::Ref,
count: 2,
}]
);
assert_eq!(
report.features.unsupported_field_reasons,
vec![FieldEvaluationReasonCount {
reason: FieldEvaluationReason::NoComputedResult,
count: 2,
}]
);
assert_eq!(
model_simple_field_reason_hints(&doc, |instruction| instruction.contains("CurrentClause")
|| instruction.contains("OldClause")),
vec![
(
"REF OldClause \\n".to_string(),
Some(FieldUnsupportedReason::NoComputedResult),
),
(
"REF CurrentClause \\r".to_string(),
Some(FieldUnsupportedReason::NoComputedResult),
),
]
);
let main_text = doc.main_text();
assert!(
main_text.contains("Former numbered clause"),
"{main_text:?}"
);
assert!(
main_text.contains("Current numbered clause"),
"{main_text:?}"
);
assert!(main_text.contains("cached old number"), "{main_text:?}");
assert!(main_text.contains("1"), "{main_text:?}");
assert!(
main_text.contains("cached relative old context"),
"{main_text:?}"
);
assert!(!main_text.contains("stale current number"), "{main_text:?}");
}
#[test]
fn docx_ref_n_t_field_suppresses_non_numeric_label_text() {
let doc = Document::open(&numbered_ref_suppress_text_switch_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 3);
assert!(fields.iter().all(|field| field.kind == FieldKind::Ref));
assert_eq!(fields[0].instruction, "REF SectionClause \\n \\t");
assert_eq!(fields[0].result, "stale numeric text");
assert_eq!(fields[0].computed_result.as_deref(), Some("1.01"));
assert_eq!(fields[1].instruction, "REF SectionClause \\n \\t \\p");
assert_eq!(fields[1].result, "stale numeric relative");
assert_eq!(fields[1].computed_result.as_deref(), Some("1.01 above"));
assert_eq!(fields[2].instruction, "SectionClause \\n \\t");
assert_eq!(fields[2].result, "stale direct numeric text");
assert_eq!(fields[2].computed_result.as_deref(), Some("1.01"));
let main_text = doc.main_text();
assert!(
!main_text.contains("stale numeric text")
&& !main_text.contains("stale numeric relative")
&& !main_text.contains("stale direct numeric text")
&& !main_text.contains("Section 1.01"),
"REF \\n \\t fields should display only numeric label text: {main_text:?}"
);
assert!(main_text.contains("1.01"), "{main_text:?}");
assert!(main_text.contains("1.01 above"), "{main_text:?}");
}
#[test]
fn docx_ref_w_field_computes_full_context_numbered_bookmark_paragraph() {
let doc = Document::open(&full_context_ref_switch_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 3);
assert!(fields.iter().all(|field| field.kind == FieldKind::Ref));
assert_eq!(fields[0].instruction, "REF DeepClause \\w");
assert_eq!(fields[0].result, "stale full context");
assert_eq!(fields[0].computed_result.as_deref(), Some("1.a.i"));
assert_eq!(fields[1].instruction, "REF DeepClause \\w \\p");
assert_eq!(fields[1].result, "stale full relative");
assert_eq!(fields[1].computed_result.as_deref(), Some("1.a.i above"));
assert_eq!(fields[2].instruction, "DeepClause \\w");
assert_eq!(fields[2].result, "stale direct full");
assert_eq!(fields[2].computed_result.as_deref(), Some("1.a.i"));
let main_text = doc.main_text();
assert!(
!main_text.contains("stale full context")
&& !main_text.contains("stale full relative")
&& !main_text.contains("stale direct full"),
"REF \\w fields should display computed full-context numbering: {main_text:?}"
);
assert!(main_text.contains("1.a.i"), "{main_text:?}");
assert!(main_text.contains("1.a.i above"), "{main_text:?}");
}
#[test]
fn docx_ref_w_t_field_accepts_full_context_numeric_text_suppression() {
let doc = Document::open(&full_context_ref_suppress_text_switch_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 3);
assert!(fields.iter().all(|field| field.kind == FieldKind::Ref));
assert_eq!(fields[0].instruction, "REF DeepClause \\w \\t");
assert_eq!(fields[0].result, "stale full numeric text");
assert_eq!(fields[0].computed_result.as_deref(), Some("1.a.i"));
assert_eq!(fields[1].instruction, "REF DeepClause \\w \\t \\p");
assert_eq!(fields[1].result, "stale full numeric relative");
assert_eq!(fields[1].computed_result.as_deref(), Some("1.a.i above"));
assert_eq!(fields[2].instruction, "DeepClause \\w \\t");
assert_eq!(fields[2].result, "stale direct full numeric");
assert_eq!(fields[2].computed_result.as_deref(), Some("1.a.i"));
let main_text = doc.main_text();
assert!(
!main_text.contains("stale full numeric text")
&& !main_text.contains("stale full numeric relative")
&& !main_text.contains("stale direct full numeric")
&& !main_text.contains("Section")
&& !main_text.contains("Article")
&& !main_text.contains("Part"),
"REF \\w \\t fields should display computed full-context numbering without level text: {main_text:?}"
);
assert!(main_text.contains("1.a.i"), "{main_text:?}");
assert!(main_text.contains("1.a.i above"), "{main_text:?}");
}
#[test]
fn docx_ref_r_field_computes_relative_context_numbered_bookmark_paragraph() {
let doc = Document::open(&relative_context_ref_switch_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 3);
assert!(fields.iter().all(|field| field.kind == FieldKind::Ref));
assert_eq!(fields[0].instruction, "REF LaterClause \\r");
assert_eq!(fields[0].result, "stale relative context");
assert_eq!(fields[0].computed_result.as_deref(), Some("5.2"));
assert_eq!(fields[1].instruction, "REF LaterClause \\r \\p");
assert_eq!(fields[1].result, "stale relative context position");
assert_eq!(fields[1].computed_result.as_deref(), Some("5.2 below"));
assert_eq!(fields[2].instruction, "LaterClause \\r \\t");
assert_eq!(fields[2].result, "stale direct relative context");
assert_eq!(fields[2].computed_result.as_deref(), Some("5.2"));
let main_text = doc.main_text();
assert!(
!main_text.contains("stale relative context")
&& !main_text.contains("stale relative context position")
&& !main_text.contains("stale direct relative context"),
"REF \\r fields should display computed relative-context numbering: {main_text:?}"
);
assert!(main_text.contains("5.2"), "{main_text:?}");
assert!(main_text.contains("5.2 below"), "{main_text:?}");
}
#[test]
fn docx_ref_p_field_computes_relative_source_position() {
let doc = Document::open(&relative_ref_switch_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 2);
assert_eq!(fields[0].kind, FieldKind::Ref);
assert_eq!(fields[0].instruction, "REF LaterBookmark \\p");
assert_eq!(fields[0].result, "stale below");
assert_eq!(fields[0].computed_result.as_deref(), Some("below"));
assert_eq!(fields[1].kind, FieldKind::Ref);
assert_eq!(fields[1].instruction, "REF Figure1 \\p");
assert_eq!(fields[1].result, "stale above");
assert_eq!(fields[1].computed_result.as_deref(), Some("above"));
let main_text = doc.main_text();
assert!(
!main_text.contains("stale below") && !main_text.contains("stale above"),
"REF \\p should display computed source-order relative text: {main_text:?}"
);
assert!(main_text.contains("below"), "{main_text:?}");
assert!(main_text.contains("above"), "{main_text:?}");
}
#[test]
fn docx_ref_p_field_uses_single_alternate_content_branch() {
let doc = Document::open(&relative_ref_alternate_content_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 1);
assert_eq!(fields[0].kind, FieldKind::Ref);
assert_eq!(fields[0].instruction, "REF LaterBookmark \\p");
assert_eq!(fields[0].result, "stale visible above");
assert_eq!(fields[0].computed_result.as_deref(), Some("above"));
let main_text = doc.main_text();
assert!(
main_text.contains("above") && !main_text.contains("fallback relative"),
"REF \\p position context must ignore untaken AlternateContent branches: {main_text:?}"
);
}
#[test]
fn docx_page_ref_fields_are_named_field_kind_without_computed_page_numbers() {
let doc = Document::open(&page_ref_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 2);
assert_eq!(fields[0].kind, FieldKind::PageRef);
assert_eq!(fields[0].instruction, "PAGEREF Figure1 \\h");
assert_eq!(fields[0].result, "3");
assert_eq!(fields[0].computed_result, None);
assert_eq!(fields[1].kind, FieldKind::PageRef);
assert_eq!(fields[1].instruction, "PAGEREF \"TableOne\" \\p");
assert_eq!(fields[1].result, "above");
assert_eq!(fields[1].computed_result, None);
let main_text = doc.main_text();
assert!(
main_text.contains("3") && main_text.contains("above"),
"PAGEREF fields should keep cached page-reference text until layout page resolution exists: {main_text:?}"
);
}
#[test]
fn docx_page_ref_gap_cases_keep_cached_text() {
let doc = Document::open(&page_ref_gap_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 2);
assert!(fields.iter().all(|field| field.kind == FieldKind::PageRef));
assert_eq!(fields[0].instruction, "PAGEREF PlainText \\h");
assert_eq!(fields[0].result, "cached page ref");
assert_eq!(fields[0].computed_result, None);
assert_eq!(fields[1].instruction, "PAGEREF MissingPage \\h");
assert_eq!(fields[1].result, "cached missing page ref");
assert_eq!(fields[1].computed_result, None);
let report = doc.report();
assert_eq!(
report.features.unsupported_field_kinds,
vec![FieldKindCount {
kind: FieldKind::PageRef,
count: 2,
}]
);
assert_eq!(
report.features.unsupported_field_reasons,
vec![
FieldEvaluationReasonCount {
reason: FieldEvaluationReason::NoComputedResult,
count: 1,
},
FieldEvaluationReasonCount {
reason: FieldEvaluationReason::UnresolvedBookmark,
count: 1,
},
]
);
assert_eq!(
model_simple_field_reason_hints(&doc, |instruction| instruction.starts_with("PAGEREF")),
vec![
(
"PAGEREF PlainText \\h".to_string(),
Some(FieldUnsupportedReason::NoComputedResult),
),
(
"PAGEREF MissingPage \\h".to_string(),
Some(FieldUnsupportedReason::UnresolvedBookmark),
),
]
);
let main_text = doc.main_text();
assert!(
main_text.contains("cached page ref") && main_text.contains("cached missing page ref"),
"PAGEREF gap cases should preserve cached result text: {main_text:?}"
);
}
#[test]
fn docx_page_ref_computes_explicit_manual_break_page_targets() {
let doc = Document::open(&page_ref_manual_break_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 3);
assert_eq!(fields[0].kind, FieldKind::PageRef);
assert_eq!(fields[0].instruction, "PAGEREF Figure1 \\h");
assert_eq!(fields[0].result, "99");
assert_eq!(fields[0].computed_result.as_deref(), Some("2"));
assert_eq!(fields[1].kind, FieldKind::PageRef);
assert_eq!(fields[1].instruction, "PAGEREF \"Figure1\" \\* MERGEFORMAT");
assert_eq!(fields[1].result, "old page");
assert_eq!(fields[1].computed_result.as_deref(), Some("2"));
assert_eq!(fields[2].kind, FieldKind::PageRef);
assert_eq!(fields[2].instruction, "PAGEREF Figure1 \\p");
assert_eq!(fields[2].result, "above");
assert_eq!(fields[2].computed_result.as_deref(), Some("on page 2"));
let main_text = doc.main_text();
assert!(
main_text.contains("2\n2\non page 2"),
"manual-break PAGEREF fields should replace unambiguous page numbers and relative page labels: {main_text:?}"
);
assert!(
!main_text.contains("99") && !main_text.contains("old page") && !main_text.contains("above"),
"computed manual-break PAGEREF fields should not display stale cached page text: {main_text:?}"
);
}
#[test]
fn docx_page_ref_computes_leading_break_relative_position() {
let doc = Document::open(&page_ref_leading_break_relative_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 1);
assert_eq!(fields[0].kind, FieldKind::PageRef);
assert_eq!(fields[0].instruction, "PAGEREF Figure1 \\p");
assert_eq!(fields[0].result, "stale relative");
assert_eq!(fields[0].computed_result.as_deref(), Some("above"));
let main_text = doc.main_text();
assert!(
main_text.contains("above") && !main_text.contains("stale relative"),
"leading-break PAGEREF relative positions should use computed text: {main_text:?}"
);
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
}
#[test]
fn docx_page_ref_applies_deterministic_number_format_switches() {
let doc = Document::open(&page_ref_format_switch_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 10);
let expected = [
("PAGEREF Figure1 \\* ROMAN", "II"),
("PAGEREF Figure1 \\*roman", "ii"),
("PAGEREF Figure1 \\* alphabetic", "b"),
("PAGEREF Figure1 \\*ALPHABETIC", "B"),
("PAGEREF Figure1 \\* Ordinal", "2nd"),
("PAGEREF Figure1 \\* CardText", "two"),
("PAGEREF Figure1 \\* CardText \\* Upper", "TWO"),
("PAGEREF Figure1 \\* OrdText", "second"),
("PAGEREF Figure1 \\* Arabic", "2"),
("PAGEREF Figure1 \\* ArabicDash", "- 2 -"),
];
for (field, (instruction, computed)) in fields.iter().zip(expected) {
assert_eq!(field.kind, FieldKind::PageRef);
assert_eq!(field.instruction, instruction);
assert_eq!(field.computed_result.as_deref(), Some(computed));
}
let main_text = doc.main_text();
assert!(
main_text.contains("II\nii\nb\nB\n2nd\ntwo\nTWO\nsecond\n2\n- 2 -"),
"formatted PAGEREF values should be materialized in the read model: {main_text:?}"
);
assert!(
!main_text.contains("stale"),
"computed PAGEREF format switches should not keep stale cached text: {main_text:?}"
);
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
}
#[test]
fn docx_page_ref_accepts_mixed_case_number_format_switch() {
let doc = Document::open(&page_ref_mixed_case_format_switch_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 1);
assert_eq!(fields[0].kind, FieldKind::PageRef);
assert_eq!(fields[0].instruction, "PAGEREF Figure1 \\* ArAbIc");
assert_eq!(fields[0].computed_result.as_deref(), Some("2"));
let main_text = doc.main_text();
assert!(
main_text.contains("2") && !main_text.contains("stale mixed arabic"),
"mixed-case PAGEREF number format should compute like Arabic: {main_text:?}"
);
}
#[test]
fn docx_page_ref_after_visible_content_keeps_cached_page_text() {
let doc = Document::open(&page_ref_after_visible_manual_break_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 1);
assert_eq!(fields[0].kind, FieldKind::PageRef);
assert_eq!(fields[0].instruction, "PAGEREF Figure1 \\h");
assert_eq!(fields[0].result, "99");
assert_eq!(fields[0].computed_result, None);
let main_text = doc.main_text();
assert!(
main_text.contains("99"),
"PAGEREF after visible content should keep cached text because auto-pagination can intervene: {main_text:?}"
);
}
#[test]
fn docx_page_ref_symbol_before_manual_break_keeps_cached_page_text() {
let doc = Document::open(&page_ref_symbol_before_manual_break_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 1);
assert_eq!(fields[0].kind, FieldKind::PageRef);
assert_eq!(fields[0].instruction, "PAGEREF FigureSymbol \\h");
assert_eq!(fields[0].result, "99");
assert_eq!(fields[0].computed_result, None);
let report = doc.report();
assert_eq!(
report.features.unsupported_field_kinds,
vec![FieldKindCount {
kind: FieldKind::PageRef,
count: 1,
}]
);
assert_eq!(
report.features.unsupported_field_reasons,
vec![FieldEvaluationReasonCount {
reason: FieldEvaluationReason::NoComputedResult,
count: 1,
}]
);
}
#[test]
fn docx_page_ref_note_mark_before_manual_break_keeps_cached_page_text() {
let doc =
Document::open(&page_ref_note_mark_before_manual_break_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 1);
assert_eq!(fields[0].kind, FieldKind::PageRef);
assert_eq!(fields[0].instruction, "PAGEREF FigureNote \\h");
assert_eq!(fields[0].result, "99");
assert_eq!(fields[0].computed_result, None);
let report = doc.report();
assert_eq!(
report.features.unsupported_field_kinds,
vec![FieldKindCount {
kind: FieldKind::PageRef,
count: 1,
}]
);
assert_eq!(
report.features.unsupported_field_reasons,
vec![FieldEvaluationReasonCount {
reason: FieldEvaluationReason::NoComputedResult,
count: 1,
}]
);
}
#[test]
fn docx_page_ref_comment_mark_before_manual_break_keeps_cached_page_text() {
let doc =
Document::open(&page_ref_comment_mark_before_manual_break_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 1);
assert_eq!(fields[0].kind, FieldKind::PageRef);
assert_eq!(fields[0].instruction, "PAGEREF FigureComment \\h");
assert_eq!(fields[0].result, "99");
assert_eq!(fields[0].computed_result, None);
let report = doc.report();
assert_eq!(
report.features.unsupported_field_kinds,
vec![FieldKindCount {
kind: FieldKind::PageRef,
count: 1,
}]
);
assert_eq!(
report.features.unsupported_field_reasons,
vec![FieldEvaluationReasonCount {
reason: FieldEvaluationReason::NoComputedResult,
count: 1,
}]
);
}
#[test]
fn docx_page_ref_ignores_stale_markers_inside_computed_field_results_before_manual_break() {
let doc = Document::open(&page_ref_computed_field_markers_before_manual_break_docx())
.expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 3);
assert_eq!(fields[0].kind, FieldKind::Dynamic("SET".to_string()));
assert_eq!(fields[0].instruction, r#"SET SimpleHidden "Plain""#);
assert_eq!(fields[0].computed_result.as_deref(), Some(""));
assert_eq!(fields[1].kind, FieldKind::Dynamic("SET".to_string()));
assert_eq!(fields[1].instruction, r#"SET ComplexHidden "Plain""#);
assert_eq!(fields[1].computed_result.as_deref(), Some(""));
assert_eq!(fields[2].kind, FieldKind::PageRef);
assert_eq!(fields[2].instruction, "PAGEREF ComputedHiddenTarget \\h");
assert_eq!(fields[2].result, "cached hidden page ref");
assert_eq!(fields[2].computed_result.as_deref(), Some("2"));
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
let main_text = doc.main_text();
assert!(
main_text.contains("Computed hidden target\n2")
&& !main_text.contains("cached hidden page ref")
&& !main_text.contains("stale hidden field text")
&& !main_text.contains('\u{0002}'),
"PAGEREF should ignore stale markers hidden inside computed field results: {main_text:?}"
);
}
#[test]
fn docx_page_ref_uses_empty_document_info_result_before_manual_break() {
let doc = Document::open(&page_ref_empty_document_info_before_manual_break_docx())
.expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 2);
assert_eq!(fields[0].kind, FieldKind::DocumentInfo("TITLE".to_string()));
assert_eq!(fields[0].instruction, "TITLE");
assert_eq!(fields[0].result, "stale page title");
assert_eq!(fields[0].computed_result.as_deref(), Some(""));
assert_eq!(fields[1].kind, FieldKind::PageRef);
assert_eq!(fields[1].instruction, "PAGEREF AfterEmptyTitle \\h");
assert_eq!(fields[1].result, "cached after title page");
assert_eq!(fields[1].computed_result.as_deref(), Some("2"));
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
let main_text = doc.main_text();
assert!(
main_text.contains("After empty title\n2")
&& !main_text.contains("stale page title")
&& !main_text.contains("cached after title page"),
"PAGEREF should use computed empty document-info output when deciding hard-break trust: {main_text:?}"
);
}
#[test]
fn docx_position_scanners_use_empty_revision_number_results() {
let page_doc = Document::open(&page_ref_empty_revision_number_before_manual_break_docx())
.expect("page fixture opens");
let page_fields = page_doc.fields();
assert_eq!(page_fields.len(), 2);
assert_eq!(
page_fields[0].kind,
FieldKind::DocumentStructure("REVNUM".to_string())
);
assert_eq!(page_fields[0].instruction, "REVNUM");
assert_eq!(page_fields[0].result, "stale page revision");
assert_eq!(page_fields[0].computed_result.as_deref(), Some(""));
assert_eq!(page_fields[1].kind, FieldKind::PageRef);
assert_eq!(page_fields[1].instruction, "PAGEREF AfterEmptyRevision \\h");
assert_eq!(page_fields[1].result, "cached after revision page");
assert_eq!(page_fields[1].computed_result.as_deref(), Some("2"));
let section_doc = Document::open(§ion_pages_empty_revision_number_result_docx())
.expect("section fixture opens");
let section_fields = section_doc.fields();
assert_eq!(section_fields.len(), 2);
assert_eq!(
section_fields[0].kind,
FieldKind::DocumentStructure("REVNUM".to_string())
);
assert_eq!(section_fields[0].instruction, "REVNUM");
assert_eq!(section_fields[0].result, "stale section revision");
assert_eq!(section_fields[0].computed_result.as_deref(), Some(""));
assert_eq!(
section_fields[1].kind,
FieldKind::DocumentStructure("SECTIONPAGES".to_string())
);
assert_eq!(section_fields[1].instruction, "SECTIONPAGES");
assert_eq!(section_fields[1].result, "cached section revision pages");
assert_eq!(section_fields[1].computed_result.as_deref(), Some("1"));
let note_doc = Document::open(¬e_ref_empty_revision_number_result_marker_docx())
.expect("note fixture opens");
let note_fields = note_doc.fields();
assert_eq!(note_fields.len(), 2);
assert_eq!(
note_fields[0].kind,
FieldKind::DocumentStructure("REVNUM".to_string())
);
assert_eq!(note_fields[0].instruction, "REVNUM");
assert_eq!(note_fields[0].result, "stale note revision");
assert_eq!(note_fields[0].computed_result.as_deref(), Some(""));
assert_eq!(note_fields[1].kind, FieldKind::NoteRef);
assert_eq!(note_fields[1].instruction, "NOTEREF ComputedNote");
assert_eq!(note_fields[1].result, "cached stale revision note ref");
assert_eq!(note_fields[1].computed_result, None);
for doc in [&page_doc, §ion_doc] {
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
}
let note_report = note_doc.report();
assert_eq!(
note_report.features.unsupported_field_kinds,
vec![FieldKindCount {
kind: FieldKind::NoteRef,
count: 1,
}]
);
assert_eq!(
note_report.features.unsupported_field_reasons,
vec![FieldEvaluationReasonCount {
reason: FieldEvaluationReason::NoComputedResult,
count: 1,
}]
);
}
#[test]
fn docx_position_scanners_use_empty_legacy_form_results() {
let page_doc = Document::open(&page_ref_empty_legacy_form_before_manual_break_docx())
.expect("page fixture opens");
let page_fields = page_doc.fields();
assert_eq!(page_fields.len(), 2);
assert_eq!(
page_fields[0].kind,
FieldKind::FormField("FORMDROPDOWN".to_string())
);
assert_eq!(page_fields[0].instruction, "FORMDROPDOWN");
assert_eq!(page_fields[0].result, "stale page option");
assert_eq!(page_fields[0].computed_result.as_deref(), Some(""));
assert_eq!(page_fields[1].kind, FieldKind::PageRef);
assert_eq!(page_fields[1].instruction, "PAGEREF AfterEmptyForm \\h");
assert_eq!(page_fields[1].result, "cached after form page");
assert_eq!(page_fields[1].computed_result.as_deref(), Some("2"));
let section_doc = Document::open(§ion_pages_empty_legacy_form_result_docx())
.expect("section fixture opens");
let section_fields = section_doc.fields();
assert_eq!(section_fields.len(), 2);
assert_eq!(
section_fields[0].kind,
FieldKind::FormField("FORMDROPDOWN".to_string())
);
assert_eq!(section_fields[0].instruction, "FORMDROPDOWN");
assert_eq!(section_fields[0].result, "stale section option");
assert_eq!(section_fields[0].computed_result.as_deref(), Some(""));
assert_eq!(
section_fields[1].kind,
FieldKind::DocumentStructure("SECTIONPAGES".to_string())
);
assert_eq!(section_fields[1].instruction, "SECTIONPAGES");
assert_eq!(section_fields[1].result, "cached section form pages");
assert_eq!(section_fields[1].computed_result.as_deref(), Some("1"));
let note_doc = Document::open(¬e_ref_empty_legacy_form_result_marker_docx())
.expect("note fixture opens");
let note_fields = note_doc.fields();
assert_eq!(note_fields.len(), 2);
assert_eq!(
note_fields[0].kind,
FieldKind::FormField("FORMDROPDOWN".to_string())
);
assert_eq!(note_fields[0].instruction, "FORMDROPDOWN");
assert_eq!(note_fields[0].result, "stale note option");
assert_eq!(note_fields[0].computed_result.as_deref(), Some(""));
assert_eq!(note_fields[1].kind, FieldKind::NoteRef);
assert_eq!(note_fields[1].instruction, "NOTEREF ComputedNote");
assert_eq!(note_fields[1].result, "cached stale legacy form note ref");
assert_eq!(note_fields[1].computed_result, None);
for doc in [&page_doc, §ion_doc] {
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
}
let note_report = note_doc.report();
assert_eq!(
note_report.features.unsupported_field_kinds,
vec![FieldKindCount {
kind: FieldKind::NoteRef,
count: 1,
}]
);
assert_eq!(
note_report.features.unsupported_field_reasons,
vec![FieldEvaluationReasonCount {
reason: FieldEvaluationReason::NoComputedResult,
count: 1,
}]
);
let page_text = page_doc.main_text();
assert!(
page_text.contains("After empty form\n2")
&& !page_text.contains("stale page option")
&& !page_text.contains("cached after form page"),
"PAGEREF should use computed empty legacy-form output when deciding hard-break trust: {page_text:?}"
);
let section_text = section_doc.main_text();
assert!(
section_text.contains('1')
&& !section_text.contains("stale section option")
&& !section_text.contains("cached section form pages"),
"SECTIONPAGES should use computed empty legacy-form output when deciding section content: {section_text:?}"
);
let note_text = note_doc.main_text();
assert!(
note_text.contains("cached stale legacy form note ref")
&& !note_text.contains("stale note option")
&& !note_text.contains('\u{0002}')
&& !note_text.contains('1'),
"NOTEREF should not resolve a stale marker hidden inside legacy-form output: {note_text:?}"
);
}
#[test]
fn docx_position_scanners_use_document_bookmark_merge_control_results() {
let page_doc = Document::open(&page_ref_bookmark_merge_control_before_manual_break_docx())
.expect("page fixture opens");
let page_fields = page_doc.fields();
assert_eq!(page_fields.len(), 2);
assert_eq!(
page_fields[0].kind,
FieldKind::Dynamic("NEXTIF".to_string())
);
assert_eq!(page_fields[0].instruction, r#"NEXTIF Gate = "Ready""#);
assert_eq!(page_fields[0].result, "stale page merge control");
assert_eq!(page_fields[0].computed_result.as_deref(), Some(""));
assert_eq!(page_fields[1].kind, FieldKind::PageRef);
assert_eq!(page_fields[1].instruction, "PAGEREF AfterBookmarkMerge \\h");
assert_eq!(page_fields[1].result, "cached after bookmark merge page");
assert_eq!(page_fields[1].computed_result.as_deref(), Some("2"));
let section_doc = Document::open(§ion_pages_bookmark_merge_control_result_docx())
.expect("section fixture opens");
let section_fields = section_doc.fields();
assert_eq!(section_fields.len(), 2);
assert_eq!(
section_fields[0].kind,
FieldKind::Dynamic("NEXTIF".to_string())
);
assert_eq!(section_fields[0].instruction, r#"NEXTIF Gate = "Ready""#);
assert_eq!(section_fields[0].result, "stale section merge control");
assert_eq!(section_fields[0].computed_result.as_deref(), Some(""));
assert_eq!(
section_fields[1].kind,
FieldKind::DocumentStructure("SECTIONPAGES".to_string())
);
assert_eq!(section_fields[1].instruction, "SECTIONPAGES");
assert_eq!(section_fields[1].result, "cached section bookmark pages");
assert_eq!(section_fields[1].computed_result.as_deref(), Some("1"));
let note_doc = Document::open(¬e_ref_bookmark_merge_control_result_marker_docx())
.expect("note fixture opens");
let note_fields = note_doc.fields();
assert_eq!(note_fields.len(), 2);
assert_eq!(
note_fields[0].kind,
FieldKind::Dynamic("NEXTIF".to_string())
);
assert_eq!(note_fields[0].instruction, r#"NEXTIF Gate = "Ready""#);
assert_eq!(note_fields[0].result, "stale note merge control");
assert_eq!(note_fields[0].computed_result.as_deref(), Some(""));
assert_eq!(note_fields[1].kind, FieldKind::NoteRef);
assert_eq!(note_fields[1].instruction, "NOTEREF ComputedNote");
assert_eq!(
note_fields[1].result,
"cached stale bookmark merge note ref"
);
assert_eq!(note_fields[1].computed_result, None);
for doc in [&page_doc, §ion_doc] {
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
}
let note_report = note_doc.report();
assert_eq!(
note_report.features.unsupported_field_kinds,
vec![FieldKindCount {
kind: FieldKind::NoteRef,
count: 1,
}]
);
assert_eq!(
note_report.features.unsupported_field_reasons,
vec![FieldEvaluationReasonCount {
reason: FieldEvaluationReason::NoComputedResult,
count: 1,
}]
);
let page_text = page_doc.main_text();
assert!(
page_text.contains("Ready\n2")
&& !page_text.contains("stale page merge control")
&& !page_text.contains("cached after bookmark merge page"),
"PAGEREF should use computed document-bookmark merge-control output before a hard break: {page_text:?}"
);
let section_text = section_doc.main_text();
assert!(
section_text.contains('1')
&& !section_text.contains("stale section merge control")
&& !section_text.contains("cached section bookmark pages"),
"SECTIONPAGES should use computed document-bookmark merge-control output when deciding section content: {section_text:?}"
);
let note_text = note_doc.main_text();
assert!(
note_text.contains("cached stale bookmark merge note ref")
&& !note_text.contains("stale note merge control")
&& !note_text.contains('\u{0002}')
&& !note_text.contains('1'),
"NOTEREF should not resolve a stale marker hidden inside document-bookmark merge-control output: {note_text:?}"
);
}
#[test]
fn docx_position_scanners_use_document_bookmark_if_results() {
let page_doc = Document::open(&page_ref_bookmark_if_before_manual_break_docx())
.expect("page fixture opens");
let page_fields = page_doc.fields();
assert_eq!(page_fields.len(), 2);
assert_eq!(page_fields[0].kind, FieldKind::Dynamic("IF".to_string()));
assert_eq!(page_fields[0].instruction, r#"IF Gate = "Ready" "" """#);
assert_eq!(page_fields[0].result, "stale page if");
assert_eq!(page_fields[0].computed_result.as_deref(), Some(""));
assert_eq!(page_fields[1].kind, FieldKind::PageRef);
assert_eq!(page_fields[1].instruction, "PAGEREF AfterBookmarkIf \\h");
assert_eq!(page_fields[1].result, "cached after bookmark if page");
assert_eq!(page_fields[1].computed_result.as_deref(), Some("2"));
let section_doc =
Document::open(§ion_pages_bookmark_if_result_docx()).expect("section fixture opens");
let section_fields = section_doc.fields();
assert_eq!(section_fields.len(), 2);
assert_eq!(section_fields[0].kind, FieldKind::Dynamic("IF".to_string()));
assert_eq!(section_fields[0].instruction, r#"IF Gate = "Ready" "" """#);
assert_eq!(section_fields[0].result, "stale section if");
assert_eq!(section_fields[0].computed_result.as_deref(), Some(""));
assert_eq!(
section_fields[1].kind,
FieldKind::DocumentStructure("SECTIONPAGES".to_string())
);
assert_eq!(section_fields[1].instruction, "SECTIONPAGES");
assert_eq!(section_fields[1].result, "cached section if pages");
assert_eq!(section_fields[1].computed_result.as_deref(), Some("1"));
let note_doc =
Document::open(¬e_ref_bookmark_if_result_marker_docx()).expect("note fixture opens");
let note_fields = note_doc.fields();
assert_eq!(note_fields.len(), 2);
assert_eq!(note_fields[0].kind, FieldKind::Dynamic("IF".to_string()));
assert_eq!(note_fields[0].instruction, r#"IF Gate = "Ready" "" """#);
assert_eq!(note_fields[0].result, "stale note if");
assert_eq!(note_fields[0].computed_result.as_deref(), Some(""));
assert_eq!(note_fields[1].kind, FieldKind::NoteRef);
assert_eq!(note_fields[1].instruction, "NOTEREF ComputedNote");
assert_eq!(note_fields[1].result, "cached stale bookmark if note ref");
assert_eq!(note_fields[1].computed_result, None);
for doc in [&page_doc, §ion_doc] {
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
}
let note_report = note_doc.report();
assert_eq!(
note_report.features.unsupported_field_kinds,
vec![FieldKindCount {
kind: FieldKind::NoteRef,
count: 1,
}]
);
assert_eq!(
note_report.features.unsupported_field_reasons,
vec![FieldEvaluationReasonCount {
reason: FieldEvaluationReason::NoComputedResult,
count: 1,
}]
);
let page_text = page_doc.main_text();
assert!(
page_text.contains("Ready\n2")
&& !page_text.contains("stale page if")
&& !page_text.contains("cached after bookmark if page"),
"PAGEREF should use computed document-bookmark IF output before a hard break: {page_text:?}"
);
let section_text = section_doc.main_text();
assert!(
section_text.contains('1')
&& !section_text.contains("stale section if")
&& !section_text.contains("cached section if pages"),
"SECTIONPAGES should use computed document-bookmark IF output when deciding section content: {section_text:?}"
);
let note_text = note_doc.main_text();
assert!(
note_text.contains("cached stale bookmark if note ref")
&& !note_text.contains("stale note if")
&& !note_text.contains('\u{0002}')
&& !note_text.contains('1'),
"NOTEREF should not resolve a stale marker hidden inside document-bookmark IF output: {note_text:?}"
);
}
#[test]
fn docx_note_ref_uses_document_bookmark_compare_result_for_marker_scan() {
let doc =
Document::open(¬e_ref_bookmark_compare_result_marker_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 2);
assert_eq!(fields[0].kind, FieldKind::Dynamic("COMPARE".to_string()));
assert_eq!(fields[0].instruction, r#"COMPARE Gate = "Ready""#);
assert_eq!(fields[0].result, "stale note compare");
assert_eq!(fields[0].computed_result.as_deref(), Some("1"));
assert_eq!(fields[1].kind, FieldKind::NoteRef);
assert_eq!(fields[1].instruction, "NOTEREF ComputedNote");
assert_eq!(fields[1].result, "cached stale bookmark compare note ref");
assert_eq!(fields[1].computed_result, None);
let report = doc.report();
assert_eq!(
report.features.unsupported_field_kinds,
vec![FieldKindCount {
kind: FieldKind::NoteRef,
count: 1,
}]
);
assert_eq!(
report.features.unsupported_field_reasons,
vec![FieldEvaluationReasonCount {
reason: FieldEvaluationReason::NoComputedResult,
count: 1,
}]
);
let main_text = doc.main_text();
assert!(
main_text.contains("1")
&& main_text.contains("cached stale bookmark compare note ref")
&& !main_text.contains("stale note compare")
&& !main_text.contains('\u{0002}'),
"NOTEREF should not resolve a stale marker hidden inside document-bookmark COMPARE output: {main_text:?}"
);
}
#[test]
fn docx_position_scanners_use_document_bookmark_formula_results() {
let page_doc = Document::open(&page_ref_bookmark_formula_rendered_break_docx())
.expect("page fixture opens");
let page_fields = page_doc.fields();
assert_eq!(page_fields.len(), 2);
assert_eq!(page_fields[0].kind, FieldKind::Dynamic("=".to_string()));
assert_eq!(page_fields[0].instruction, "= InvoiceSubtotal + 8");
assert_eq!(page_fields[0].result, "\u{000c}stale page formula");
assert_eq!(page_fields[0].computed_result.as_deref(), Some("50"));
assert_eq!(page_fields[1].kind, FieldKind::PageRef);
assert_eq!(
page_fields[1].instruction,
"PAGEREF AfterBookmarkFormula \\h"
);
assert_eq!(page_fields[1].result, "cached after bookmark formula page");
assert_eq!(page_fields[1].computed_result.as_deref(), Some("2"));
let section_doc = Document::open(§ion_pages_bookmark_formula_result_docx())
.expect("section fixture opens");
let section_fields = section_doc.fields();
assert_eq!(section_fields.len(), 2);
assert_eq!(section_fields[0].kind, FieldKind::Dynamic("=".to_string()));
assert_eq!(section_fields[0].instruction, "= InvoiceSubtotal + 8");
assert_eq!(section_fields[0].result, "");
assert_eq!(section_fields[0].computed_result.as_deref(), Some("50"));
assert_eq!(
section_fields[1].kind,
FieldKind::DocumentStructure("SECTIONPAGES".to_string())
);
assert_eq!(section_fields[1].instruction, "SECTIONPAGES");
assert_eq!(section_fields[1].result, "cached section formula pages");
assert_eq!(section_fields[1].computed_result, None);
let note_doc = Document::open(¬e_ref_bookmark_formula_result_marker_docx())
.expect("note fixture opens");
let note_fields = note_doc.fields();
assert_eq!(note_fields.len(), 2);
assert_eq!(note_fields[0].kind, FieldKind::Dynamic("=".to_string()));
assert_eq!(note_fields[0].instruction, "= InvoiceSubtotal + 8");
assert_eq!(note_fields[0].result, "stale note formula");
assert_eq!(note_fields[0].computed_result.as_deref(), Some("50"));
assert_eq!(note_fields[1].kind, FieldKind::NoteRef);
assert_eq!(note_fields[1].instruction, "NOTEREF ComputedNote");
assert_eq!(
note_fields[1].result,
"cached stale bookmark formula note ref"
);
assert_eq!(note_fields[1].computed_result, None);
let page_report = page_doc.report();
assert!(page_report.features.unsupported_field_kinds.is_empty());
assert!(page_report.features.unsupported_field_reasons.is_empty());
let section_report = section_doc.report();
assert_eq!(
section_report.features.unsupported_field_kinds,
vec![FieldKindCount {
kind: FieldKind::DocumentStructure("SECTIONPAGES".to_string()),
count: 1,
}]
);
assert_eq!(
section_report.features.unsupported_field_reasons,
vec![FieldEvaluationReasonCount {
reason: FieldEvaluationReason::NoComputedResult,
count: 1,
}]
);
let note_report = note_doc.report();
assert_eq!(
note_report.features.unsupported_field_kinds,
vec![FieldKindCount {
kind: FieldKind::NoteRef,
count: 1,
}]
);
assert_eq!(
note_report.features.unsupported_field_reasons,
vec![FieldEvaluationReasonCount {
reason: FieldEvaluationReason::NoComputedResult,
count: 1,
}]
);
let page_text = page_doc.main_text();
assert!(
page_text.contains("50\n42\n2")
&& !page_text.contains("stale page formula")
&& !page_text.contains("cached after bookmark formula page"),
"PAGEREF should use computed document-bookmark formula output when scanning page markers: {page_text:?}"
);
let section_text = section_doc.main_text();
assert!(
section_text.contains("50")
&& section_text.contains("cached section formula pages")
&& section_text.contains("42")
&& !section_text.contains('1'),
"SECTIONPAGES should treat computed document-bookmark formula output as visible section content: {section_text:?}"
);
let note_text = note_doc.main_text();
assert!(
note_text.contains("50")
&& note_text.contains("cached stale bookmark formula note ref")
&& !note_text.contains("stale note formula")
&& !note_text.contains('\u{0002}')
&& !note_text.contains('1'),
"NOTEREF should not resolve a stale marker hidden inside document-bookmark formula output: {note_text:?}"
);
}
#[test]
fn docx_page_ref_ignores_stale_empty_ref_result_before_manual_break() {
let doc =
Document::open(&page_ref_empty_ref_before_manual_break_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 2);
assert_eq!(fields[0].kind, FieldKind::Ref);
assert_eq!(fields[0].instruction, "REF EmptyTarget");
assert_eq!(fields[0].result, "stale empty ref before break");
assert_eq!(fields[0].computed_result.as_deref(), Some(""));
assert_eq!(fields[1].kind, FieldKind::PageRef);
assert_eq!(fields[1].instruction, "PAGEREF AfterEmptyRef \\h");
assert_eq!(fields[1].result, "cached after empty ref page");
assert_eq!(fields[1].computed_result.as_deref(), Some("2"));
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
let main_text = doc.main_text();
assert!(
main_text.contains("After empty ref\n2")
&& !main_text.contains("stale empty ref before break")
&& !main_text.contains("cached after empty ref page"),
"PAGEREF should use the computed empty REF result when deciding hard-break trust: {main_text:?}"
);
}
#[test]
fn docx_page_ref_ignores_stale_empty_direct_bookmark_result_before_manual_break() {
let doc = Document::open(&page_ref_empty_direct_bookmark_before_manual_break_docx())
.expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 2);
assert_eq!(fields[0].kind, FieldKind::Ref);
assert_eq!(fields[0].instruction, "EmptyTarget");
assert_eq!(fields[0].result, "stale empty direct ref before break");
assert_eq!(fields[0].computed_result.as_deref(), Some(""));
assert_eq!(fields[1].kind, FieldKind::PageRef);
assert_eq!(fields[1].instruction, "PAGEREF AfterDirectRef \\h");
assert_eq!(fields[1].result, "cached after direct ref page");
assert_eq!(fields[1].computed_result.as_deref(), Some("2"));
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
let main_text = doc.main_text();
assert!(
main_text.contains("After direct ref\n2")
&& !main_text.contains("stale empty direct ref before break")
&& !main_text.contains("cached after direct ref page"),
"PAGEREF should use the computed empty direct bookmark result when deciding hard-break trust: {main_text:?}"
);
}
#[test]
fn docx_page_ref_does_not_treat_known_field_names_as_direct_bookmarks() {
let doc = Document::open(&page_ref_known_field_name_bookmark_before_manual_break_docx())
.expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 2);
assert_eq!(fields[0].kind, FieldKind::Toc);
assert_eq!(fields[0].instruction, "TOC");
assert_eq!(fields[0].result, "stale toc before break");
assert_eq!(fields[0].computed_result, None);
assert_eq!(fields[1].kind, FieldKind::PageRef);
assert_eq!(fields[1].instruction, "PAGEREF AfterKnownField \\h");
assert_eq!(fields[1].result, "cached after known field page");
assert_eq!(fields[1].computed_result, None);
let report = doc.report();
assert_eq!(
report.features.unsupported_field_kinds,
vec![
FieldKindCount {
kind: FieldKind::Toc,
count: 1,
},
FieldKindCount {
kind: FieldKind::PageRef,
count: 1,
},
]
);
assert_eq!(
report.features.unsupported_field_reasons,
vec![FieldEvaluationReasonCount {
reason: FieldEvaluationReason::NoComputedResult,
count: 2,
}]
);
let main_text = doc.main_text();
assert!(
main_text.contains("cached after known field page") && !main_text.contains("\n2"),
"PAGEREF should not treat a known TOC field as an empty direct bookmark before a manual break: {main_text:?}"
);
}
#[test]
fn docx_page_ref_computes_source_rendered_page_break_targets() {
let doc = Document::open(&page_ref_rendered_break_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 3);
assert_eq!(fields[0].kind, FieldKind::PageRef);
assert_eq!(fields[0].instruction, "PAGEREF FigureTwo \\h");
assert_eq!(fields[0].result, "99");
assert_eq!(fields[0].computed_result.as_deref(), Some("2"));
assert_eq!(fields[1].kind, FieldKind::PageRef);
assert_eq!(
fields[1].instruction,
"PAGEREF \"FigureTwo\" \\* CHARFORMAT"
);
assert_eq!(fields[1].result, "old rendered page");
assert_eq!(fields[1].computed_result.as_deref(), Some("2"));
assert_eq!(fields[2].kind, FieldKind::PageRef);
assert_eq!(fields[2].instruction, "PAGEREF FigureTwo \\p");
assert_eq!(fields[2].result, "below");
assert_eq!(fields[2].computed_result.as_deref(), Some("above"));
let main_text = doc.main_text();
assert!(
main_text.contains("2\n2\nabove"),
"rendered-break PAGEREF fields should replace supported page-number and relative-position fields: {main_text:?}"
);
assert!(
!main_text.contains("99")
&& !main_text.contains("old rendered page")
&& !main_text.contains("below"),
"computed rendered-break PAGEREF fields should not display stale cached page text: {main_text:?}"
);
}
#[test]
fn docx_page_ref_computes_source_rendered_relative_below() {
let doc =
Document::open(&page_ref_rendered_break_relative_below_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 1);
assert_eq!(fields[0].kind, FieldKind::PageRef);
assert_eq!(fields[0].instruction, "PAGEREF FigureLater \\p");
assert_eq!(fields[0].result, "above");
assert_eq!(fields[0].computed_result.as_deref(), Some("below"));
let main_text = doc.main_text();
assert!(
main_text.contains("below") && !main_text.contains("above"),
"same-page PAGEREF before its bookmark should compute relative position as below: {main_text:?}"
);
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
}
#[test]
fn docx_page_ref_advances_rendered_context_across_manual_page_breaks() {
let doc = Document::open(&page_ref_rendered_then_manual_break_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 4);
assert_eq!(fields[0].kind, FieldKind::PageRef);
assert_eq!(fields[0].instruction, "PAGEREF PageThree \\p");
assert_eq!(fields[0].result, "stale distant relative");
assert_eq!(fields[0].computed_result.as_deref(), Some("on page 3"));
assert_eq!(fields[1].kind, FieldKind::PageRef);
assert_eq!(fields[1].instruction, "PAGEREF PageThree \\h");
assert_eq!(fields[1].result, "99");
assert_eq!(fields[1].computed_result.as_deref(), Some("3"));
assert_eq!(fields[2].kind, FieldKind::PageRef);
assert_eq!(fields[2].instruction, "PAGEREF PageThree \\p");
assert_eq!(fields[2].result, "old relative");
assert_eq!(fields[2].computed_result.as_deref(), Some("above"));
assert_eq!(fields[3].kind, FieldKind::Page);
assert_eq!(fields[3].instruction, "PAGE \\* Arabic");
assert_eq!(fields[3].result, "stale current page");
assert_eq!(fields[3].computed_result.as_deref(), Some("3"));
let main_text = doc.main_text();
assert!(
main_text.contains("on page 3\nPage two lead.")
&& main_text.contains("3\nabove\n3"),
"rendered-context hard breaks should advance computed PAGEREF relative, PAGEREF page, and PAGE output: {main_text:?}"
);
assert!(
!main_text.contains("stale distant relative")
&& !main_text.contains("99")
&& !main_text.contains("old relative")
&& !main_text.contains("stale current page"),
"computed rendered-context fields should not keep stale cached text: {main_text:?}"
);
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
}
#[test]
fn docx_page_and_page_ref_compute_structural_section_break_targets() {
let doc = Document::open(&page_ref_section_break_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 6);
assert_eq!(fields[0].kind, FieldKind::Page);
assert_eq!(fields[0].instruction, "PAGE \\* Arabic");
assert_eq!(fields[0].computed_result.as_deref(), Some("2"));
assert_eq!(fields[1].kind, FieldKind::Page);
assert_eq!(fields[1].instruction, "PAGE \\* Arabic");
assert_eq!(fields[1].computed_result.as_deref(), Some("4"));
assert_eq!(fields[2].kind, FieldKind::Page);
assert_eq!(fields[2].instruction, "PAGE \\* Arabic");
assert_eq!(fields[2].computed_result.as_deref(), Some("5"));
assert_eq!(fields[3].kind, FieldKind::PageRef);
assert_eq!(fields[3].instruction, "PAGEREF NextSection \\h");
assert_eq!(fields[3].computed_result.as_deref(), Some("2"));
assert_eq!(fields[4].kind, FieldKind::PageRef);
assert_eq!(fields[4].instruction, "PAGEREF EvenSection \\* roman");
assert_eq!(fields[4].computed_result.as_deref(), Some("iv"));
assert_eq!(fields[5].kind, FieldKind::PageRef);
assert_eq!(fields[5].instruction, "PAGEREF OddSection \\p");
assert_eq!(fields[5].computed_result.as_deref(), Some("above"));
let main_text = doc.main_text();
assert!(
main_text.contains("2\nPage three lead.\nEven section target\n4\nOdd section target\n5\n2\niv\nabove"),
"structural section-break PAGE and PAGEREF fields should render computed text: {main_text:?}"
);
assert!(
!main_text.contains("stale"),
"computed section-break PAGE and PAGEREF fields should not keep stale cached text: {main_text:?}"
);
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
}
#[test]
fn docx_page_ref_defers_content_paragraph_section_break_until_paragraph_end() {
let doc =
Document::open(&page_ref_content_paragraph_section_break_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 2);
assert_eq!(fields[0].kind, FieldKind::Page);
assert_eq!(fields[0].instruction, "PAGE");
assert_eq!(fields[0].computed_result.as_deref(), Some("1"));
assert_eq!(fields[1].kind, FieldKind::PageRef);
assert_eq!(fields[1].instruction, "PAGEREF BeforeSectionBreak \\h");
assert_eq!(fields[1].result, "stale before break");
assert_eq!(fields[1].computed_result.as_deref(), Some("1"));
let main_text = doc.main_text();
assert!(
main_text.contains("Before break1\nAfter break\n1"),
"section-break paragraph content should stay on the pre-break page: {main_text:?}"
);
assert!(
!main_text.contains("stale same-paragraph page")
&& !main_text.contains("stale before break"),
"computed fields should replace stale section-break paragraph text: {main_text:?}"
);
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
}
#[test]
fn docx_page_ref_computes_relative_target_before_content_paragraph_section_format() {
let doc =
Document::open(&page_ref_content_paragraph_section_format_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 2);
assert_eq!(fields[0].kind, FieldKind::PageRef);
assert_eq!(fields[0].instruction, "PAGEREF BeforeFormatBreak \\p");
assert_eq!(fields[0].result, "stale before");
assert_eq!(fields[0].computed_result.as_deref(), Some("on page 1"));
assert_eq!(fields[1].kind, FieldKind::PageRef);
assert_eq!(fields[1].instruction, "PAGEREF AfterFormatBreak \\p");
assert_eq!(fields[1].result, "stale after");
assert_eq!(fields[1].computed_result, None);
let main_text = doc.main_text();
assert!(
main_text.contains("Before format break\nAfter format break\non page 1\nstale after"),
"pre-break PAGEREF relative target should compute while the unsupported-format target remains cached: {main_text:?}"
);
assert!(
!main_text.contains("stale before"),
"computed pre-break relative PAGEREF should replace stale cached text: {main_text:?}"
);
let report = doc.report();
assert_eq!(
report.features.unsupported_field_kinds,
vec![FieldKindCount {
kind: FieldKind::PageRef,
count: 1,
}]
);
assert_eq!(
report.features.unsupported_field_reasons,
vec![FieldEvaluationReasonCount {
reason: FieldEvaluationReason::UnsupportedSwitch,
count: 1,
}]
);
}
#[test]
fn docx_page_ref_computes_default_next_page_section_break_target() {
let doc = Document::open(&page_ref_default_section_break_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 1);
assert_eq!(fields[0].kind, FieldKind::PageRef);
assert_eq!(fields[0].instruction, "PAGEREF DefaultSection \\h");
assert_eq!(fields[0].computed_result.as_deref(), Some("2"));
let main_text = doc.main_text();
assert!(
main_text.contains("2"),
"default next-page section-break PAGEREF should render computed text: {main_text:?}"
);
assert!(
!main_text.contains("stale default"),
"computed default section-break PAGEREF should not keep stale cached text: {main_text:?}"
);
}
#[test]
fn docx_page_ref_computes_page_break_before_targets() {
let doc = Document::open(&page_ref_page_break_before_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 4);
assert_eq!(fields[0].kind, FieldKind::PageRef);
assert_eq!(fields[0].instruction, "PAGEREF BreakBefore \\h");
assert_eq!(fields[0].computed_result.as_deref(), Some("2"));
assert_eq!(fields[1].kind, FieldKind::PageRef);
assert_eq!(fields[1].instruction, "PAGEREF BreakAfterIntro \\h");
assert_eq!(fields[1].computed_result.as_deref(), Some("3"));
assert_eq!(fields[2].kind, FieldKind::PageRef);
assert_eq!(
fields[2].instruction,
"PAGEREF RenderedBreakBefore \\* Ordinal"
);
assert_eq!(fields[2].computed_result.as_deref(), Some("5th"));
assert_eq!(fields[3].kind, FieldKind::PageRef);
assert_eq!(fields[3].instruction, "PAGEREF RenderedBreakBefore \\p");
assert_eq!(fields[3].computed_result.as_deref(), Some("above"));
let main_text = doc.main_text();
assert!(
main_text.contains("2\n3\n5th\nabove"),
"pageBreakBefore PAGEREF fields should render computed text: {main_text:?}"
);
assert!(
!main_text.contains("stale"),
"computed pageBreakBefore PAGEREF fields should not keep stale cached text: {main_text:?}"
);
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
}
#[test]
fn docx_page_section_context_ignores_old_paragraph_property_revisions() {
let doc = Document::open(&page_section_property_revision_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 3);
assert_eq!(fields[0].kind, FieldKind::Page);
assert_eq!(fields[0].instruction, "PAGE \\* Arabic");
assert_eq!(fields[0].result, "cached old page break page");
assert_eq!(fields[0].computed_result.as_deref(), Some("1"));
assert_eq!(
fields[1].kind,
FieldKind::DocumentStructure("SECTION".to_string())
);
assert_eq!(fields[1].instruction, "SECTION");
assert_eq!(fields[1].result, "cached old section");
assert_eq!(fields[1].computed_result.as_deref(), Some("1"));
assert_eq!(fields[2].kind, FieldKind::PageRef);
assert_eq!(fields[2].instruction, "PAGEREF CurrentBreak \\h");
assert_eq!(fields[2].result, "stale current break");
assert_eq!(fields[2].computed_result.as_deref(), Some("2"));
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
let main_text = doc.main_text();
assert!(main_text.contains("Intro page one."), "{main_text:?}");
assert!(main_text.contains("Current break target"), "{main_text:?}");
assert!(
!main_text.contains("cached old page break page"),
"{main_text:?}"
);
assert!(!main_text.contains("cached old section"), "{main_text:?}");
assert!(!main_text.contains("stale current break"), "{main_text:?}");
assert!(main_text.contains("1\n1"), "{main_text:?}");
assert!(main_text.contains("2"), "{main_text:?}");
}
#[test]
fn docx_page_ref_ignores_disabled_page_break_before() {
let doc = Document::open(&page_ref_disabled_page_break_before_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 1);
assert_eq!(fields[0].kind, FieldKind::PageRef);
assert_eq!(fields[0].instruction, "PAGEREF NoForcedBreak \\h");
assert_eq!(fields[0].computed_result.as_deref(), Some("2"));
let main_text = doc.main_text();
assert!(
main_text.contains("2") && !main_text.contains("stale disabled break"),
"disabled pageBreakBefore should not advance PAGEREF page context: {main_text:?}"
);
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
}
#[test]
fn docx_page_ref_applies_structural_section_page_number_restart() {
let doc = Document::open(&page_ref_section_page_number_restart_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 3);
assert_eq!(fields[0].kind, FieldKind::PageRef);
assert_eq!(fields[0].instruction, "PAGEREF Restarted \\h");
assert_eq!(fields[0].computed_result.as_deref(), Some("7"));
assert_eq!(fields[1].kind, FieldKind::PageRef);
assert_eq!(fields[1].instruction, "PAGEREF RestartedNext \\* ROMAN");
assert_eq!(fields[1].computed_result.as_deref(), Some("VIII"));
assert_eq!(fields[2].kind, FieldKind::PageRef);
assert_eq!(fields[2].instruction, "PAGEREF RestartedNext \\h\\p");
assert_eq!(fields[2].computed_result.as_deref(), Some("above"));
let main_text = doc.main_text();
assert!(
main_text.contains("7\nVIII\nabove"),
"section page-number restart should format displayed page labels: {main_text:?}"
);
assert!(
!main_text.contains("stale"),
"computed restarted-section PAGEREF fields should not keep stale cached text: {main_text:?}"
);
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
}
#[test]
fn docx_page_ref_computes_restarted_section_display_page_after_visible_intro() {
let doc = Document::open(&page_ref_visible_intro_section_page_number_restart_docx())
.expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 2);
assert_eq!(fields[0].kind, FieldKind::PageRef);
assert_eq!(fields[0].instruction, "PAGEREF RestartedAfterIntro \\h");
assert_eq!(fields[0].computed_result.as_deref(), Some("7"));
assert_eq!(fields[1].kind, FieldKind::PageRef);
assert_eq!(fields[1].instruction, "PAGEREF RestartedAfterIntro \\p");
assert_eq!(fields[1].computed_result.as_deref(), Some("above"));
let main_text = doc.main_text();
assert!(
main_text.contains("7")
&& main_text.contains("above")
&& !main_text.contains("stale restarted page")
&& !main_text.contains("stale restarted relative"),
"restarted section display page and same-segment relative position should compute: {main_text:?}"
);
let report = doc.report();
assert!(report.features.unsupported_field_reasons.is_empty());
}
#[test]
fn docx_page_and_page_ref_apply_trusted_section_page_number_formats() {
let doc = Document::open(&page_ref_section_page_number_format_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 10);
assert_eq!(fields[0].kind, FieldKind::Page);
assert_eq!(fields[0].instruction, "PAGE \\* Arabic");
assert_eq!(fields[0].computed_result.as_deref(), Some("3"));
assert_eq!(fields[1].kind, FieldKind::PageRef);
assert_eq!(fields[1].instruction, "PAGEREF RomanSection \\h");
assert_eq!(fields[1].computed_result.as_deref(), Some("iii"));
assert_eq!(fields[2].kind, FieldKind::PageRef);
assert_eq!(fields[2].instruction, "PAGEREF RomanSection \\* Arabic");
assert_eq!(fields[2].computed_result.as_deref(), Some("3"));
assert_eq!(fields[3].kind, FieldKind::PageRef);
assert_eq!(fields[3].instruction, "PAGEREF RomanSection \\p");
assert_eq!(fields[3].computed_result.as_deref(), Some("above"));
assert_eq!(fields[4].kind, FieldKind::Page);
assert_eq!(fields[4].instruction, "PAGE");
assert_eq!(fields[4].computed_result.as_deref(), Some("04"));
assert_eq!(fields[5].kind, FieldKind::PageRef);
assert_eq!(fields[5].instruction, "PAGEREF DecimalZeroSection \\h");
assert_eq!(fields[5].computed_result.as_deref(), Some("04"));
assert_eq!(fields[6].kind, FieldKind::PageRef);
assert_eq!(
fields[6].instruction,
"PAGEREF DecimalZeroSection \\* Arabic"
);
assert_eq!(fields[6].computed_result.as_deref(), Some("4"));
assert_eq!(fields[7].kind, FieldKind::Page);
assert_eq!(fields[7].instruction, "PAGE");
assert_eq!(fields[7].computed_result.as_deref(), Some("- 5 -"));
assert_eq!(fields[8].kind, FieldKind::PageRef);
assert_eq!(fields[8].instruction, "PAGEREF DashedSection \\h");
assert_eq!(fields[8].computed_result.as_deref(), Some("- 5 -"));
assert_eq!(fields[9].kind, FieldKind::PageRef);
assert_eq!(fields[9].instruction, "PAGEREF DashedSection \\* Arabic");
assert_eq!(fields[9].computed_result.as_deref(), Some("5"));
let main_text = doc.main_text();
assert!(
main_text.contains("3\niii\n3\nabove")
&& main_text.contains("04\n04\n4")
&& main_text.contains("- 5 -\n- 5 -\n5"),
"trusted section page-number formats should drive supported PAGE and PAGEREF text: {main_text:?}"
);
assert!(
!main_text.contains("stale roman current")
&& !main_text.contains("stale roman")
&& !main_text.contains("stale arabic override")
&& !main_text.contains("stale roman relative")
&& !main_text.contains("stale decimal current")
&& !main_text.contains("stale decimal zero")
&& !main_text.contains("stale decimal arabic")
&& !main_text.contains("stale dashed current")
&& !main_text.contains("stale dashed")
&& !main_text.contains("stale dashed arabic"),
"computed section-format PAGE and PAGEREF fields should replace stale cached text: {main_text:?}"
);
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
}
#[test]
fn docx_page_ref_applies_textual_section_page_number_formats() {
let doc =
Document::open(&page_ref_textual_section_page_number_format_docx()).expect("fixture opens");
let fields = doc.fields();
let expected = [
("PAGEREF LowerLetterSection \\h", "b"),
("PAGEREF LowerLetterSection \\* Arabic", "2"),
("PAGEREF UpperLetterSection \\h", "C"),
("PAGEREF UpperLetterSection \\* Arabic", "3"),
("PAGEREF UpperRomanSection \\h", "VI"),
("PAGEREF UpperRomanSection \\* Arabic", "6"),
("PAGEREF CardinalTextSection \\h", "five"),
("PAGEREF CardinalTextSection \\* Arabic", "5"),
("PAGEREF OrdinalTextSection \\h", "fifth"),
("PAGEREF OrdinalTextSection \\* Arabic", "5"),
];
assert_eq!(fields.len(), expected.len());
for (field, (instruction, computed)) in fields.iter().zip(expected) {
assert_eq!(field.kind, FieldKind::PageRef);
assert_eq!(field.instruction, instruction);
assert_eq!(field.computed_result.as_deref(), Some(computed));
}
let main_text = doc.main_text();
for computed in ["b", "C", "VI", "five", "fifth"] {
assert!(
main_text.contains(computed),
"textual section page-number formats should drive PAGEREF text: {main_text:?}"
);
}
assert!(
!main_text.contains("stale"),
"computed textual section PAGEREF fields should replace stale cached text: {main_text:?}"
);
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
}
#[test]
fn docx_page_ref_relative_unsupported_section_format_uses_arabic_fallback() {
let doc = Document::open(&page_ref_relative_unsupported_section_page_number_format_docx())
.expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 1);
assert_eq!(fields[0].kind, FieldKind::PageRef);
assert_eq!(fields[0].instruction, "PAGEREF UnsupportedFmt \\p");
assert_eq!(fields[0].result, "stale relative");
assert_eq!(fields[0].computed_result.as_deref(), Some("on page 2"));
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
let main_text = doc.main_text();
assert!(
main_text.contains("on page 2") && !main_text.contains("stale relative"),
"relative PAGEREF should use a deterministic fallback page label: {main_text:?}"
);
}
#[test]
fn docx_page_ref_relative_unsupported_section_format_explicit_override_is_computed() {
let doc = Document::open(&page_ref_relative_unsupported_section_format_override_docx())
.expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 1);
assert_eq!(fields[0].kind, FieldKind::PageRef);
assert_eq!(
fields[0].instruction,
"PAGEREF UnsupportedFmt \\p \\* Arabic"
);
assert_eq!(fields[0].result, "stale relative override");
assert_eq!(fields[0].computed_result.as_deref(), Some("on page 2"));
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
let main_text = doc.main_text();
assert!(
main_text.contains("on page 2") && !main_text.contains("stale relative override"),
"relative PAGEREF with an explicit Arabic override should compute in trusted context: {main_text:?}"
);
}
#[test]
fn docx_page_ref_relative_unsupported_even_odd_section_formats_use_arabic_fallback() {
let doc = Document::open(&page_ref_relative_unsupported_even_odd_section_formats_docx())
.expect("fixture opens");
let fields = doc.fields();
let expected = [
(
"PAGEREF EvenUnsupportedFmt \\p",
"stale even relative",
"on page 2",
),
(
"PAGEREF OddUnsupportedFmt \\p",
"stale odd relative",
"on page 5",
),
];
assert_eq!(fields.len(), expected.len());
for (field, (instruction, result, computed)) in fields.iter().zip(expected) {
assert_eq!(field.kind, FieldKind::PageRef);
assert_eq!(field.instruction, instruction);
assert_eq!(field.result, result);
assert_eq!(field.computed_result.as_deref(), Some(computed));
}
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
let main_text = doc.main_text();
assert!(
main_text.contains("on page 2")
&& main_text.contains("on page 5")
&& !main_text.contains("stale even relative")
&& !main_text.contains("stale odd relative"),
"relative PAGEREF should use fallback labels across trusted even/odd section starts: {main_text:?}"
);
}
#[test]
fn docx_page_ref_unsupported_section_format_explicit_override_is_computed() {
let doc = Document::open(&page_ref_unsupported_section_format_override_docx())
.expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 1);
assert_eq!(fields[0].kind, FieldKind::PageRef);
assert_eq!(
fields[0].instruction,
"PAGEREF UnsupportedFmt \\h \\* Arabic"
);
assert_eq!(fields[0].result, "stale override");
assert_eq!(fields[0].computed_result.as_deref(), Some("2"));
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
let main_text = doc.main_text();
assert!(main_text.contains("2"), "{main_text:?}");
assert!(!main_text.contains("stale override"), "{main_text:?}");
}
#[test]
fn docx_page_ref_applies_decimal_full_width_section_page_number_format() {
let doc = Document::open(&page_ref_decimal_full_width_section_page_number_format_docx())
.expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 2);
assert_eq!(fields[0].kind, FieldKind::PageRef);
assert_eq!(fields[0].instruction, "PAGEREF FullWidthSection \\h");
assert_eq!(fields[0].computed_result.as_deref(), Some("12"));
assert_eq!(fields[1].kind, FieldKind::PageRef);
assert_eq!(fields[1].instruction, "PAGEREF FullWidthSection \\* Arabic");
assert_eq!(fields[1].computed_result.as_deref(), Some("12"));
let main_text = doc.main_text();
assert!(
main_text.contains("12\n12"),
"decimalFullWidth section page-number format should drive supported PAGEREF text: {main_text:?}"
);
assert!(
!main_text.contains("stale fullwidth"),
"computed decimalFullWidth PAGEREF fields should replace stale cached text: {main_text:?}"
);
}
#[test]
fn docx_page_ref_applies_decimal_enclosed_circle_section_page_number_format() {
let doc = Document::open(&page_ref_decimal_enclosed_circle_section_page_number_format_docx())
.expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 2);
assert_eq!(fields[0].kind, FieldKind::PageRef);
assert_eq!(fields[0].instruction, "PAGEREF CircleSection \\h");
assert_eq!(fields[0].computed_result.as_deref(), Some("\u{246b}"));
assert_eq!(fields[1].kind, FieldKind::PageRef);
assert_eq!(fields[1].instruction, "PAGEREF CircleSection \\* Arabic");
assert_eq!(fields[1].computed_result.as_deref(), Some("12"));
let main_text = doc.main_text();
let expected = format!("{}\n12", "\u{246b}");
assert!(
main_text.contains(&expected),
"decimalEnclosedCircle section page-number format should drive supported PAGEREF text: {main_text:?}"
);
assert!(
!main_text.contains("stale circle"),
"computed decimalEnclosedCircle PAGEREF fields should replace stale cached text: {main_text:?}"
);
}
#[test]
fn docx_page_ref_applies_decimal_enclosed_punctuation_section_page_number_formats() {
let doc =
Document::open(&page_ref_decimal_enclosed_punctuation_section_page_number_format_docx())
.expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 4);
assert_eq!(fields[0].kind, FieldKind::PageRef);
assert_eq!(fields[0].instruction, "PAGEREF FullstopSection \\h");
assert_eq!(fields[0].computed_result.as_deref(), Some("\u{2493}"));
assert_eq!(fields[1].kind, FieldKind::PageRef);
assert_eq!(fields[1].instruction, "PAGEREF FullstopSection \\* Arabic");
assert_eq!(fields[1].computed_result.as_deref(), Some("12"));
assert_eq!(fields[2].kind, FieldKind::PageRef);
assert_eq!(fields[2].instruction, "PAGEREF ParenSection \\h");
assert_eq!(fields[2].computed_result.as_deref(), Some("\u{2480}"));
assert_eq!(fields[3].kind, FieldKind::PageRef);
assert_eq!(fields[3].instruction, "PAGEREF ParenSection \\* Arabic");
assert_eq!(fields[3].computed_result.as_deref(), Some("13"));
let main_text = doc.main_text();
assert!(
main_text.contains(&format!("{}\n12", "\u{2493}"))
&& main_text.contains(&format!("{}\n13", "\u{2480}")),
"decimal enclosed punctuation section page-number formats should drive supported PAGEREF text: {main_text:?}"
);
assert!(
!main_text.contains("stale fullstop") && !main_text.contains("stale paren"),
"computed decimal enclosed punctuation PAGEREF fields should replace stale cached text: {main_text:?}"
);
}
#[test]
fn docx_page_ref_applies_decimal_width_variant_section_page_number_formats() {
let doc = Document::open(&page_ref_decimal_width_variant_section_page_number_format_docx())
.expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 4);
assert_eq!(fields[0].kind, FieldKind::PageRef);
assert_eq!(fields[0].instruction, "PAGEREF HalfWidthSection \\h");
assert_eq!(fields[0].computed_result.as_deref(), Some("12"));
assert_eq!(fields[1].kind, FieldKind::PageRef);
assert_eq!(
fields[1].instruction,
"PAGEREF HalfWidthSection \\* ArabicDash"
);
assert_eq!(fields[1].computed_result.as_deref(), Some("- 12 -"));
assert_eq!(fields[2].kind, FieldKind::PageRef);
assert_eq!(fields[2].instruction, "PAGEREF FullWidthAltSection \\h");
assert_eq!(fields[2].computed_result.as_deref(), Some("13"));
assert_eq!(fields[3].kind, FieldKind::PageRef);
assert_eq!(
fields[3].instruction,
"PAGEREF FullWidthAltSection \\* Arabic"
);
assert_eq!(fields[3].computed_result.as_deref(), Some("13"));
let main_text = doc.main_text();
assert!(
main_text.contains("12\n- 12 -") && main_text.contains("13\n13"),
"decimal width variant section page-number formats should drive supported PAGEREF text: {main_text:?}"
);
assert!(
!main_text.contains("stale halfwidth") && !main_text.contains("stale fullwidth alt"),
"computed decimal width variant PAGEREF fields should replace stale cached text: {main_text:?}"
);
}
#[test]
fn docx_page_ref_applies_korean_section_page_number_formats() {
let doc =
Document::open(&page_ref_korean_section_page_number_format_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 4);
assert_eq!(fields[0].kind, FieldKind::PageRef);
assert_eq!(fields[0].instruction, "PAGEREF GanadaSection \\h");
assert_eq!(fields[0].computed_result.as_deref(), Some("\u{ac00}"));
assert_eq!(fields[1].kind, FieldKind::PageRef);
assert_eq!(fields[1].instruction, "PAGEREF GanadaSection \\* Arabic");
assert_eq!(fields[1].computed_result.as_deref(), Some("1"));
assert_eq!(fields[2].kind, FieldKind::PageRef);
assert_eq!(fields[2].instruction, "PAGEREF ChosungSection \\h");
assert_eq!(fields[2].computed_result.as_deref(), Some("\u{3134}"));
assert_eq!(fields[3].kind, FieldKind::PageRef);
assert_eq!(fields[3].instruction, "PAGEREF ChosungSection \\* Arabic");
assert_eq!(fields[3].computed_result.as_deref(), Some("2"));
let main_text = doc.main_text();
assert!(
main_text.contains(&format!("{}\n1", "\u{ac00}"))
&& main_text.contains(&format!("{}\n2", "\u{3134}")),
"Korean section page-number formats should drive supported PAGEREF text: {main_text:?}"
);
assert!(
!main_text.contains("stale ganada") && !main_text.contains("stale chosung"),
"computed Korean PAGEREF fields should replace stale cached text: {main_text:?}"
);
}
#[test]
fn docx_page_ref_applies_korean_numeric_section_page_number_formats() {
let doc = Document::open(&page_ref_korean_numeric_section_page_number_format_docx())
.expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 8);
assert_eq!(fields[0].kind, FieldKind::PageRef);
assert_eq!(fields[0].instruction, "PAGEREF KoreanDigitalSection \\h");
assert_eq!(fields[0].computed_result.as_deref(), Some("\u{c77c}"));
assert_eq!(fields[1].kind, FieldKind::PageRef);
assert_eq!(
fields[1].instruction,
"PAGEREF KoreanDigitalSection \\* Arabic"
);
assert_eq!(fields[1].computed_result.as_deref(), Some("1"));
assert_eq!(fields[2].kind, FieldKind::PageRef);
assert_eq!(fields[2].instruction, "PAGEREF KoreanCountingSection \\h");
assert_eq!(fields[2].computed_result.as_deref(), Some("\u{b458}"));
assert_eq!(fields[3].kind, FieldKind::PageRef);
assert_eq!(
fields[3].instruction,
"PAGEREF KoreanCountingSection \\* Arabic"
);
assert_eq!(fields[3].computed_result.as_deref(), Some("2"));
assert_eq!(fields[4].kind, FieldKind::PageRef);
assert_eq!(fields[4].instruction, "PAGEREF KoreanLegalSection \\h");
assert_eq!(fields[4].computed_result.as_deref(), Some("\u{c2ed}"));
assert_eq!(fields[5].kind, FieldKind::PageRef);
assert_eq!(
fields[5].instruction,
"PAGEREF KoreanLegalSection \\* Arabic"
);
assert_eq!(fields[5].computed_result.as_deref(), Some("10"));
assert_eq!(fields[6].kind, FieldKind::PageRef);
assert_eq!(fields[6].instruction, "PAGEREF KoreanDigital2Section \\h");
assert_eq!(fields[6].computed_result.as_deref(), Some("\u{c774}"));
assert_eq!(fields[7].kind, FieldKind::PageRef);
assert_eq!(
fields[7].instruction,
"PAGEREF KoreanDigital2Section \\* Arabic"
);
assert_eq!(fields[7].computed_result.as_deref(), Some("2"));
let main_text = doc.main_text();
assert!(
main_text.contains(&format!("{}\n1", "\u{c77c}"))
&& main_text.contains(&format!("{}\n2", "\u{b458}"))
&& main_text.contains(&format!("{}\n10", "\u{c2ed}"))
&& main_text.contains(&format!("{}\n2", "\u{c774}")),
"Korean numeric section page-number formats should drive supported PAGEREF text: {main_text:?}"
);
assert!(
!main_text.contains("stale korean digital")
&& !main_text.contains("stale korean counting")
&& !main_text.contains("stale korean legal")
&& !main_text.contains("stale korean digital2"),
"computed Korean numeric PAGEREF fields should replace stale cached text: {main_text:?}"
);
}
#[test]
fn docx_page_and_page_ref_apply_final_section_page_number_format() {
let doc =
Document::open(&page_ref_final_section_page_number_format_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 4);
assert_eq!(fields[0].kind, FieldKind::Page);
assert_eq!(fields[0].instruction, "PAGE \\* Arabic");
assert_eq!(fields[0].computed_result.as_deref(), Some("6"));
assert_eq!(fields[1].kind, FieldKind::PageRef);
assert_eq!(fields[1].instruction, "PAGEREF FinalSection \\h");
assert_eq!(fields[1].computed_result.as_deref(), Some("vi"));
assert_eq!(fields[2].kind, FieldKind::PageRef);
assert_eq!(fields[2].instruction, "PAGEREF FinalSection \\* Arabic");
assert_eq!(fields[2].computed_result.as_deref(), Some("6"));
assert_eq!(fields[3].kind, FieldKind::PageRef);
assert_eq!(fields[3].instruction, "PAGEREF FinalSection \\p");
assert_eq!(fields[3].computed_result.as_deref(), Some("above"));
let main_text = doc.main_text();
assert!(
main_text.contains("6\nvi\n6\nabove"),
"final section page-number format should apply to computed PAGE and PAGEREF output: {main_text:?}"
);
assert!(
!main_text.contains("stale final"),
"computed final-section PAGE and PAGEREF fields should replace stale cached text: {main_text:?}"
);
}
#[test]
fn docx_model_applies_final_section_alternate_content_page_number_format() {
let doc = Document::open(&page_ref_final_section_alternate_content_page_number_format_docx())
.expect("fixture opens");
let model = doc.model();
assert_eq!(model.setup.page_number_start, Some(5));
assert_eq!(
model.setup.page_number_format,
Some(PageNumberFormat::LowerRoman)
);
}
#[test]
fn docx_model_applies_final_section_alternate_content_page_setup() {
let doc =
Document::open(&final_section_alternate_content_page_setup_docx()).expect("fixture opens");
let page = doc.model().setup.page;
assert!(page.landscape);
assert_eq!(page.width_pt, 792.0);
assert_eq!(page.height_pt, 612.0);
assert_eq!(page.margin_pt, 36.0);
assert_eq!(page.margin_left_pt, Some(36.0));
assert_eq!(page.margin_right_pt, Some(54.0));
assert_eq!(page.margin_top_pt, Some(72.0));
assert_eq!(page.margin_bottom_pt, Some(90.0));
}
#[test]
fn docx_model_applies_final_section_alternate_content_section_setup() {
let doc = Document::open(&final_section_alternate_content_section_setup_docx())
.expect("fixture opens");
let setup = &doc.model().setup;
assert_eq!(setup.columns, Some(2));
assert_eq!(
setup.text_direction,
Some(TextDirection::TopToBottomRightToLeft)
);
let grid = setup.doc_grid.as_ref().expect("doc grid");
assert_eq!(grid.grid_type, DocGridType::Lines);
assert_eq!(grid.line_pitch, Some(360));
assert_eq!(grid.character_space, Some(120));
assert!(setup.title_page);
}
#[test]
fn docx_page_ref_final_section_numbering_ignores_old_paragraph_property_revisions() {
let doc = Document::open(&page_ref_final_section_old_paragraph_revision_docx())
.expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 3);
assert_eq!(fields[0].kind, FieldKind::Page);
assert_eq!(fields[0].instruction, "PAGE \\* Arabic");
assert_eq!(fields[0].result, "stale old revision final current");
assert_eq!(fields[0].computed_result.as_deref(), Some("6"));
assert_eq!(fields[1].kind, FieldKind::PageRef);
assert_eq!(fields[1].instruction, "PAGEREF FinalSection \\h");
assert_eq!(fields[1].result, "stale old revision final roman");
assert_eq!(fields[1].computed_result.as_deref(), Some("vi"));
assert_eq!(fields[2].kind, FieldKind::PageRef);
assert_eq!(fields[2].instruction, "PAGEREF FinalSection \\* Arabic");
assert_eq!(fields[2].result, "stale old revision final arabic");
assert_eq!(fields[2].computed_result.as_deref(), Some("6"));
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
let main_text = doc.main_text();
assert!(
main_text.contains("6\nvi\n6"),
"final section numbering should ignore old paragraph property revisions: {main_text:?}"
);
assert!(
!main_text.contains("stale old revision"),
"computed final-section fields should replace stale cached text: {main_text:?}"
);
}
#[test]
fn docx_page_ref_final_section_numbering_ignores_deleted_paragraph_section() {
let doc = Document::open(&page_ref_final_section_ignores_deleted_paragraph_section_docx())
.expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 3);
assert_eq!(fields[0].kind, FieldKind::PageRef);
assert_eq!(fields[0].instruction, "PAGEREF FinalSection \\h");
assert_eq!(fields[0].computed_result.as_deref(), Some("VI"));
assert_eq!(fields[1].kind, FieldKind::PageRef);
assert_eq!(fields[1].instruction, "PAGEREF FinalSection \\* Arabic");
assert_eq!(fields[1].computed_result.as_deref(), Some("6"));
assert_eq!(fields[2].kind, FieldKind::PageRef);
assert_eq!(fields[2].instruction, "PAGEREF FinalSection \\p");
assert_eq!(fields[2].computed_result.as_deref(), Some("above"));
let main_text = doc.main_text();
assert!(
main_text.contains("VI\n6\nabove"),
"accepted-current final section numbering should ignore deleted paragraph sectPr: {main_text:?}"
);
assert!(
!main_text.contains("stale final"),
"computed final-section PAGEREF fields should replace stale cached text: {main_text:?}"
);
}
#[test]
fn docx_page_ref_keeps_ambiguous_pre_marker_manual_break_cached() {
let doc = Document::open(&page_ref_visible_manual_break_before_rendered_hint_docx())
.expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 1);
assert_eq!(fields[0].kind, FieldKind::PageRef);
assert_eq!(fields[0].instruction, "PAGEREF AmbiguousTarget \\h");
assert_eq!(fields[0].result, "99");
assert_eq!(fields[0].computed_result, None);
let main_text = doc.main_text();
assert!(
main_text.contains("99"),
"pre-marker hard breaks after visible content should remain cached: {main_text:?}"
);
}
#[test]
fn docx_page_ref_computes_source_rendered_page_one_targets() {
let doc = Document::open(&page_ref_rendered_break_page_one_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 1);
assert_eq!(fields[0].kind, FieldKind::PageRef);
assert_eq!(fields[0].instruction, "PAGEREF Cover \\h");
assert_eq!(fields[0].result, "99");
assert_eq!(fields[0].computed_result.as_deref(), Some("1"));
let main_text = doc.main_text();
assert!(
main_text.contains("1") && !main_text.contains("99"),
"rendered-break PAGEREF should compute page-one targets once source page markers exist: {main_text:?}"
);
}
#[test]
fn docx_page_ref_ignores_deleted_source_rendered_page_breaks() {
let doc = Document::open(&page_ref_deleted_rendered_break_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 1);
assert_eq!(fields[0].kind, FieldKind::PageRef);
assert_eq!(fields[0].instruction, "PAGEREF Figure1 \\h");
assert_eq!(fields[0].result, "99");
assert_eq!(fields[0].computed_result, None);
let main_text = doc.main_text();
assert!(
main_text.contains("99"),
"deleted rendered page-break markers should not make visible PAGEREF values computable: {main_text:?}"
);
}
#[test]
fn docx_page_ref_keeps_leading_hard_break_target_over_later_rendered_hint() {
let doc = Document::open(&page_ref_leading_break_precedes_rendered_hint_docx())
.expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 1);
assert_eq!(fields[0].kind, FieldKind::PageRef);
assert_eq!(fields[0].instruction, "PAGEREF Figure1 \\h");
assert_eq!(fields[0].result, "99");
assert_eq!(fields[0].computed_result.as_deref(), Some("2"));
let main_text = doc.main_text();
assert!(
main_text.contains("2") && !main_text.contains("99"),
"leading hard-break target should not be overwritten by a later rendered-page hint: {main_text:?}"
);
}
#[test]
fn docx_page_ref_computed_fields_without_cached_results_are_materialized() {
let doc =
Document::open(&page_ref_rendered_break_no_cached_result_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 2);
assert_eq!(fields[0].kind, FieldKind::PageRef);
assert_eq!(fields[0].instruction, "PAGEREF FigureTwo \\h");
assert_eq!(fields[0].result, "");
assert_eq!(fields[0].computed_result.as_deref(), Some("2"));
assert_eq!(fields[1].kind, FieldKind::PageRef);
assert_eq!(
fields[1].instruction,
"PAGEREF \"FigureTwo\" \\* MERGEFORMAT"
);
assert_eq!(fields[1].result, "");
assert_eq!(fields[1].computed_result.as_deref(), Some("2"));
let main_text = doc.main_text();
assert!(
main_text.contains("2\n2"),
"computed PAGEREF fields without cached result runs should still read as computed text: {main_text:?}"
);
}
#[test]
fn docx_page_ref_wrapped_complex_field_uses_computed_result_in_body() {
let doc =
Document::open(&page_ref_rendered_break_wrapped_complex_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 1);
assert_eq!(fields[0].kind, FieldKind::PageRef);
assert_eq!(
fields[0].instruction,
"PAGEREF \"FigureTwo\" \\* MERGEFORMAT"
);
assert_eq!(fields[0].result, "old wrapped page");
assert_eq!(fields[0].computed_result.as_deref(), Some("2"));
let main_text = doc.main_text();
assert!(
main_text.contains("2") && !main_text.contains("old wrapped page"),
"complex PAGEREF inside accepted visible wrappers should read as computed text: {main_text:?}"
);
}
#[test]
fn docx_page_ref_uses_single_alternate_content_page_break_branch() {
let doc =
Document::open(&page_ref_alternate_content_rendered_break_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 1);
assert_eq!(fields[0].kind, FieldKind::PageRef);
assert_eq!(fields[0].instruction, "PAGEREF AltPage \\h");
assert_eq!(fields[0].result, "stale alternate page");
assert_eq!(fields[0].computed_result.as_deref(), Some("2"));
let main_text = doc.main_text();
assert!(
main_text.contains("2") && !main_text.contains("stale alternate page"),
"PAGEREF page context should not double-count Choice/Fallback page markers: {main_text:?}"
);
let report = doc.report();
assert!(report.features.unsupported_field_kinds.is_empty());
assert!(report.features.unsupported_field_reasons.is_empty());
}
#[cfg(feature = "render")]
#[test]
fn docx_page_ref_complex_field_is_counted_in_model_render_report() {
let doc = Document::open(&page_ref_docx()).expect("fixture opens");
let model = doc.model();
let rendered = rwml::render_pdf_with_report(&model);
assert_eq!(rendered.report.unsupported.fields, 2);
assert_eq!(
rendered.report.unsupported.field_kinds,
vec![rwml::FieldKindCount {
kind: FieldKind::PageRef,
count: 2,
}]
);
}
#[cfg(feature = "render")]
#[test]
fn docx_page_ref_computed_manual_break_fields_are_not_model_render_warnings() {
let doc = Document::open(&page_ref_manual_break_docx()).expect("fixture opens");
let model = doc.model();
let rendered = rwml::render_pdf_with_report(&model);
assert_eq!(rendered.report.unsupported.fields, 0);
assert!(rendered.report.unsupported.field_kinds.is_empty());
}
#[cfg(feature = "render")]
#[test]
fn docx_page_ref_computed_rendered_break_fields_are_not_model_render_warnings() {
let doc = Document::open(&page_ref_rendered_break_docx()).expect("fixture opens");
let model = doc.model();
let rendered = rwml::render_pdf_with_report(&model);
assert_eq!(rendered.report.unsupported.fields, 0);
assert!(rendered.report.unsupported.field_kinds.is_empty());
}
#[cfg(feature = "render")]
#[test]
fn docx_page_ref_no_cached_result_fields_are_not_model_render_warnings() {
let doc =
Document::open(&page_ref_rendered_break_no_cached_result_docx()).expect("fixture opens");
let model = doc.model();
let rendered = rwml::render_pdf_with_report(&model);
assert_eq!(rendered.report.unsupported.fields, 0);
assert!(rendered.report.unsupported.field_kinds.is_empty());
}
#[cfg(feature = "render")]
#[test]
fn docx_page_unsupported_switch_model_render_report_matches_document_reason_bucket() {
let doc = Document::open(&page_unsupported_switch_docx()).expect("fixture opens");
let expected_reasons = doc.report().features.unsupported_field_reasons;
assert_eq!(
expected_reasons,
vec![FieldEvaluationReasonCount {
reason: FieldEvaluationReason::UnsupportedSwitch,
count: 1,
}]
);
assert_eq!(
model_simple_field_reason_hints(&doc, |instruction| instruction.starts_with("PAGE")),
vec![(
"PAGE \\* Unknown".to_string(),
Some(FieldUnsupportedReason::UnsupportedSwitch),
)]
);
let model = doc.model();
let rendered = rwml::render_pdf_with_report(&model);
assert_eq!(rendered.report.unsupported.fields, 1);
assert_eq!(
rendered.report.unsupported.field_kinds,
vec![FieldKindCount {
kind: FieldKind::Page,
count: 1,
}]
);
assert_eq!(
rendered.report.unsupported.unsupported_field_reasons,
expected_reasons
);
}
#[cfg(feature = "render")]
#[test]
fn docx_page_ref_gap_model_render_report_matches_document_reason_buckets() {
let doc = Document::open(&page_ref_gap_docx()).expect("fixture opens");
let expected_reasons = doc.report().features.unsupported_field_reasons;
let model = doc.model();
let rendered = rwml::render_pdf_with_report(&model);
assert_eq!(rendered.report.unsupported.fields, 2);
assert_eq!(
rendered.report.unsupported.field_kinds,
vec![rwml::FieldKindCount {
kind: FieldKind::PageRef,
count: 2,
}]
);
assert_eq!(
rendered.report.unsupported.unsupported_field_reasons,
expected_reasons
);
}
#[cfg(feature = "render")]
#[test]
fn docx_page_ref_section_format_model_render_report_matches_document_reason_bucket() {
let doc =
Document::open(&page_ref_content_paragraph_section_format_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 2);
assert_eq!(fields[0].computed_result.as_deref(), Some("on page 1"));
assert_eq!(fields[1].computed_result, None);
let expected_reasons = doc.report().features.unsupported_field_reasons;
assert_eq!(
expected_reasons,
vec![FieldEvaluationReasonCount {
reason: FieldEvaluationReason::UnsupportedSwitch,
count: 1,
}]
);
let model = doc.model();
let rendered = rwml::render_pdf_with_report(&model);
assert_eq!(rendered.report.unsupported.fields, 1);
assert_eq!(
rendered.report.unsupported.field_kinds,
vec![FieldKindCount {
kind: FieldKind::PageRef,
count: 1,
}]
);
assert_eq!(
rendered.report.unsupported.unsupported_field_reasons,
expected_reasons
);
}
#[cfg(feature = "render")]
#[test]
fn docx_page_ref_complex_section_format_model_render_report_matches_document_reason_bucket() {
let doc = Document::open(&page_ref_complex_content_paragraph_section_format_docx())
.expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 1);
assert_eq!(fields[0].kind, FieldKind::PageRef);
assert_eq!(fields[0].computed_result, None);
let expected_reasons = doc.report().features.unsupported_field_reasons;
assert_eq!(
expected_reasons,
vec![FieldEvaluationReasonCount {
reason: FieldEvaluationReason::UnsupportedSwitch,
count: 1,
}]
);
let model = doc.model();
let rendered = rwml::render_pdf_with_report(&model);
assert_eq!(rendered.report.unsupported.fields, 1);
assert_eq!(
rendered.report.unsupported.field_kinds,
vec![FieldKindCount {
kind: FieldKind::PageRef,
count: 1,
}]
);
assert_eq!(
rendered.report.unsupported.unsupported_field_reasons,
expected_reasons
);
}
#[cfg(feature = "render")]
#[test]
fn docx_ref_gap_model_render_report_matches_document_reason_buckets() {
let doc = Document::open(&ref_gap_docx()).expect("fixture opens");
let expected_reasons = doc.report().features.unsupported_field_reasons;
let model = doc.model();
let rendered = rwml::render_pdf_with_report(&model);
assert_eq!(rendered.report.unsupported.fields, 2);
assert_eq!(
rendered.report.unsupported.field_kinds,
vec![rwml::FieldKindCount {
kind: FieldKind::Ref,
count: 2,
}]
);
assert_eq!(
rendered.report.unsupported.unsupported_field_reasons,
expected_reasons
);
}
#[cfg(feature = "render")]
#[test]
fn docx_ref_existing_target_numeric_gap_model_render_report_matches_document_reason_bucket() {
let doc = Document::open(&ref_existing_target_numeric_gap_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 1);
assert_eq!(fields[0].kind, FieldKind::Ref);
assert_eq!(fields[0].instruction, "REF PlainText \\n");
assert_eq!(fields[0].computed_result, None);
let expected_reasons = doc.report().features.unsupported_field_reasons;
assert_eq!(
expected_reasons,
vec![FieldEvaluationReasonCount {
reason: FieldEvaluationReason::NoComputedResult,
count: 1,
}]
);
let model = doc.model();
let rendered = rwml::render_pdf_with_report(&model);
assert_eq!(rendered.report.unsupported.fields, 1);
assert_eq!(
rendered.report.unsupported.field_kinds,
vec![FieldKindCount {
kind: FieldKind::Ref,
count: 1,
}]
);
assert_eq!(
rendered.report.unsupported.unsupported_field_reasons,
expected_reasons
);
}
#[cfg(feature = "render")]
#[test]
fn docx_empty_bookmark_ref_model_render_report_matches_document_reason_bucket() {
let doc = Document::open(&ref_empty_bookmark_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 3);
assert_eq!(fields[0].computed_result.as_deref(), Some(""));
assert_eq!(fields[1].computed_result.as_deref(), Some(""));
assert_eq!(fields[2].computed_result, None);
let expected_reasons = doc.report().features.unsupported_field_reasons;
assert_eq!(
expected_reasons,
vec![FieldEvaluationReasonCount {
reason: FieldEvaluationReason::UnresolvedBookmark,
count: 1,
}]
);
let model = doc.model();
let rendered = rwml::render_pdf_with_report(&model);
assert_eq!(rendered.report.unsupported.fields, 1);
assert_eq!(
rendered.report.unsupported.field_kinds,
vec![FieldKindCount {
kind: FieldKind::Ref,
count: 1,
}]
);
assert_eq!(
rendered.report.unsupported.unsupported_field_reasons,
expected_reasons
);
}
#[cfg(feature = "render")]
#[test]
fn docx_direct_bookmark_ref_gap_model_render_report_matches_document_reason_buckets() {
let doc = Document::open(&direct_bookmark_ref_switch_field_docx()).expect("fixture opens");
let expected_reasons = doc.report().features.unsupported_field_reasons;
assert_eq!(
expected_reasons,
vec![FieldEvaluationReasonCount {
reason: FieldEvaluationReason::NoComputedResult,
count: 1,
}]
);
let model = doc.model();
let rendered = rwml::render_pdf_with_report(&model);
assert_eq!(rendered.report.unsupported.fields, 1);
assert_eq!(
rendered.report.unsupported.field_kinds,
vec![FieldKindCount {
kind: FieldKind::Ref,
count: 1,
}]
);
assert_eq!(
rendered.report.unsupported.unsupported_field_reasons,
expected_reasons
);
}
#[cfg(feature = "render")]
#[test]
fn docx_set_backed_direct_ref_gap_model_render_report_matches_document_reason_bucket() {
let doc = Document::open(&set_backed_direct_ref_gap_docx()).expect("fixture opens");
let expected_reasons = doc.report().features.unsupported_field_reasons;
assert_eq!(
expected_reasons,
vec![FieldEvaluationReasonCount {
reason: FieldEvaluationReason::NoComputedResult,
count: 1,
}]
);
let model = doc.model();
let rendered = rwml::render_pdf_with_report(&model);
assert_eq!(rendered.report.unsupported.fields, 1);
assert_eq!(
rendered.report.unsupported.field_kinds,
vec![FieldKindCount {
kind: FieldKind::Ref,
count: 1,
}]
);
assert_eq!(
rendered.report.unsupported.unsupported_field_reasons,
expected_reasons
);
}
#[cfg(feature = "render")]
#[test]
fn docx_note_ref_gap_model_render_report_matches_document_reason_buckets() {
let doc = Document::open(¬e_ref_gap_docx()).expect("fixture opens");
let expected_reasons = doc.report().features.unsupported_field_reasons;
let model = doc.model();
let rendered = rwml::render_pdf_with_report(&model);
assert_eq!(rendered.report.unsupported.fields, 3);
assert_eq!(
rendered.report.unsupported.field_kinds,
vec![rwml::FieldKindCount {
kind: FieldKind::NoteRef,
count: 3,
}]
);
assert_eq!(
rendered.report.unsupported.unsupported_field_reasons,
expected_reasons
);
}
#[cfg(feature = "render")]
#[test]
fn docx_toc_computed_fields_are_not_model_render_warnings() {
let doc = Document::open(&complex_toc_heading_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 1);
assert_eq!(fields[0].kind, FieldKind::Toc);
assert_eq!(
fields[0].computed_result.as_deref(),
Some("EXECUTIVE SUMMARY\n RISKS")
);
assert!(doc.report().features.unsupported_field_kinds.is_empty());
let model = doc.model();
let rendered = rwml::render_pdf_with_report(&model);
assert_eq!(rendered.report.unsupported.fields, 0);
assert!(rendered.report.unsupported.field_kinds.is_empty());
assert!(rendered
.report
.unsupported
.unsupported_field_reasons
.is_empty());
}
#[cfg(feature = "render")]
#[test]
fn docx_toc_unsupported_switch_model_render_report_matches_document_reason_bucket() {
let doc = Document::open(&unsupported_toc_switch_docx()).expect("fixture opens");
let expected_reasons = doc.report().features.unsupported_field_reasons;
assert_eq!(
expected_reasons,
vec![FieldEvaluationReasonCount {
reason: FieldEvaluationReason::UnsupportedSwitch,
count: 1,
}]
);
let model = doc.model();
let rendered = rwml::render_pdf_with_report(&model);
assert_eq!(rendered.report.unsupported.fields, 1);
assert_eq!(
rendered.report.unsupported.field_kinds,
vec![FieldKindCount {
kind: FieldKind::Toc,
count: 1,
}]
);
assert_eq!(
rendered.report.unsupported.unsupported_field_reasons,
expected_reasons
);
}
#[cfg(feature = "render")]
#[test]
fn docx_hyperlink_unsupported_switch_model_render_report_matches_document_reason_bucket() {
let doc = Document::open(&hyperlink_gap_docx()).expect("fixture opens");
let fields = doc.fields();
assert_eq!(fields.len(), 4);
assert!(fields
.iter()
.all(|field| field.kind == FieldKind::Hyperlink));
assert!(fields.iter().any(|field| field.result == "Example"));
assert!(fields.iter().any(|field| field.result == "Cached link"));
assert!(fields
.iter()
.any(|field| field.result == "Cached tooltip-only link"));
assert!(fields
.iter()
.any(|field| field.result == "Cached trailing link"));
let expected_reasons = doc.report().features.unsupported_field_reasons;
assert_eq!(
expected_reasons,
vec![FieldEvaluationReasonCount {
reason: FieldEvaluationReason::UnsupportedSwitch,
count: 3,
}]
);
assert_eq!(
model_simple_field_reason_hints(&doc, |instruction| {
instruction.starts_with("HYPERLINK")
}),
vec![
(
"HYPERLINK \"https://example.com ".to_string(),
Some(FieldUnsupportedReason::UnsupportedSwitch),
),
(
"HYPERLINK \\o \"tip\"".to_string(),
Some(FieldUnsupportedReason::UnsupportedSwitch),
),
(
"HYPERLINK \"https://example.com\" extra".to_string(),
Some(FieldUnsupportedReason::UnsupportedSwitch),
),
]
);
let model = doc.model();
let rendered = rwml::render_pdf_with_report(&model);
assert_eq!(rendered.report.unsupported.fields, 3);
assert_eq!(
rendered.report.unsupported.field_kinds,
vec![FieldKindCount {
kind: FieldKind::Hyperlink,
count: 3,
}]
);
assert_eq!(
rendered.report.unsupported.unsupported_field_reasons,
expected_reasons
);
}
#[test]
fn field_kind_reports_canonical_names() {
assert_eq!(FieldKind::Hyperlink.as_str(), "HYPERLINK");
assert_eq!(FieldKind::Page.as_str(), "PAGE");
assert_eq!(FieldKind::Toc.as_str(), "TOC");
assert_eq!(FieldKind::Filename.as_str(), "FILENAME");
assert_eq!(FieldKind::MergeField.as_str(), "MERGEFIELD");
assert_eq!(FieldKind::Ref.as_str(), "REF");
assert_eq!(FieldKind::PageRef.as_str(), "PAGEREF");
assert_eq!(FieldKind::NoteRef.as_str(), "NOTEREF");
assert_eq!(FieldKind::TocEntry.as_str(), "TC");
assert_eq!(FieldKind::Sequence.as_str(), "SEQ");
assert_eq!(FieldKind::DocumentInfo("DATE".to_string()).as_str(), "DATE");
assert_eq!(
FieldKind::from_instruction("CATEGORY"),
FieldKind::DocumentInfo("CATEGORY".to_string())
);
assert_eq!(
FieldKind::from_instruction("CONTENTSTATUS"),
FieldKind::DocumentInfo("CONTENTSTATUS".to_string())
);
assert_eq!(
FieldKind::from_instruction("VERSION"),
FieldKind::DocumentInfo("VERSION".to_string())
);
assert_eq!(
FieldKind::from_instruction("CREATOR"),
FieldKind::DocumentInfo("CREATOR".to_string())
);
assert_eq!(
FieldKind::from_instruction("DESCRIPTION"),
FieldKind::DocumentInfo("DESCRIPTION".to_string())
);
assert_eq!(
FieldKind::from_instruction("KEYWORD"),
FieldKind::DocumentInfo("KEYWORD".to_string())
);
assert_eq!(
FieldKind::from_instruction("LASTMODIFIEDBY"),
FieldKind::DocumentInfo("LASTMODIFIEDBY".to_string())
);
assert_eq!(
FieldKind::from_instruction("APPLICATION"),
FieldKind::DocumentInfo("APPLICATION".to_string())
);
assert_eq!(
FieldKind::from_instruction("APPVERSION"),
FieldKind::DocumentInfo("APPVERSION".to_string())
);
assert_eq!(
FieldKind::from_instruction("MANAGER"),
FieldKind::DocumentInfo("MANAGER".to_string())
);
assert_eq!(
FieldKind::from_instruction("COMPANY"),
FieldKind::DocumentInfo("COMPANY".to_string())
);
assert_eq!(
FieldKind::from_instruction("HYPERLINKBASE"),
FieldKind::DocumentInfo("HYPERLINKBASE".to_string())
);
assert_eq!(
FieldKind::from_instruction("DOCSECURITY"),
FieldKind::DocumentInfo("DOCSECURITY".to_string())
);
assert_eq!(
FieldKind::from_instruction("LINKSUPTODATE"),
FieldKind::DocumentInfo("LINKSUPTODATE".to_string())
);
assert_eq!(FieldKind::Dynamic("IF".to_string()).as_str(), "IF");
assert_eq!(
FieldKind::InsertedContent("INCLUDETEXT".to_string()).as_str(),
"INCLUDETEXT"
);
assert_eq!(
FieldKind::MailMerge("ADDRESSBLOCK".to_string()).as_str(),
"ADDRESSBLOCK"
);
assert_eq!(
FieldKind::ReferenceIndex("BIBLIOGRAPHY".to_string()).as_str(),
"BIBLIOGRAPHY"
);
assert_eq!(
FieldKind::Numbering("AUTONUM".to_string()).as_str(),
"AUTONUM"
);
assert_eq!(
FieldKind::DocumentStructure("SECTION".to_string()).as_str(),
"SECTION"
);
assert_eq!(FieldKind::Display("EQ".to_string()).as_str(), "EQ");
assert_eq!(
FieldKind::Action("MACROBUTTON".to_string()).as_str(),
"MACROBUTTON"
);
assert_eq!(
FieldKind::Compatibility("PRIVATE".to_string()).as_str(),
"PRIVATE"
);
assert_eq!(
FieldKind::Barcode("DISPLAYBARCODE".to_string()).as_str(),
"DISPLAYBARCODE"
);
assert_eq!(
FieldKind::FormField("FORMTEXT".to_string()).as_str(),
"FORMTEXT"
);
assert_eq!(FieldKind::Unknown("custom".to_string()).as_str(), "custom");
}
#[test]
fn set_field_result_updates_simple_and_complex_cached_results() {
let mut doc = Document::open(&field_docx()).expect("fixture opens");
doc.set_field_result(0, "7").expect("update PAGE result");
doc.set_field_result(5, "renamed.docx")
.expect("update FILENAME result");
let saved = doc.save().expect("save edited docx");
let mut reopened = Document::open(&saved).expect("reopen edited docx");
let fields = reopened.fields();
assert_eq!(fields[0].kind, FieldKind::Page);
assert_eq!(fields[0].instruction, "PAGE");
assert_eq!(fields[0].result, "7");
assert_eq!(fields[5].kind, FieldKind::Filename);
assert_eq!(fields[5].instruction, "FILENAME \\p");
assert_eq!(fields[5].result, "renamed.docx");
assert!(reopened.set_field_result(6, "missing").is_err());
}
#[test]
fn set_field_result_skips_deleted_body_fields() {
let fixture = docx_fixture(&[
(
"[Content_Types].xml",
r#"<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>"#,
),
(
"_rels/.rels",
r#"<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>"#,
),
(
"word/document.xml",
r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:del w:id="1"><w:p><w:fldSimple w:instr=" PAGE "><w:r><w:delText>deleted page</w:delText></w:r></w:fldSimple></w:p></w:del><w:moveFrom w:id="2"><w:p><w:fldSimple w:instr=" CUSTOM moved "><w:r><w:delText>moved page</w:delText></w:r></w:fldSimple></w:p></w:moveFrom><w:p><w:fldSimple w:instr=" PAGE "><w:r><w:t>1</w:t></w:r></w:fldSimple></w:p></w:body></w:document>"#,
),
]);
let mut doc = Document::open(&fixture).expect("fixture opens");
assert_eq!(doc.fields().len(), 1);
doc.set_field_result(0, "7")
.expect("visible field result updated");
let saved = doc.save().expect("save edited docx");
let body = String::from_utf8(unzip_parts(&saved)["word/document.xml"].clone()).unwrap();
assert!(
body.contains("<w:delText>deleted page</w:delText>"),
"{body}"
);
assert!(body.contains("<w:delText>moved page</w:delText>"), "{body}");
let reopened = Document::open(&saved).expect("reopen edited docx");
let fields = reopened.fields();
assert_eq!(fields.len(), 1);
assert_eq!(fields[0].result, "7");
}
#[test]
fn set_field_result_uses_fields_order_for_nested_complex_fields() {
let mut doc = Document::open(&nested_complex_field_docx()).expect("fixture opens");
doc.set_field_result(1, "Outer Updated")
.expect("update outer nested field result");
let saved = doc.save().expect("save edited docx");
let reopened = Document::open(&saved).expect("reopen edited docx");
let fields = reopened.fields();
assert_eq!(fields.len(), 2);
assert_eq!(fields[1].instruction, "CUSTOM outer");
assert_eq!(fields[1].result, "Outer Updated");
}
#[test]
fn set_field_result_rejects_note_field_indexes_without_mutation() {
let fixture = note_body_field_docx();
let before = unzip_parts(&fixture);
let mut doc = Document::open(&fixture).expect("fixture opens");
assert_eq!(doc.fields().len(), 2);
let err = doc
.set_field_result(0, "changed.docx")
.expect_err("note field index rejected");
assert!(
err.to_string().contains("editable body field range"),
"{err}"
);
assert!(doc.edited_parts().is_empty());
let after = unzip_parts(&doc.save().expect("save rejected edit"));
assert_eq!(
before.get("word/footnotes.xml"),
after.get("word/footnotes.xml"),
"rejected note field edit should not mutate footnotes.xml"
);
assert_eq!(
before.get("word/endnotes.xml"),
after.get("word/endnotes.xml"),
"rejected note field edit should not mutate endnotes.xml"
);
}
#[test]
fn set_field_result_writes_tabs_and_breaks_as_markers() {
let mut doc = Document::open(&field_docx()).expect("fixture opens");
doc.set_field_result(0, "Line 1\nLine\t2")
.expect("update simple field result");
doc.set_field_result(5, "Path\nName\t2")
.expect("update complex field result");
let saved = doc.save().expect("save edited docx");
let parts = unzip_parts(&saved);
let body = String::from_utf8(parts["word/document.xml"].clone()).unwrap();
assert!(
body.contains("<w:t>Line 1</w:t><w:br/><w:t>Line</w:t><w:tab/><w:t>2</w:t>"),
"simple field result did not use WML markers: {body}"
);
assert!(
body.contains("<w:t>Path</w:t><w:br/><w:t>Name</w:t><w:tab/><w:t>2</w:t>"),
"complex field result did not use WML markers: {body}"
);
let reopened = Document::open(&saved).expect("reopen edited docx");
let fields = reopened.fields();
assert_eq!(fields[0].result, "Line 1\nLine\t2");
assert_eq!(fields[5].result, "Path\nName\t2");
}