ElyTable: a filtered range keeps its rows only for a cell inside it (R2.9)
This commit is contained in:
3 files changed
+61
-12
No files matched your search
@@ -18,6 +18,33 @@ const BLOCK: &str = r#"<?xml version="1.0" encoding="UTF-8"?>
|
||||
</table:table></office:spreadsheet></office:body>
|
||||
</office:document>"#;
|
||||
|
||||
/// Two blocks: A1:A5 as in `BLOCK`, and D1:D3.
|
||||
const TWO: &str = r#"<?xml version="1.0" encoding="UTF-8"?>
|
||||
<office:document xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0"
|
||||
xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0"
|
||||
xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0" office:version="1.3" office:mimetype="application/vnd.oasis.opendocument.spreadsheet">
|
||||
<office:body><office:spreadsheet><table:table table:name="S">
|
||||
<table:table-row><table:table-cell><text:p>Name</text:p></table:table-cell><table:table-cell table:number-columns-repeated="2"/><table:table-cell><text:p>Other</text:p></table:table-cell></table:table-row>
|
||||
<table:table-row><table:table-cell office:value-type="float" office:value="1"><text:p>1</text:p></table:table-cell><table:table-cell table:number-columns-repeated="2"/><table:table-cell office:value-type="float" office:value="9"><text:p>9</text:p></table:table-cell></table:table-row>
|
||||
<table:table-row><table:table-cell office:value-type="float" office:value="2"><text:p>2</text:p></table:table-cell><table:table-cell table:number-columns-repeated="2"/><table:table-cell office:value-type="float" office:value="10"><text:p>10</text:p></table:table-cell></table:table-row>
|
||||
<table:table-row><table:table-cell office:value-type="float" office:value="3"><text:p>3</text:p></table:table-cell></table:table-row>
|
||||
<table:table-row><table:table-cell office:value-type="float" office:value="6"><text:p>6</text:p></table:table-cell></table:table-row>
|
||||
</table:table></office:spreadsheet></office:body>
|
||||
</office:document>"#;
|
||||
|
||||
/// The book saved as flat XML.
|
||||
fn saved(worker: &mut Worker, doc: &Doc, dir: &std::path::Path) -> String {
|
||||
let out = dir.join("kept.fods");
|
||||
doc.save_as(worker, &crate::file_url(&out), "fods").expect("saves");
|
||||
std::fs::read_to_string(&out).expect("the saved book")
|
||||
}
|
||||
|
||||
/// Whether the row holding `value` is hidden by a filter.
|
||||
fn hidden(xml: &str, value: &str) -> bool {
|
||||
let before = &xml[..xml.find(&format!("office:value=\"{value}\"")).expect("the value")];
|
||||
before[before.rfind("<table:table-row").expect("its row")..].contains("table:visibility=\"filter\"")
|
||||
}
|
||||
|
||||
/// Column A's filter entries.
|
||||
fn entries(worker: &mut Worker, doc: &Doc) -> Vec<String> {
|
||||
let query = sheet::cell_query(sheet::FILTER, 0, 0);
|
||||
@@ -38,13 +65,9 @@ fn keep_one(worker: &mut Worker, doc: &Doc, dir: &std::path::Path) -> (String, b
|
||||
worker.run(doc, "cell.goto", &["A1"]).expect("A1");
|
||||
let one = r#"{"column":0,"conditions":[{"op":"values","values":["1"]}]}"#;
|
||||
worker.run(doc, "data.filter", &[one]).expect("keeps 1");
|
||||
let out = dir.join("kept.fods");
|
||||
doc.save_as(worker, &crate::file_url(&out), "fods").expect("saves");
|
||||
let xml = std::fs::read_to_string(&out).expect("the saved book");
|
||||
let xml = saved(worker, doc, dir);
|
||||
let range = xml.split("table:target-range-address=\"").nth(1).expect("a filter range");
|
||||
let total = &xml[..xml.find("office:value=\"6\"").expect("the total")];
|
||||
let row = &total[total.rfind("<table:table-row").expect("its row")..];
|
||||
(range[..range.find('"').expect("closed")].to_string(), row.contains("table:visibility=\"filter\""))
|
||||
(range[..range.find('"').expect("closed")].to_string(), hidden(&xml, "6"))
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -104,3 +127,28 @@ fn a_saved_autofilter_range_keeps_its_rows_when_reopened() {
|
||||
assert_eq!(keep_one(&mut worker, &doc, dir.path()), ("S.A1:S.A4".into(), false), "{format}");
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn one_cell_in_another_block_filters_that_block() {
|
||||
if install().is_none() {
|
||||
eprintln!("SKIP: no pinned LOK build");
|
||||
return;
|
||||
}
|
||||
let (dir, mut worker, doc) = open_book(TWO);
|
||||
worker.run(&doc, "cell.goto", &["A1:A4"]).expect("marks the block");
|
||||
worker.run(&doc, "data.autofilter", &[]).expect("filters A");
|
||||
worker.run(&doc, "cell.goto", &["D1"]).expect("D1");
|
||||
let nine = r#"{"conditions":[{"field":3,"op":"equals","value":"9"}]}"#;
|
||||
worker.run(&doc, "data.filter", &[nine]).expect("keeps 9");
|
||||
let xml = saved(&mut worker, &doc, dir.path());
|
||||
assert!(hidden(&xml, "10") && !hidden(&xml, "9"), "D keeps 9 alone");
|
||||
assert!(!hidden(&xml, "3") && !hidden(&xml, "6"), "A's rows past D stay");
|
||||
let (_dir, mut worker, doc) = open_book(TWO);
|
||||
worker.run(&doc, "cell.goto", &["A1:A4"]).expect("marks the block");
|
||||
worker.run(&doc, "data.autofilter", &[]).expect("filters A");
|
||||
worker.run(&doc, "cell.goto", &["D1"]).expect("D1");
|
||||
worker.run(&doc, "data.autofilter", &[]).expect("filters D");
|
||||
let json = worker.values(&doc, &sheet::cell_query(sheet::FILTER, 3, 0)).expect("D's entries");
|
||||
let entries: Vec<String> = sheet::filter_values(&json).expect("parses").entries.into_iter().map(|e| e.text).collect();
|
||||
assert_eq!(entries, ["9", "10"], "an AutoFilter from D1 is D's");
|
||||
}
|
||||
Reference in new issue
Block a user