use excelreader::workbook::Workbook;
use excelreader::CellType;
fn fixture(name: &str) -> String {
let root = std::path::Path::new(env!("CARGO_MANIFEST_DIR"))
.parent()
.and_then(|p| p.parent())
.expect("repo root is two levels above the crate");
root.join(name).to_string_lossy().into_owned()
}
#[test]
fn cursor_reads_the_header_row() {
let mut workbook = Workbook::open(&fixture("RealExcel.xlsx")).expect("open");
let mut cursor = workbook.rows();
let row = cursor.next_row().expect("a first row").expect("no error");
let names: Vec<String> = row.iter().map(|cell| cell.as_str().unwrap().to_string()).collect();
assert!(names.contains(&"Coluna1".to_string()), "got {names:?}");
assert!(names.contains(&"Coluna3".to_string()), "got {names:?}");
}
#[test]
fn cursor_terminates_cleanly() {
let mut workbook = Workbook::open(&fixture("RealExcel.xlsx")).expect("open");
let mut counted = 0usize;
{
let mut cursor = workbook.rows();
while let Some(row) = cursor.next_row() {
row.expect("no error mid-sheet");
counted += 1;
}
}
assert!(counted > 1, "fixture should have a header plus data rows");
let mut cursor = workbook.rows();
assert!(cursor.next_row().is_none());
}
#[test]
fn move_to_sheet_resets_the_cursor() {
let mut workbook = Workbook::open(&fixture("RealExcel.xlsx")).expect("open");
let first: Vec<String> = {
let mut cursor = workbook.rows();
let row = cursor.next_row().expect("row").expect("ok");
row.iter().map(|c| c.as_str().unwrap().to_string()).collect()
};
workbook.move_to_sheet(0).expect("re-select sheet 0");
let again: Vec<String> = {
let mut cursor = workbook.rows();
let row = cursor.next_row().expect("row").expect("ok");
row.iter().map(|c| c.as_str().unwrap().to_string()).collect()
};
assert_eq!(first, again);
}
#[test]
fn grows_its_buffer_for_an_oversized_row() {
let big = "x".repeat(200_000);
let dir = std::env::temp_dir().join("excelreader-rust-rows-test");
std::fs::create_dir_all(&dir).expect("temp dir");
let path = dir.join("wide.csv");
std::fs::write(&path, format!("a\n{big}\n")).expect("write fixture");
let mut workbook =
Workbook::open_with(&path.to_string_lossy(), excelreader::XL_FORMAT_CSV, None).expect("open csv");
let mut cursor = workbook.rows();
let header = cursor.next_row().expect("header").expect("ok");
assert_eq!(header.get(0).unwrap().as_str().unwrap(), "a");
let row = cursor.next_row().expect("data row").expect("ok");
let cell = row.get(0).expect("one cell");
assert_eq!(cell.cell_type, CellType::String);
assert_eq!(cell.as_str().unwrap().len(), 200_000);
drop(cursor);
drop(workbook);
std::fs::remove_file(&path).ok();
}
#[test]
fn decoded_rows_agree_with_the_cursor() {
let from_cursor: Vec<Vec<String>> = {
let mut workbook = Workbook::open(&fixture("RealExcel.xlsx")).expect("open");
let mut cursor = workbook.rows();
let mut all = Vec::new();
while let Some(row) = cursor.next_row() {
let row = row.expect("ok");
all.push(row.iter().map(|c| c.as_str().unwrap().to_string()).collect());
}
all
};
let mut workbook = Workbook::open(&fixture("RealExcel.xlsx")).expect("open");
let decoded = workbook.read_all_decoded().expect("decode");
assert_eq!(decoded.len(), from_cursor.len());
for (index, expected) in from_cursor.iter().enumerate() {
let row = decoded.get(index).expect("row in range");
let actual: Vec<String> = row.iter().map(|c| c.as_str().unwrap().to_string()).collect();
assert_eq!(&actual, expected, "row {index} differs");
}
}
#[test]
fn decoded_rows_on_an_exhausted_sheet_is_empty_not_an_error() {
let mut workbook = Workbook::open(&fixture("RealExcel.xlsx")).expect("open");
{
let mut cursor = workbook.rows();
while let Some(row) = cursor.next_row() {
row.expect("ok");
}
}
let decoded = workbook.read_all_decoded().expect("empty remainder is not an error");
assert_eq!(decoded.len(), 0);
assert!(decoded.is_empty());
assert_eq!(decoded.iter().count(), 0);
}