UPDATE: Dump of initial files

This commit is contained in:
Nicolás Hatcher
2023-11-18 21:26:18 +01:00
commit c5b8efd83d
279 changed files with 42654 additions and 0 deletions

View File

@@ -0,0 +1,484 @@
#![allow(clippy::unwrap_used)]
use crate::cell::CellValue;
use crate::number_format::to_excel_precision_str;
use crate::test::util::new_empty_model;
#[test]
fn test_empty_model() {
let model = new_empty_model();
let names = model.workbook.get_worksheet_names();
assert_eq!(names.len(), 1);
assert_eq!(names[0], "Sheet1");
}
#[test]
fn test_model_simple_evaluation() {
let mut model = new_empty_model();
model.set_user_input(0, 1, 1, "= 1 + 3".to_string());
model.evaluate();
let result = model._get_text_at(0, 1, 1);
assert_eq!(result, *"4");
let result = model._get_formula("A1");
assert_eq!(result, *"=1+3");
}
#[test]
fn test_model_simple_evaluation_order() {
let mut model = new_empty_model();
model._set("A1", "=1/2/3");
model._set("A2", "=(1/2)/3");
model._set("A3", "=1/(2/3)");
model.evaluate();
assert_eq!(model._get_text("A1"), *"0.166666667");
assert_eq!(model._get_text("A2"), *"0.166666667");
assert_eq!(model._get_text("A3"), *"1.5");
// Unnecessary parenthesis are lost
assert_eq!(model._get_formula("A2"), *"=1/2/3");
assert_eq!(model._get_formula("A3"), *"=1/(2/3)");
}
#[test]
fn test_model_invalid_formula() {
let mut model = new_empty_model();
model.set_user_input(0, 1, 1, "= 1 +".to_string());
model.evaluate();
let result = model._get_text_at(0, 1, 1);
assert_eq!(result, *"#ERROR!");
let result = model._get_formula("A1");
assert_eq!(result, *"= 1 +");
}
#[test]
fn test_model_dependencies() {
let mut model = new_empty_model();
model.set_user_input(0, 1, 1, "23".to_string()); // A1
model.set_user_input(0, 1, 2, "= A1* 2-4".to_string()); // B1
model.evaluate();
let result = model._get_text_at(0, 1, 1);
assert_eq!(result, *"23");
assert!(!model._has_formula("A1"));
let result = model._get_text_at(0, 1, 2);
assert_eq!(result, *"42");
let result = model._get_formula("B1");
assert_eq!(result, *"=A1*2-4");
model.set_user_input(0, 2, 1, "=SUM(A1, B1)".to_string()); // A2
model.evaluate();
let result = model._get_text_at(0, 2, 1);
assert_eq!(result, *"65");
}
#[test]
fn test_model_strings() {
let mut model = new_empty_model();
model.set_user_input(0, 1, 1, "Hello World".to_string());
model.set_user_input(0, 1, 2, "=A1".to_string());
model.evaluate();
let result = model._get_text_at(0, 1, 1);
assert_eq!(result, *"Hello World");
let result = model._get_text_at(0, 1, 2);
assert_eq!(result, *"Hello World");
}
#[test]
fn test_get_sheet_index_by_sheet_id() {
let mut model = new_empty_model();
model.new_sheet();
assert_eq!(model.get_sheet_index_by_sheet_id(1), Some(0));
assert_eq!(model.get_sheet_index_by_sheet_id(2), Some(1));
assert_eq!(model.get_sheet_index_by_sheet_id(1337), None);
}
#[test]
fn test_set_row_height() {
let mut model = new_empty_model();
let worksheet = model.workbook.worksheet_mut(0).unwrap();
worksheet.set_row_height(5, 25.0).unwrap();
let worksheet = model.workbook.worksheet(0).unwrap();
assert!((25.0 - worksheet.row_height(5).unwrap()).abs() < f64::EPSILON);
let worksheet = model.workbook.worksheet_mut(0).unwrap();
worksheet.set_row_height(5, 5.0).unwrap();
let worksheet = model.workbook.worksheet(0).unwrap();
assert!((5.0 - worksheet.row_height(5).unwrap()).abs() < f64::EPSILON);
}
#[test]
fn test_to_excel_precision_str() {
struct TestCase<'a> {
value: f64,
str: &'a str,
}
let test_cases = vec![
TestCase {
value: 2e-23,
str: "2e-23",
},
TestCase {
value: 42.0,
str: "42",
},
TestCase {
value: 200.0e-23,
str: "2e-21",
},
TestCase {
value: -200e-23,
str: "-2e-21",
},
TestCase {
value: 10.002,
str: "10.002",
},
TestCase {
value: f64::INFINITY,
str: "inf",
},
TestCase {
value: f64::NAN,
str: "NaN",
},
];
for test_case in test_cases {
let str = to_excel_precision_str(test_case.value);
assert_eq!(str, test_case.str);
}
}
#[test]
fn test_booleans() {
let mut model = new_empty_model();
model.set_user_input(0, 1, 1, "true".to_string());
model.set_user_input(0, 2, 1, "TRUE".to_string());
model.set_user_input(0, 3, 1, "True".to_string());
model.set_user_input(0, 4, 1, "false".to_string());
model.set_user_input(0, 5, 1, "FALSE".to_string());
model.set_user_input(0, 6, 1, "False".to_string());
model.set_user_input(0, 1, 2, "=ISLOGICAL(A1)".to_string());
model.set_user_input(0, 2, 2, "=ISLOGICAL(A2)".to_string());
model.set_user_input(0, 3, 2, "=ISLOGICAL(A3)".to_string());
model.set_user_input(0, 4, 2, "=ISLOGICAL(A4)".to_string());
model.set_user_input(0, 5, 2, "=ISLOGICAL(A5)".to_string());
model.set_user_input(0, 6, 2, "=ISLOGICAL(A6)".to_string());
model.set_user_input(0, 1, 5, "=IF(false, True, FALSe)".to_string());
model.evaluate();
assert_eq!(model._get_text_at(0, 1, 1), *"TRUE");
assert_eq!(model._get_text_at(0, 2, 1), *"TRUE");
assert_eq!(model._get_text_at(0, 3, 1), *"TRUE");
assert_eq!(model._get_text_at(0, 4, 1), *"FALSE");
assert_eq!(model._get_text_at(0, 5, 1), *"FALSE");
assert_eq!(model._get_text_at(0, 6, 1), *"FALSE");
assert_eq!(model._get_text_at(0, 1, 2), *"TRUE");
assert_eq!(model._get_text_at(0, 2, 2), *"TRUE");
assert_eq!(model._get_text_at(0, 3, 2), *"TRUE");
assert_eq!(model._get_text_at(0, 4, 2), *"TRUE");
assert_eq!(model._get_text_at(0, 5, 2), *"TRUE");
assert_eq!(model._get_text_at(0, 6, 2), *"TRUE");
assert_eq!(model._get_formula("E1"), *"=IF(FALSE,TRUE,FALSE)");
}
#[test]
fn test_set_cell_style() {
let mut model = new_empty_model();
let mut style = model.get_style_for_cell(0, 1, 1);
assert!(!style.font.b);
style.font.b = true;
assert!(model.set_cell_style(0, 1, 1, &style).is_ok());
let mut style = model.get_style_for_cell(0, 1, 1);
assert!(style.font.b);
style.font.b = false;
assert!(model.set_cell_style(0, 1, 1, &style).is_ok());
let style = model.get_style_for_cell(0, 1, 1);
assert!(!style.font.b);
}
#[test]
fn test_copy_cell_style() {
let mut model = new_empty_model();
let mut style = model.get_style_for_cell(0, 1, 1);
style.font.b = true;
assert!(model.set_cell_style(0, 1, 1, &style).is_ok());
let mut style = model.get_style_for_cell(0, 1, 2);
style.font.i = true;
assert!(model.set_cell_style(0, 1, 2, &style).is_ok());
assert!(model.copy_cell_style((0, 1, 1), (0, 1, 2)).is_ok());
let style = model.get_style_for_cell(0, 1, 1);
assert!(style.font.b);
assert!(!style.font.i);
let style = model.get_style_for_cell(0, 1, 2);
assert!(style.font.b);
assert!(!style.font.i);
}
#[test]
fn test_get_cell_style_index() {
let mut model = new_empty_model();
let mut style = model.get_style_for_cell(0, 1, 1);
let style_index = model.get_cell_style_index(0, 1, 1);
assert_eq!(style_index, 0);
assert!(!style.font.b);
style.font.b = true;
assert!(model.set_cell_style(0, 1, 1, &style).is_ok());
let style_index = model.get_cell_style_index(0, 1, 1);
assert_eq!(style_index, 1);
}
#[test]
fn test_model_set_cells_with_values_styles() {
let mut model = new_empty_model();
// Inputs
model.set_user_input(0, 1, 1, "21".to_string()); // A1
model.set_user_input(0, 2, 1, "2".to_string()); // A2
let style_index = model.get_cell_style_index(0, 1, 1);
assert_eq!(style_index, 0);
let mut style = model.get_style_for_cell(0, 1, 1);
style.font.b = true;
assert!(model.set_cell_style(0, 1, 1, &style).is_ok());
assert!(model.set_cell_style(0, 2, 1, &style).is_ok());
let style_index = model.get_cell_style_index(0, 1, 1);
assert_eq!(style_index, 1);
let style_index = model.get_cell_style_index(0, 2, 1);
assert_eq!(style_index, 1);
model.update_cell_with_number(0, 1, 2, 1.0);
model.update_cell_with_number(0, 2, 1, 2.0);
model.evaluate();
// Styles are not modified
let style_index = model.get_cell_style_index(0, 1, 1);
assert_eq!(style_index, 1);
let style_index = model.get_cell_style_index(0, 2, 1);
assert_eq!(style_index, 1);
}
#[test]
fn test_style_fmt_id() {
let mut model = new_empty_model();
let mut style = model.get_style_for_cell(0, 1, 1);
style.num_fmt = "#.##".to_string();
assert!(model.set_cell_style(0, 1, 1, &style).is_ok());
let style = model.get_style_for_cell(0, 1, 1);
assert_eq!(style.num_fmt, "#.##");
let mut style = model.get_style_for_cell(0, 10, 1);
style.num_fmt = "$$#,##0.0000".to_string();
assert!(model.set_cell_style(0, 10, 1, &style).is_ok());
let style = model.get_style_for_cell(0, 10, 1);
assert_eq!(style.num_fmt, "$$#,##0.0000");
// Make sure old style is not touched
let style = model.get_style_for_cell(0, 1, 1);
assert_eq!(style.num_fmt, "#.##");
}
#[test]
fn test_set_sheet_color() {
let mut model = new_empty_model();
assert_eq!(model.workbook.worksheet(0).unwrap().color, None);
assert!(model.set_sheet_color(0, "#FFFAAA").is_ok());
// Test new tab color is properly set
assert_eq!(
model.workbook.worksheet(0).unwrap().color,
Some("#FFFAAA".to_string())
);
// Test we can remove it
assert!(model.set_sheet_color(0, "").is_ok());
assert_eq!(model.workbook.worksheet(0).unwrap().color, None);
}
#[test]
fn test_set_sheet_color_invalid_sheet() {
let mut model = new_empty_model();
assert_eq!(
model.set_sheet_color(10, "#FFFAAA"),
Err("Invalid sheet index".to_string())
);
}
#[test]
fn test_set_sheet_color_invalid() {
let mut model = new_empty_model();
// Boundaries
assert!(model.set_sheet_color(0, "#FFFFFF").is_ok());
assert!(model.set_sheet_color(0, "#000000").is_ok());
assert_eq!(
model.set_sheet_color(0, "#FFF"),
Err("Invalid color: #FFF".to_string())
);
assert_eq!(
model.set_sheet_color(0, "-#FFF"),
Err("Invalid color: -#FFF".to_string())
);
assert_eq!(
model.set_sheet_color(0, "#-FFF"),
Err("Invalid color: #-FFF".to_string())
);
assert_eq!(
model.set_sheet_color(0, "2FFFFFF"),
Err("Invalid color: 2FFFFFF".to_string())
);
assert_eq!(
model.set_sheet_color(0, "#FFFFFF1"),
Err("Invalid color: #FFFFFF1".to_string())
);
}
#[test]
fn set_input_autocomplete() {
let mut model = new_empty_model();
model._set("A1", "1");
model._set("A2", "2");
model.set_user_input(0, 3, 1, "=SUM(A1:A2".to_string());
// This will fail anyway
model.set_user_input(0, 4, 1, "=SUM(A1*".to_string());
model.evaluate();
assert_eq!(model._get_formula("A3"), "=SUM(A1:A2)");
assert_eq!(model._get_text("A3"), "3");
assert_eq!(model._get_formula("A4"), "=SUM(A1*");
assert_eq!(model._get_text("A4"), "#ERROR!");
}
#[test]
fn test_get_cell_value_by_ref() {
let mut model = new_empty_model();
model._set("A1", "1");
model._set("A2", "2");
model.evaluate();
// Correct
assert_eq!(
model.get_cell_value_by_ref("Sheet1!A1"),
Ok(CellValue::Number(1.0))
);
// You need to specify full reference
assert_eq!(
model.get_cell_value_by_ref("A1"),
Err("Error parsing reference: 'A1'".to_string())
);
// Error, it has a trailing space
assert_eq!(
model.get_cell_value_by_ref("Sheet1!A1 "),
Err("Error parsing reference: 'Sheet1!A1 '".to_string())
);
}
#[test]
fn test_get_formatted_cell_value() {
let mut model = new_empty_model();
model._set("A1", "foobar");
model._set("A2", "true");
model._set("A3", "");
model._set("A4", "123.456");
model._set("A5", "123.456");
// change A5 format
let mut style = model.get_style_for_cell(0, 5, 1);
style.num_fmt = "$#,##0.00".to_string();
model.set_cell_style(0, 5, 1, &style).unwrap();
model.evaluate();
assert_eq!(model.formatted_cell_value(0, 1, 1).unwrap(), "foobar");
assert_eq!(model.formatted_cell_value(0, 2, 1).unwrap(), "TRUE");
assert_eq!(model.formatted_cell_value(0, 3, 1).unwrap(), "");
assert_eq!(model.formatted_cell_value(0, 4, 1).unwrap(), "123.456");
assert_eq!(model.formatted_cell_value(0, 5, 1).unwrap(), "$123.46");
}
#[test]
fn test_cell_formula() {
let mut model = new_empty_model();
model._set("A1", "=1+2+3");
model._set("A2", "foobar");
model.evaluate();
assert_eq!(
model.cell_formula(0, 1, 1), // A1
Ok(Some("=1+2+3".to_string())),
);
assert_eq!(
model.cell_formula(0, 2, 1), // A2
Ok(None),
);
assert_eq!(
model.cell_formula(0, 3, 1), // A3 - empty cell
Ok(None),
);
assert_eq!(
model.cell_formula(42, 1, 1),
Err("Invalid sheet index".to_string()),
);
}
#[test]
fn test_xlfn() {
let mut model = new_empty_model();
model._set("A1", "=_xlfn.SIN(1)");
model._set("A2", "=_xlfn.SINY(1)");
model._set("A3", "=_xlfn.CONCAT(3, 4.0)");
model.evaluate();
// Only modern formulas strip the '_xlfn.'
assert_eq!(
model.cell_formula(0, 1, 1).unwrap(),
Some("=_xlfn.SIN(1)".to_string())
);
// unknown formulas keep the '_xlfn.' prefix
assert_eq!(
model.cell_formula(0, 2, 1).unwrap(),
Some("=_xlfn.SINY(1)".to_string())
);
assert_eq!(
model.cell_formula(0, 3, 1).unwrap(),
Some("=CONCAT(3,4)".to_string())
);
}
#[test]
fn test_letter_case() {
let mut model = new_empty_model();
model._set("A1", "=sin(1)");
model._set("A2", "=sIn(2)");
model.evaluate();
assert_eq!(
model.cell_formula(0, 1, 1).unwrap(),
Some("=SIN(1)".to_string())
);
assert_eq!(
model.cell_formula(0, 2, 1).unwrap(),
Some("=SIN(2)".to_string())
);
}