t5rExp2flV3K4p<
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
N$N=f6?k5HKzX0;%s7(L>
literal 0
HcmV?d00001
diff --git a/resources/test/any_sheets.xlsx b/resources/test/any_sheets.xlsx
new file mode 100644
index 0000000000000000000000000000000000000000..693894d89566ebfacd8f4807a4a13d6b53837842
GIT binary patch
literal 14804
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
LE3jex> = wrk.read_stdout(&mut cmd);
+ let expected = vec![
+ svec![
+ "index",
+ "sheet_name",
+ "type",
+ "visible",
+ "headers",
+ "num_columns",
+ "num_rows",
+ "safe_headers",
+ "safe_headers_count",
+ "unsafe_headers",
+ "unsafe_headers_count",
+ "duplicate_headers_count"
+ ],
+ svec![
+ "0",
+ "Visible",
+ "[\"1\", \"2\"]",
+ "WorkSheet",
+ "Visible",
+ "2",
+ "5",
+ "[]",
+ "0",
+ "[\"1\", \"2\"]",
+ "2",
+ "0"
+ ],
+ svec![
+ "1",
+ "Hidden",
+ "[\"1\", \"2\"]",
+ "WorkSheet",
+ "Hidden",
+ "2",
+ "3",
+ "[]",
+ "0",
+ "[\"1\", \"2\"]",
+ "2",
+ "0"
+ ],
+ svec![
+ "2",
+ "VeryHidden",
+ "[]",
+ "WorkSheet",
+ "VeryHidden",
+ "0",
+ "0",
+ "[]",
+ "0",
+ "[]",
+ "0",
+ "0"
+ ],
+ svec![
+ "3",
+ "Chart",
+ "[\"1\", \"2\"]",
+ "ChartSheet",
+ "Visible",
+ "2",
+ "3",
+ "[]",
+ "0",
+ "[\"1\", \"2\"]",
+ "2",
+ "0"
+ ],
+ ];
+ assert_eq!(got, expected);
+ wrk.assert_success(&mut cmd);
+}
+
+#[test]
+fn excel_metadata_sheet_types_xlsx() {
+ let wrk = Workdir::new("excel_metadata_sheet_types_xlsx");
+
+ let xlsx_file = wrk.load_test_file("any_sheets.xlsx");
+
+ let mut cmd = wrk.command("excel");
+ cmd.arg("--metadata").arg("csv").arg(xlsx_file);
+
+ let got: Vec> = wrk.read_stdout(&mut cmd);
+ let expected = vec![
+ svec![
+ "index",
+ "sheet_name",
+ "type",
+ "visible",
+ "headers",
+ "num_columns",
+ "num_rows",
+ "safe_headers",
+ "safe_headers_count",
+ "unsafe_headers",
+ "unsafe_headers_count",
+ "duplicate_headers_count"
+ ],
+ svec![
+ "0",
+ "Visible",
+ "[\"1\", \"2\"]",
+ "WorkSheet",
+ "Visible",
+ "2",
+ "5",
+ "[]",
+ "0",
+ "[\"1\", \"2\"]",
+ "2",
+ "0"
+ ],
+ svec![
+ "1",
+ "Hidden",
+ "[]",
+ "WorkSheet",
+ "Hidden",
+ "0",
+ "0",
+ "[]",
+ "0",
+ "[]",
+ "0",
+ "0"
+ ],
+ svec![
+ "2",
+ "VeryHidden",
+ "[]",
+ "WorkSheet",
+ "VeryHidden",
+ "0",
+ "0",
+ "[]",
+ "0",
+ "[]",
+ "0",
+ "0"
+ ],
+ // we don't get metadata for chart sheets in xlsx
+ svec![
+ "3",
+ "Chart",
+ "[]",
+ "ChartSheet",
+ "Visible",
+ "0",
+ "0",
+ "[]",
+ "0",
+ "[]",
+ "0",
+ "0"
+ ],
+ ];
+ assert_eq!(got, expected);
+ wrk.assert_success(&mut cmd);
+}
+
+#[test]
+fn excel_metadata_sheet_types_xlsb() {
+ let wrk = Workdir::new("excel_metadata_sheet_types_xlsb");
+
+ let xlsb_file = wrk.load_test_file("any_sheets.xlsb");
+
+ let mut cmd = wrk.command("excel");
+ cmd.arg("--metadata").arg("csv").arg(xlsb_file);
+
+ let got: Vec> = wrk.read_stdout(&mut cmd);
+ let expected = vec![
+ svec![
+ "index",
+ "sheet_name",
+ "type",
+ "visible",
+ "headers",
+ "num_columns",
+ "num_rows",
+ "safe_headers",
+ "safe_headers_count",
+ "unsafe_headers",
+ "unsafe_headers_count",
+ "duplicate_headers_count"
+ ],
+ svec![
+ "0",
+ "Visible",
+ "[\"1\", \"2\"]",
+ "WorkSheet",
+ "Visible",
+ "2",
+ "5",
+ "[]",
+ "0",
+ "[\"1\", \"2\"]",
+ "2",
+ "0"
+ ],
+ svec![
+ "1",
+ "Hidden",
+ "[]",
+ "WorkSheet",
+ "Hidden",
+ "0",
+ "0",
+ "[]",
+ "0",
+ "[]",
+ "0",
+ "0"
+ ],
+ svec![
+ "2",
+ "VeryHidden",
+ "[]",
+ "WorkSheet",
+ "VeryHidden",
+ "0",
+ "0",
+ "[]",
+ "0",
+ "[]",
+ "0",
+ "0"
+ ],
+ // we don't get metadata for chart sheets in xlsb
+ svec![
+ "3",
+ "Chart",
+ "[]",
+ "ChartSheet",
+ "Visible",
+ "0",
+ "0",
+ "[]",
+ "0",
+ "[]",
+ "0",
+ "0"
+ ],
+ ];
+ assert_eq!(got, expected);
+ wrk.assert_success(&mut cmd);
+}
+
+#[test]
+fn excel_metadata_sheet_types_ods() {
+ let wrk = Workdir::new("excel_metadata_sheet_types_ods");
+
+ let ods_file = wrk.load_test_file("any_sheets.ods");
+
+ let mut cmd = wrk.command("excel");
+ cmd.arg("--metadata").arg("csv").arg(ods_file);
+
+ let got: Vec> = wrk.read_stdout(&mut cmd);
+ let expected = vec![
+ svec![
+ "index",
+ "sheet_name",
+ "type",
+ "visible",
+ "headers",
+ "num_columns",
+ "num_rows",
+ "safe_headers",
+ "safe_headers_count",
+ "unsafe_headers",
+ "unsafe_headers_count",
+ "duplicate_headers_count"
+ ],
+ svec![
+ "0",
+ "Visible",
+ "[\"1\", \"2\"]",
+ "WorkSheet",
+ "Visible",
+ "2",
+ "5",
+ "[]",
+ "0",
+ "[\"1\", \"2\"]",
+ "2",
+ "0"
+ ],
+ svec![
+ "1",
+ "Hidden",
+ "[]",
+ "WorkSheet",
+ "Hidden",
+ "0",
+ "0",
+ "[]",
+ "0",
+ "[]",
+ "0",
+ "0"
+ ],
+ svec![
+ "2",
+ "VeryHidden",
+ "[]",
+ "WorkSheet",
+ "Hidden",
+ "0",
+ "0",
+ "[]",
+ "0",
+ "[]",
+ "0",
+ "0"
+ ],
+ svec![
+ "3",
+ "Chart",
+ "[]",
+ "WorkSheet",
+ "Visible",
+ "0",
+ "0",
+ "[]",
+ "0",
+ "[]",
+ "0",
+ "0"
+ ],
+ ];
+ assert_eq!(got, expected);
+ wrk.assert_success(&mut cmd);
+}
+
#[test]
fn excel_message() {
let wrk = Workdir::new("excel_message");
@@ -804,7 +1201,7 @@ fn excel_empty_sheet2_message() {
cmd.arg("--sheet").arg("Sheet1").arg(xls_file);
let got = wrk.output_stderr(&mut cmd);
- assert_eq!(got, "\"Sheet1\" sheet is empty\n");
+ assert_eq!(got, "\"Sheet1\" sheet is empty.\n");
wrk.assert_err(&mut cmd);
}
From 4c2d9fff5274d4ce8867ca62f67f1bee147ffcab Mon Sep 17 00:00:00 2001
From: Joel Natividad <1980690+jqnatividad@users.noreply.github.com>
Date: Sat, 2 Sep 2023 09:43:51 -0400
Subject: [PATCH 4/4] add lint allow for clippy::implicit_clone
false positive lint warning as we actually need to clone for iter().enumerate() later
---
src/cmd/excel.rs | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/cmd/excel.rs b/src/cmd/excel.rs
index 01c06e09d..20bb0e0cd 100644
--- a/src/cmd/excel.rs
+++ b/src/cmd/excel.rs
@@ -258,6 +258,7 @@ pub fn run(argv: &[&str]) -> CliResult<()> {
return fail!("No sheets found.");
}
let num_sheets = sheet_names.len();
+ #[allow(clippy::redundant_clone)]
let sheet_vec = sheet_names.to_owned();
let mut wtr = Config::new(&args.flag_output)