From 2b03b3e3b987d9f10ead852c32d7e22187d3bcc7 Mon Sep 17 00:00:00 2001 From: Varun Hegde <44541344+varuntumbe@users.noreply.github.com> Date: Sat, 14 Sep 2024 21:07:31 +0530 Subject: [PATCH] Error Handling of public Set functions (#88) What are we trying to achieve ? ++ Currently all the major public set functions is panic prone and does not handle and return error. This PR tries to address to all those functions. What major errors that could happen in these functions ? ++ All the functions which are being made as error safe is being tested against invalid sheet, row and column values, which could given by user What are the list of functions whose return type has been altered ? **base/src/model.rs** 1. update_cell_with_text 2. update_cell_with_bool 3. update_cell_with_number 4. set_user_input 5. get_cell_style_index 6. get_style_for_cell 7. set_cell_with_string ++> New functions being added 1. set_cell_with_boolean 2. set_cell_with_number **base/src/styles.rs** 1. get_style_with_quote_prefix 3. get_style_with_format 4. get_style_without_quote_prefix 5. get_style **base/src/worksheet.rs** 1. update_cell 2. set_cell_style 3. set_cell_with_formula 4. set_cell_with_number 6. set_cell_with_string 8. set_cell_with_boolean 9. set_cell_with_error 10. cell_clear_contents 11. cell_clear_contents_with_style ++> Above is the comprehensive list of all functions being ( most are public, some are private ) altered for better error handling. As a side effect of changing function signature, there are many changes being done to other functions ( mostly adding "?" to enable to error propagation further ) --- base/examples/formulas_and_errors.rs | 10 +- base/examples/hello_world.rs | 6 +- base/src/actions.rs | 7 +- base/src/model.rs | 219 +++++---- base/src/styles.rs | 47 +- base/src/test/mod.rs | 1 + base/src/test/test_column_width.rs | 6 +- base/src/test/test_general.rs | 122 +++-- base/src/test/test_get_cell_content.rs | 8 +- base/src/test/test_metadata.rs | 2 +- base/src/test/test_model_is_empty_cell.rs | 4 +- base/src/test/test_quote_prefix.rs | 32 +- .../test/test_set_functions_error_handling.rs | 449 ++++++++++++++++++ base/src/test/test_set_user_input.rs | 208 +++++--- base/src/test/test_sheet_markup.rs | 2 +- base/src/test/test_sheets.rs | 8 +- base/src/test/test_styles.rs | 20 +- base/src/test/test_worksheet.rs | 30 +- base/src/test/util.rs | 3 +- base/src/units.rs | 7 +- base/src/user_model/common.rs | 34 +- base/src/worksheet.rs | 86 +++- xlsx/examples/hello_calc.rs | 6 +- xlsx/examples/hello_styles.rs | 2 +- xlsx/src/export/test/test_export.rs | 46 +- xlsx/tests/test.rs | 84 +++- 26 files changed, 1087 insertions(+), 362 deletions(-) create mode 100644 base/src/test/test_set_functions_error_handling.rs diff --git a/base/examples/formulas_and_errors.rs b/base/examples/formulas_and_errors.rs index b279c17..3e706b6 100644 --- a/base/examples/formulas_and_errors.rs +++ b/base/examples/formulas_and_errors.rs @@ -3,15 +3,15 @@ use ironcalc_base::{types::CellType, Model}; fn main() -> Result<(), Box> { let mut model = Model::new_empty("formulas-and-errors", "en", "UTC")?; // A1 - model.set_user_input(0, 1, 1, "1".to_string()); + model.set_user_input(0, 1, 1, "1".to_string())?; // A2 - model.set_user_input(0, 2, 1, "2".to_string()); + model.set_user_input(0, 2, 1, "2".to_string())?; // A3 - model.set_user_input(0, 3, 1, "3".to_string()); + model.set_user_input(0, 3, 1, "3".to_string())?; // B1 - model.set_user_input(0, 1, 2, "=SUM(A1:A3)".to_string()); + model.set_user_input(0, 1, 2, "=SUM(A1:A3)".to_string())?; // B2 - model.set_user_input(0, 2, 2, "=B1/0".to_string()); + model.set_user_input(0, 2, 2, "=B1/0".to_string())?; // Evaluate model.evaluate(); diff --git a/base/examples/hello_world.rs b/base/examples/hello_world.rs index 4275421..4199df5 100644 --- a/base/examples/hello_world.rs +++ b/base/examples/hello_world.rs @@ -3,11 +3,11 @@ use ironcalc_base::{cell::CellValue, Model}; fn main() -> Result<(), Box> { let mut model = Model::new_empty("hello-world", "en", "UTC")?; // A1 - model.set_user_input(0, 1, 1, "Hello".to_string()); + model.set_user_input(0, 1, 1, "Hello".to_string())?; // B1 - model.set_user_input(0, 1, 2, "world!".to_string()); + model.set_user_input(0, 1, 2, "world!".to_string())?; // C1 - model.set_user_input(0, 1, 3, "=CONCAT(A1, \" \", B1".to_string()); + model.set_user_input(0, 1, 3, "=CONCAT(A1, \" \", B1".to_string())?; // evaluates model.evaluate(); diff --git a/base/src/actions.rs b/base/src/actions.rs index bd79520..e288d14 100644 --- a/base/src/actions.rs +++ b/base/src/actions.rs @@ -79,12 +79,11 @@ impl Model { let formula_or_value = self .get_cell_formula(sheet, source_row, source_column)? .unwrap_or_else(|| source_cell.get_text(&self.workbook.shared_strings, &self.language)); - self.set_user_input(sheet, target_row, target_column, formula_or_value); + self.set_user_input(sheet, target_row, target_column, formula_or_value)?; self.workbook .worksheet_mut(sheet)? - .set_cell_style(target_row, target_column, style); - self.cell_clear_all(sheet, source_row, source_column)?; - Ok(()) + .set_cell_style(target_row, target_column, style)?; + self.cell_clear_all(sheet, source_row, source_column) } /// Inserts one or more new columns into the model at the specified index. diff --git a/base/src/model.rs b/base/src/model.rs index 695ec57..f110d8a 100644 --- a/base/src/model.rs +++ b/base/src/model.rs @@ -7,19 +7,15 @@ use crate::{ calc_result::{CalcResult, Range}, cell::CellValue, constants::{self, LAST_COLUMN, LAST_ROW}, - expressions::token::{Error, OpCompare, OpProduct, OpSum, OpUnary}, - expressions::{ - parser::move_formula::{move_formula, MoveContext}, - token::get_error_by_name, - types::*, - utils::{self, is_valid_row}, - }, expressions::{ parser::{ + move_formula::{move_formula, MoveContext}, stringify::{to_rc_format, to_string}, Node, Parser, }, - utils::is_valid_column_number, + token::{get_error_by_name, Error, OpCompare, OpProduct, OpSum, OpUnary}, + types::*, + utils::{self, is_valid_column_number, is_valid_row}, }, formatter::{ format::{format_number, parse_formatted_number}, @@ -1204,10 +1200,10 @@ impl Model { /// # fn main() -> Result<(), Box> { /// let mut model = Model::new_empty("model", "en", "UTC")?; /// let (sheet, row, column) = (0, 1, 1); - /// model.set_user_input(sheet, row, column, "Hello!".to_string()); + /// model.set_user_input(sheet, row, column, "Hello!".to_string())?; /// assert_eq!(model.get_cell_content(sheet, row, column)?, "Hello!".to_string()); /// - /// model.update_cell_with_text(sheet, row, column, "Goodbye!"); + /// model.update_cell_with_text(sheet, row, column, "Goodbye!")?; /// assert_eq!(model.get_cell_content(sheet, row, column)?, "Goodbye!".to_string()); /// # Ok(()) /// # } @@ -1218,23 +1214,30 @@ impl Model { /// * [Model::update_cell_with_number()] /// * [Model::update_cell_with_bool()] /// * [Model::update_cell_with_formula()] - pub fn update_cell_with_text(&mut self, sheet: u32, row: i32, column: i32, value: &str) { - let style_index = self.get_cell_style_index(sheet, row, column); + pub fn update_cell_with_text( + &mut self, + sheet: u32, + row: i32, + column: i32, + value: &str, + ) -> Result<(), String> { + let style_index = self.get_cell_style_index(sheet, row, column)?; let new_style_index; if common::value_needs_quoting(value, &self.language) { new_style_index = self .workbook .styles - .get_style_with_quote_prefix(style_index); + .get_style_with_quote_prefix(style_index)?; } else if self.workbook.styles.style_is_quote_prefix(style_index) { new_style_index = self .workbook .styles - .get_style_without_quote_prefix(style_index); + .get_style_without_quote_prefix(style_index)?; } else { new_style_index = style_index; } - self.set_cell_with_string(sheet, row, column, value, new_style_index); + + self.set_cell_with_string(sheet, row, column, value, new_style_index) } /// Updates the value of a cell with a boolean value @@ -1247,10 +1250,10 @@ impl Model { /// # fn main() -> Result<(), Box> { /// let mut model = Model::new_empty("model", "en", "UTC")?; /// let (sheet, row, column) = (0, 1, 1); - /// model.set_user_input(sheet, row, column, "TRUE".to_string()); + /// model.set_user_input(sheet, row, column, "TRUE".to_string())?; /// assert_eq!(model.get_cell_content(sheet, row, column)?, "TRUE".to_string()); /// - /// model.update_cell_with_bool(sheet, row, column, false); + /// model.update_cell_with_bool(sheet, row, column, false)?; /// assert_eq!(model.get_cell_content(sheet, row, column)?, "FALSE".to_string()); /// # Ok(()) /// # } @@ -1261,17 +1264,22 @@ impl Model { /// * [Model::update_cell_with_number()] /// * [Model::update_cell_with_text()] /// * [Model::update_cell_with_formula()] - pub fn update_cell_with_bool(&mut self, sheet: u32, row: i32, column: i32, value: bool) { - let style_index = self.get_cell_style_index(sheet, row, column); + pub fn update_cell_with_bool( + &mut self, + sheet: u32, + row: i32, + column: i32, + value: bool, + ) -> Result<(), String> { + let style_index = self.get_cell_style_index(sheet, row, column)?; let new_style_index = if self.workbook.styles.style_is_quote_prefix(style_index) { self.workbook .styles - .get_style_without_quote_prefix(style_index) + .get_style_without_quote_prefix(style_index)? } else { style_index }; - let worksheet = &mut self.workbook.worksheets[sheet as usize]; - worksheet.set_cell_with_boolean(row, column, value, new_style_index); + self.set_cell_with_boolean(sheet, row, column, value, new_style_index) } /// Updates the value of a cell with a number @@ -1284,10 +1292,10 @@ impl Model { /// # fn main() -> Result<(), Box> { /// let mut model = Model::new_empty("model", "en", "UTC")?; /// let (sheet, row, column) = (0, 1, 1); - /// model.set_user_input(sheet, row, column, "42".to_string()); + /// model.set_user_input(sheet, row, column, "42".to_string())?; /// assert_eq!(model.get_cell_content(sheet, row, column)?, "42".to_string()); /// - /// model.update_cell_with_number(sheet, row, column, 23.0); + /// model.update_cell_with_number(sheet, row, column, 23.0)?; /// assert_eq!(model.get_cell_content(sheet, row, column)?, "23".to_string()); /// # Ok(()) /// # } @@ -1298,17 +1306,22 @@ impl Model { /// * [Model::update_cell_with_text()] /// * [Model::update_cell_with_bool()] /// * [Model::update_cell_with_formula()] - pub fn update_cell_with_number(&mut self, sheet: u32, row: i32, column: i32, value: f64) { - let style_index = self.get_cell_style_index(sheet, row, column); + pub fn update_cell_with_number( + &mut self, + sheet: u32, + row: i32, + column: i32, + value: f64, + ) -> Result<(), String> { + let style_index = self.get_cell_style_index(sheet, row, column)?; let new_style_index = if self.workbook.styles.style_is_quote_prefix(style_index) { self.workbook .styles - .get_style_without_quote_prefix(style_index) + .get_style_without_quote_prefix(style_index)? } else { style_index }; - let worksheet = &mut self.workbook.worksheets[sheet as usize]; - worksheet.set_cell_with_number(row, column, value, new_style_index); + self.set_cell_with_number(sheet, row, column, value, new_style_index) } /// Updates the formula of given cell @@ -1322,11 +1335,11 @@ impl Model { /// # fn main() -> Result<(), Box> { /// let mut model = Model::new_empty("model", "en", "UTC")?; /// let (sheet, row, column) = (0, 1, 1); - /// model.set_user_input(sheet, row, column, "=A2*2".to_string()); + /// model.set_user_input(sheet, row, column, "=A2*2".to_string())?; /// model.evaluate(); /// assert_eq!(model.get_cell_content(sheet, row, column)?, "=A2*2".to_string()); /// - /// model.update_cell_with_formula(sheet, row, column, "=A3*2".to_string()); + /// model.update_cell_with_formula(sheet, row, column, "=A3*2".to_string())?; /// model.evaluate(); /// assert_eq!(model.get_cell_content(sheet, row, column)?, "=A3*2".to_string()); /// # Ok(()) @@ -1345,12 +1358,12 @@ impl Model { column: i32, formula: String, ) -> Result<(), String> { - let mut style_index = self.get_cell_style_index(sheet, row, column); + let mut style_index = self.get_cell_style_index(sheet, row, column)?; if self.workbook.styles.style_is_quote_prefix(style_index) { style_index = self .workbook .styles - .get_style_without_quote_prefix(style_index); + .get_style_without_quote_prefix(style_index)?; } let formula = formula .strip_prefix('=') @@ -1390,31 +1403,36 @@ impl Model { /// * [Model::update_cell_with_number()] /// * [Model::update_cell_with_bool()] /// * [Model::update_cell_with_text()] - pub fn set_user_input(&mut self, sheet: u32, row: i32, column: i32, value: String) { + pub fn set_user_input( + &mut self, + sheet: u32, + row: i32, + column: i32, + value: String, + ) -> Result<(), String> { // If value starts with "'" then we force the style to be quote_prefix - let style_index = self.get_cell_style_index(sheet, row, column); + let style_index = self.get_cell_style_index(sheet, row, column)?; if let Some(new_value) = value.strip_prefix('\'') { // First check if it needs quoting let new_style = if common::value_needs_quoting(new_value, &self.language) { self.workbook .styles - .get_style_with_quote_prefix(style_index) + .get_style_with_quote_prefix(style_index)? } else { style_index }; - self.set_cell_with_string(sheet, row, column, new_value, new_style); + self.set_cell_with_string(sheet, row, column, new_value, new_style)?; } else { let mut new_style_index = style_index; if self.workbook.styles.style_is_quote_prefix(style_index) { new_style_index = self .workbook .styles - .get_style_without_quote_prefix(style_index); + .get_style_without_quote_prefix(style_index)?; } if let Some(formula) = value.strip_prefix('=') { - let formula_index = self - .set_cell_with_formula(sheet, row, column, formula, new_style_index) - .expect("could not set the cell formula"); + let formula_index = + self.set_cell_with_formula(sheet, row, column, formula, new_style_index)?; // Update the style if needed let cell = CellReferenceIndex { sheet, row, column }; let parsed_formula = &self.parsed_formulas[sheet as usize][formula_index as usize]; @@ -1422,15 +1440,11 @@ impl Model { let new_style_index = self .workbook .styles - .get_style_with_format(new_style_index, &units.get_num_fmt()); - let style = self.workbook.styles.get_style(new_style_index); - self.set_cell_style(sheet, row, column, &style) - .expect("Failed setting the style"); + .get_style_with_format(new_style_index, &units.get_num_fmt())?; + let style = self.workbook.styles.get_style(new_style_index)?; + self.set_cell_style(sheet, row, column, &style)? } } else { - let worksheets = &mut self.workbook.worksheets; - let worksheet = &mut worksheets[sheet as usize]; - // The list of currencies is '$', '€' and the local currency let mut currencies = vec!["$", "€"]; let currency = &self.locale.currency.symbol; @@ -1443,35 +1457,39 @@ impl Model { // Should not apply the format in the following cases: // - we assign a date to already date-formatted cell let should_apply_format = !(is_likely_date_number_format( - &self.workbook.styles.get_style(new_style_index).num_fmt, + &self.workbook.styles.get_style(new_style_index)?.num_fmt, ) && is_likely_date_number_format(&num_fmt)); if should_apply_format { new_style_index = self .workbook .styles - .get_style_with_format(new_style_index, &num_fmt); + .get_style_with_format(new_style_index, &num_fmt)?; } } - worksheet.set_cell_with_number(row, column, v, new_style_index); - return; + let worksheet = self.workbook.worksheet_mut(sheet)?; + worksheet.set_cell_with_number(row, column, v, new_style_index)?; + return Ok(()); } // We try to parse as boolean if let Ok(v) = value.to_lowercase().parse::() { - worksheet.set_cell_with_boolean(row, column, v, new_style_index); - return; + let worksheet = self.workbook.worksheet_mut(sheet)?; + worksheet.set_cell_with_boolean(row, column, v, new_style_index)?; + return Ok(()); } // Check is it is error value let upper = value.to_uppercase(); + let worksheet = self.workbook.worksheet_mut(sheet)?; match get_error_by_name(&upper, &self.language) { Some(error) => { - worksheet.set_cell_with_error(row, column, error, new_style_index); + worksheet.set_cell_with_error(row, column, error, new_style_index)?; } None => { - self.set_cell_with_string(sheet, row, column, &value, new_style_index); + self.set_cell_with_string(sheet, row, column, &value, new_style_index)?; } } } } + Ok(()) } fn set_cell_with_formula( @@ -1512,24 +1530,66 @@ impl Model { self.parsed_formulas[sheet as usize].push(parsed_formula); formula_index = (shared_formulas.len() as i32) - 1; } - worksheet.set_cell_with_formula(row, column, formula_index, style); + worksheet.set_cell_with_formula(row, column, formula_index, style)?; Ok(formula_index) } - fn set_cell_with_string(&mut self, sheet: u32, row: i32, column: i32, value: &str, style: i32) { - let worksheets = &mut self.workbook.worksheets; - let worksheet = &mut worksheets[sheet as usize]; + fn set_cell_with_string( + &mut self, + sheet: u32, + row: i32, + column: i32, + value: &str, + style: i32, + ) -> Result<(), String> { match self.shared_strings.get(value) { Some(string_index) => { - worksheet.set_cell_with_string(row, column, *string_index as i32, style); + self.workbook.worksheet_mut(sheet)?.set_cell_with_string( + row, + column, + *string_index as i32, + style, + )?; } None => { let string_index = self.workbook.shared_strings.len(); self.workbook.shared_strings.push(value.to_string()); self.shared_strings.insert(value.to_string(), string_index); - worksheet.set_cell_with_string(row, column, string_index as i32, style); + self.workbook.worksheet_mut(sheet)?.set_cell_with_string( + row, + column, + string_index as i32, + style, + )?; } } + Ok(()) + } + + fn set_cell_with_boolean( + &mut self, + sheet: u32, + row: i32, + column: i32, + value: bool, + style: i32, + ) -> Result<(), String> { + self.workbook + .worksheet_mut(sheet)? + .set_cell_with_boolean(row, column, value, style) + } + + fn set_cell_with_number( + &mut self, + sheet: u32, + row: i32, + column: i32, + value: f64, + style: i32, + ) -> Result<(), String> { + self.workbook + .worksheet_mut(sheet)? + .set_cell_with_number(row, column, value, style) } /// Gets the Excel Value (Bool, Number, String) of a cell @@ -1596,7 +1656,7 @@ impl Model { ) -> Result { match self.workbook.worksheet(sheet_index)?.cell(row, column) { Some(cell) => { - let format = self.get_style_for_cell(sheet_index, row, column).num_fmt; + let format = self.get_style_for_cell(sheet_index, row, column)?.num_fmt; let formatted_value = cell.formatted_value(&self.workbook.shared_strings, &self.language, |value| { format_number(value, &format, &self.locale).text @@ -1699,7 +1759,7 @@ impl Model { pub fn cell_clear_contents(&mut self, sheet: u32, row: i32, column: i32) -> Result<(), String> { self.workbook .worksheet_mut(sheet)? - .cell_clear_contents(row, column); + .cell_clear_contents(row, column)?; Ok(()) } @@ -1734,43 +1794,40 @@ impl Model { } /// Returns the style index for cell (`sheet`, `row`, `column`) - pub fn get_cell_style_index(&self, sheet: u32, row: i32, column: i32) -> i32 { + pub fn get_cell_style_index(&self, sheet: u32, row: i32, column: i32) -> Result { // First check the cell, then row, the column - let cell = self - .workbook - .worksheet(sheet) - .expect("Invalid sheet") - .cell(row, column); + let cell = self.workbook.worksheet(sheet)?.cell(row, column); + match cell { - Some(cell) => cell.get_style(), + Some(cell) => Ok(cell.get_style()), None => { - let rows = &self.workbook.worksheets[sheet as usize].rows; + let rows = &self.workbook.worksheet(sheet)?.rows; for r in rows { if r.r == row { if r.custom_format { - return r.s; + return Ok(r.s); } break; } } - let cols = &self.workbook.worksheets[sheet as usize].cols; + let cols = &self.workbook.worksheet(sheet)?.cols; for c in cols.iter() { let min = c.min; let max = c.max; if column >= min && column <= max { - return c.style.unwrap_or(0); + return Ok(c.style.unwrap_or(0)); } } - 0 + Ok(0) } } } /// Returns the style for cell (`sheet`, `row`, `column`) - pub fn get_style_for_cell(&self, sheet: u32, row: i32, column: i32) -> Style { - self.workbook - .styles - .get_style(self.get_cell_style_index(sheet, row, column)) + pub fn get_style_for_cell(&self, sheet: u32, row: i32, column: i32) -> Result { + let style_index = self.get_cell_style_index(sheet, row, column)?; + let style = self.workbook.styles.get_style(style_index)?; + Ok(style) } /// Returns an internal binary representation of the workbook @@ -1810,7 +1867,7 @@ impl Model { Some(formula) => formula, None => self.get_formatted_cell_value(sheet, row, column)?, }; - let style = self.get_style_for_cell(sheet, row, column); + let style = self.get_style_for_cell(sheet, row, column)?; if style.font.b { cell_markup = format!("**{cell_markup}**") } diff --git a/base/src/styles.rs b/base/src/styles.rs index ba75068..4d41cc2 100644 --- a/base/src/styles.rs +++ b/base/src/styles.rs @@ -161,26 +161,29 @@ impl Styles { pub fn create_named_style(&mut self, style_name: &str, style: &Style) -> Result<(), String> { let style_index = self.create_new_style(style); - self.add_named_cell_style(style_name, style_index)?; - Ok(()) + self.add_named_cell_style(style_name, style_index) } - pub(crate) fn get_style_with_quote_prefix(&mut self, index: i32) -> i32 { - let mut style = self.get_style(index); + pub(crate) fn get_style_with_quote_prefix(&mut self, index: i32) -> Result { + let mut style = self.get_style(index)?; style.quote_prefix = true; - self.get_style_index_or_create(&style) + Ok(self.get_style_index_or_create(&style)) } - pub(crate) fn get_style_with_format(&mut self, index: i32, num_fmt: &str) -> i32 { - let mut style = self.get_style(index); + pub(crate) fn get_style_with_format( + &mut self, + index: i32, + num_fmt: &str, + ) -> Result { + let mut style = self.get_style(index)?; style.num_fmt = num_fmt.to_string(); - self.get_style_index_or_create(&style) + Ok(self.get_style_index_or_create(&style)) } - pub(crate) fn get_style_without_quote_prefix(&mut self, index: i32) -> i32 { - let mut style = self.get_style(index); + pub(crate) fn get_style_without_quote_prefix(&mut self, index: i32) -> Result { + let mut style = self.get_style(index)?; style.quote_prefix = false; - self.get_style_index_or_create(&style) + Ok(self.get_style_index_or_create(&style)) } pub(crate) fn style_is_quote_prefix(&self, index: i32) -> bool { @@ -188,9 +191,11 @@ impl Styles { cell_xf.quote_prefix } - pub(crate) fn get_style(&self, index: i32) -> Style { - let cell_xf = &self.cell_xfs[index as usize]; - + pub(crate) fn get_style(&self, index: i32) -> Result { + let cell_xf = &self + .cell_xfs + .get(index as usize) + .ok_or("Invalid index provided".to_string())?; let border_id = cell_xf.border_id as usize; let fill_id = cell_xf.fill_id as usize; let font_id = cell_xf.font_id as usize; @@ -198,14 +203,14 @@ impl Styles { let quote_prefix = cell_xf.quote_prefix; let alignment = cell_xf.alignment.clone(); - Style { + Ok(Style { alignment, num_fmt: get_num_fmt(num_fmt_id, &self.num_fmts), fill: self.fills[fill_id].clone(), font: self.fonts[font_id].clone(), border: self.borders[border_id].clone(), quote_prefix, - } + }) } } @@ -221,8 +226,7 @@ impl Model { let style_index = self.workbook.styles.get_style_index_or_create(style); self.workbook .worksheet_mut(sheet)? - .set_cell_style(row, column, style_index); - Ok(()) + .set_cell_style(row, column, style_index) } pub fn copy_cell_style( @@ -237,9 +241,7 @@ impl Model { self.workbook .worksheet_mut(destination_cell.0)? - .set_cell_style(destination_cell.1, destination_cell.2, source_style_index); - - Ok(()) + .set_cell_style(destination_cell.1, destination_cell.2, source_style_index) } /// Sets the style "style_name" in cell @@ -253,8 +255,7 @@ impl Model { let style_index = self.workbook.styles.get_style_index_by_name(style_name)?; self.workbook .worksheet_mut(sheet)? - .set_cell_style(row, column, style_index); - Ok(()) + .set_cell_style(row, column, style_index) } pub fn set_sheet_style(&mut self, sheet: u32, style_name: &str) -> Result<(), String> { diff --git a/base/src/test/mod.rs b/base/src/test/mod.rs index 8f3a666..c34fbd8 100644 --- a/base/src/test/mod.rs +++ b/base/src/test/mod.rs @@ -52,6 +52,7 @@ mod test_fn_type; mod test_frozen_rows_and_columns; mod test_get_cell_content; mod test_percentage; +mod test_set_functions_error_handling; mod test_today; mod test_types; mod user_model; diff --git a/base/src/test/test_column_width.rs b/base/src/test/test_column_width.rs index 3e38eb0..c2cd136 100644 --- a/base/src/test/test_column_width.rs +++ b/base/src/test/test_column_width.rs @@ -26,7 +26,7 @@ fn test_column_width() { assert!((worksheet.get_column_width(1).unwrap() - DEFAULT_COLUMN_WIDTH).abs() < f64::EPSILON); assert!((worksheet.get_column_width(2).unwrap() - 30.0).abs() < f64::EPSILON); assert!((worksheet.get_column_width(3).unwrap() - DEFAULT_COLUMN_WIDTH).abs() < f64::EPSILON); - assert_eq!(model.get_cell_style_index(0, 23, 2), 6); + assert_eq!(model.get_cell_style_index(0, 23, 2), Ok(6)); } #[test] @@ -53,7 +53,7 @@ fn test_column_width_lower_edge() { assert!( (worksheet.get_column_width(6).unwrap() - 10.0 * COLUMN_WIDTH_FACTOR).abs() < f64::EPSILON ); - assert_eq!(model.get_cell_style_index(0, 23, 5), 1); + assert_eq!(model.get_cell_style_index(0, 23, 5), Ok(1)); } #[test] @@ -80,5 +80,5 @@ fn test_column_width_higher_edge() { ); assert!((worksheet.get_column_width(16).unwrap() - 30.0).abs() < f64::EPSILON); assert!((worksheet.get_column_width(17).unwrap() - DEFAULT_COLUMN_WIDTH).abs() < f64::EPSILON); - assert_eq!(model.get_cell_style_index(0, 23, 16), 1); + assert_eq!(model.get_cell_style_index(0, 23, 16), Ok(1)); } diff --git a/base/src/test/test_general.rs b/base/src/test/test_general.rs index 58a583d..440f7d4 100644 --- a/base/src/test/test_general.rs +++ b/base/src/test/test_general.rs @@ -17,7 +17,9 @@ fn test_empty_model() { #[test] fn test_model_simple_evaluation() { let mut model = new_empty_model(); - model.set_user_input(0, 1, 1, "= 1 + 3".to_string()); + model + .set_user_input(0, 1, 1, "= 1 + 3".to_string()) + .unwrap(); model.evaluate(); let result = model._get_text_at(0, 1, 1); assert_eq!(result, *"4"); @@ -43,7 +45,7 @@ fn test_model_simple_evaluation_order() { #[test] fn test_model_invalid_formula() { let mut model = new_empty_model(); - model.set_user_input(0, 1, 1, "= 1 +".to_string()); + model.set_user_input(0, 1, 1, "= 1 +".to_string()).unwrap(); model.evaluate(); let result = model._get_text_at(0, 1, 1); assert_eq!(result, *"#ERROR!"); @@ -54,8 +56,10 @@ fn test_model_invalid_formula() { #[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.set_user_input(0, 1, 1, "23".to_string()).unwrap(); // A1 + model + .set_user_input(0, 1, 2, "= A1* 2-4".to_string()) + .unwrap(); // B1 model.evaluate(); let result = model._get_text_at(0, 1, 1); assert_eq!(result, *"23"); @@ -65,7 +69,9 @@ fn test_model_dependencies() { 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 + .set_user_input(0, 2, 1, "=SUM(A1, B1)".to_string()) + .unwrap(); // A2 model.evaluate(); let result = model._get_text_at(0, 2, 1); assert_eq!(result, *"65"); @@ -74,8 +80,10 @@ fn test_model_dependencies() { #[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 + .set_user_input(0, 1, 1, "Hello World".to_string()) + .unwrap(); + model.set_user_input(0, 1, 2, "=A1".to_string()).unwrap(); model.evaluate(); let result = model._get_text_at(0, 1, 1); assert_eq!(result, *"Hello World"); @@ -152,21 +160,35 @@ fn test_to_excel_precision_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, 1, "true".to_string()).unwrap(); + model.set_user_input(0, 2, 1, "TRUE".to_string()).unwrap(); + model.set_user_input(0, 3, 1, "True".to_string()).unwrap(); + model.set_user_input(0, 4, 1, "false".to_string()).unwrap(); + model.set_user_input(0, 5, 1, "FALSE".to_string()).unwrap(); + model.set_user_input(0, 6, 1, "False".to_string()).unwrap(); - 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, 2, "=ISLOGICAL(A1)".to_string()) + .unwrap(); + model + .set_user_input(0, 2, 2, "=ISLOGICAL(A2)".to_string()) + .unwrap(); + model + .set_user_input(0, 3, 2, "=ISLOGICAL(A3)".to_string()) + .unwrap(); + model + .set_user_input(0, 4, 2, "=ISLOGICAL(A4)".to_string()) + .unwrap(); + model + .set_user_input(0, 5, 2, "=ISLOGICAL(A5)".to_string()) + .unwrap(); + model + .set_user_input(0, 6, 2, "=ISLOGICAL(A6)".to_string()) + .unwrap(); - model.set_user_input(0, 1, 5, "=IF(false, True, FALSe)".to_string()); + model + .set_user_input(0, 1, 5, "=IF(false, True, FALSe)".to_string()) + .unwrap(); model.evaluate(); @@ -191,19 +213,19 @@ fn test_booleans() { #[test] fn test_set_cell_style() { let mut model = new_empty_model(); - let mut style = model.get_style_for_cell(0, 1, 1); + let mut style = model.get_style_for_cell(0, 1, 1).unwrap(); 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); + let mut style = model.get_style_for_cell(0, 1, 1).unwrap(); 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); + let style = model.get_style_for_cell(0, 1, 1).unwrap(); assert!(!style.font.b); } @@ -211,21 +233,21 @@ fn test_set_cell_style() { fn test_copy_cell_style() { let mut model = new_empty_model(); - let mut style = model.get_style_for_cell(0, 1, 1); + let mut style = model.get_style_for_cell(0, 1, 1).unwrap(); 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); + let mut style = model.get_style_for_cell(0, 1, 2).unwrap(); 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); + let style = model.get_style_for_cell(0, 1, 1).unwrap(); assert!(style.font.b); assert!(!style.font.i); - let style = model.get_style_for_cell(0, 1, 2); + let style = model.get_style_for_cell(0, 1, 2).unwrap(); assert!(style.font.b); assert!(!style.font.i); } @@ -234,15 +256,15 @@ fn test_copy_cell_style() { 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); + let mut style = model.get_style_for_cell(0, 1, 1).unwrap(); + let style_index = model.get_cell_style_index(0, 1, 1).unwrap(); 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); + let style_index = model.get_cell_style_index(0, 1, 1).unwrap(); assert_eq!(style_index, 1); } @@ -250,29 +272,29 @@ fn test_get_cell_style_index() { 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 + model.set_user_input(0, 1, 1, "21".to_string()).unwrap(); // A1 + model.set_user_input(0, 2, 1, "2".to_string()).unwrap(); // A2 - let style_index = model.get_cell_style_index(0, 1, 1); + let style_index = model.get_cell_style_index(0, 1, 1).unwrap(); assert_eq!(style_index, 0); - let mut style = model.get_style_for_cell(0, 1, 1); + let mut style = model.get_style_for_cell(0, 1, 1).unwrap(); 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); + let style_index = model.get_cell_style_index(0, 1, 1).unwrap(); assert_eq!(style_index, 1); - let style_index = model.get_cell_style_index(0, 2, 1); + let style_index = model.get_cell_style_index(0, 2, 1).unwrap(); 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.update_cell_with_number(0, 1, 2, 1.0).unwrap(); + model.update_cell_with_number(0, 2, 1, 2.0).unwrap(); model.evaluate(); // Styles are not modified - let style_index = model.get_cell_style_index(0, 1, 1); + let style_index = model.get_cell_style_index(0, 1, 1).unwrap(); assert_eq!(style_index, 1); - let style_index = model.get_cell_style_index(0, 2, 1); + let style_index = model.get_cell_style_index(0, 2, 1).unwrap(); assert_eq!(style_index, 1); } @@ -280,20 +302,20 @@ fn test_model_set_cells_with_values_styles() { fn test_style_fmt_id() { let mut model = new_empty_model(); - let mut style = model.get_style_for_cell(0, 1, 1); + let mut style = model.get_style_for_cell(0, 1, 1).unwrap(); 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); + let style = model.get_style_for_cell(0, 1, 1).unwrap(); assert_eq!(style.num_fmt, "#.##"); - let mut style = model.get_style_for_cell(0, 10, 1); + let mut style = model.get_style_for_cell(0, 10, 1).unwrap(); 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); + let style = model.get_style_for_cell(0, 10, 1).unwrap(); assert_eq!(style.num_fmt, "$$#,##0.0000"); // Make sure old style is not touched - let style = model.get_style_for_cell(0, 1, 1); + let style = model.get_style_for_cell(0, 1, 1).unwrap(); assert_eq!(style.num_fmt, "#.##"); } @@ -357,9 +379,13 @@ 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()); + model + .set_user_input(0, 3, 1, "=SUM(A1:A2".to_string()) + .unwrap(); // This will fail anyway - model.set_user_input(0, 4, 1, "=SUM(A1*".to_string()); + model + .set_user_input(0, 4, 1, "=SUM(A1*".to_string()) + .unwrap(); model.evaluate(); assert_eq!(model._get_formula("A3"), "=SUM(A1:A2)"); @@ -405,7 +431,7 @@ fn test_get_formatted_cell_value() { model._set("A5", "123.456"); // change A5 format - let mut style = model.get_style_for_cell(0, 5, 1); + let mut style = model.get_style_for_cell(0, 5, 1).unwrap(); style.num_fmt = "$#,##0.00".to_string(); model.set_cell_style(0, 5, 1, &style).unwrap(); diff --git a/base/src/test/test_get_cell_content.rs b/base/src/test/test_get_cell_content.rs index e36846b..da3d5eb 100644 --- a/base/src/test/test_get_cell_content.rs +++ b/base/src/test/test_get_cell_content.rs @@ -5,8 +5,12 @@ use crate::test::util::new_empty_model; #[test] fn test_formulas() { let mut model = new_empty_model(); - model.set_user_input(0, 1, 1, "$100.348".to_string()); - model.set_user_input(0, 1, 2, "=ISNUMBER(A1)".to_string()); + model + .set_user_input(0, 1, 1, "$100.348".to_string()) + .unwrap(); + model + .set_user_input(0, 1, 2, "=ISNUMBER(A1)".to_string()) + .unwrap(); model.evaluate(); diff --git a/base/src/test/test_metadata.rs b/base/src/test/test_metadata.rs index 5d5bbfd..c1d8742 100644 --- a/base/src/test/test_metadata.rs +++ b/base/src/test/test_metadata.rs @@ -3,7 +3,7 @@ use crate::test::util::new_empty_model; #[test] fn test_metadata_new_model() { let mut model = new_empty_model(); - model.set_user_input(0, 1, 1, "5.5".to_string()); + model.set_user_input(0, 1, 1, "5.5".to_string()).unwrap(); model.evaluate(); let metadata = &model.workbook.metadata; assert_eq!(metadata.application, "IronCalc Sheets"); diff --git a/base/src/test/test_model_is_empty_cell.rs b/base/src/test/test_model_is_empty_cell.rs index 0db431b..d24ece2 100644 --- a/base/src/test/test_model_is_empty_cell.rs +++ b/base/src/test/test_model_is_empty_cell.rs @@ -14,7 +14,9 @@ fn test_is_empty_cell_non_existing_sheet() { fn test_is_empty_cell() { let mut model = new_empty_model(); assert!(model.is_empty_cell(0, 3, 1).unwrap()); - model.set_user_input(0, 3, 1, "Hello World".to_string()); + model + .set_user_input(0, 3, 1, "Hello World".to_string()) + .unwrap(); assert!(!model.is_empty_cell(0, 3, 1).unwrap()); model.cell_clear_contents(0, 3, 1).unwrap(); assert!(model.is_empty_cell(0, 3, 1).unwrap()); diff --git a/base/src/test/test_quote_prefix.rs b/base/src/test/test_quote_prefix.rs index 455e673..8935713 100644 --- a/base/src/test/test_quote_prefix.rs +++ b/base/src/test/test_quote_prefix.rs @@ -57,12 +57,12 @@ fn test_quote_prefix_enter() { model._set("A2", "=ISTEXT(A1)"); model.evaluate(); // We introduce a value with a "quote prefix" index - model.set_user_input(0, 1, 3, "'=A1".to_string()); + model.set_user_input(0, 1, 3, "'=A1".to_string()).unwrap(); model.evaluate(); assert_eq!(model._get_text("C1"), *"=A1"); // But if we enter with a quote_prefix but without the "'" it won't be quote_prefix - model.set_user_input(0, 1, 4, "=A1".to_string()); + model.set_user_input(0, 1, 4, "=A1".to_string()).unwrap(); model.evaluate(); assert_eq!(model._get_text("D1"), *"123"); } @@ -75,7 +75,7 @@ fn test_quote_prefix_reenter() { model.evaluate(); assert_eq!(model._get_text("A2"), *"TRUE"); // We introduce a value with a "quote prefix" index - model.set_user_input(0, 1, 1, "123".to_string()); + model.set_user_input(0, 1, 1, "123".to_string()).unwrap(); model.evaluate(); assert_eq!(model._get_text("A2"), *"FALSE"); } @@ -83,7 +83,7 @@ fn test_quote_prefix_reenter() { #[test] fn test_update_cell_quote() { let mut model = new_empty_model(); - model.update_cell_with_text(0, 1, 1, "= 1 + 3"); + model.update_cell_with_text(0, 1, 1, "= 1 + 3").unwrap(); model.evaluate(); assert_eq!(model._get_text("A1"), *"= 1 + 3"); assert!(!model._has_formula("A1")); @@ -92,12 +92,12 @@ fn test_update_cell_quote() { #[test] fn test_update_quote_prefix_reenter() { let mut model = new_empty_model(); - model.update_cell_with_text(0, 1, 1, "123"); + model.update_cell_with_text(0, 1, 1, "123").unwrap(); model._set("A2", "=ISTEXT(A1)"); model.evaluate(); assert_eq!(model._get_text("A2"), *"TRUE"); // We reenter as a number - model.update_cell_with_number(0, 1, 1, 123.0); + model.update_cell_with_number(0, 1, 1, 123.0).unwrap(); model.evaluate(); assert_eq!(model._get_text("A2"), *"FALSE"); } @@ -105,12 +105,12 @@ fn test_update_quote_prefix_reenter() { #[test] fn test_update_quote_prefix_reenter_bool() { let mut model = new_empty_model(); - model.update_cell_with_text(0, 1, 1, "TRUE"); + model.update_cell_with_text(0, 1, 1, "TRUE").unwrap(); model._set("A2", "=ISTEXT(A1)"); model.evaluate(); assert_eq!(model._get_text("A2"), *"TRUE"); // We enter a bool - model.update_cell_with_bool(0, 1, 1, true); + model.update_cell_with_bool(0, 1, 1, true).unwrap(); model.evaluate(); assert_eq!(model._get_text("A2"), *"FALSE"); } @@ -118,29 +118,29 @@ fn test_update_quote_prefix_reenter_bool() { #[test] fn test_update_quote_prefix_reenter_text() { let mut model = new_empty_model(); - model.update_cell_with_text(0, 1, 1, "123"); + model.update_cell_with_text(0, 1, 1, "123").unwrap(); model._set("A2", "=ISTEXT(A1)"); model.evaluate(); assert_eq!(model._get_text("A2"), *"TRUE"); - assert!(model.get_style_for_cell(0, 1, 1).quote_prefix); + assert!(model.get_style_for_cell(0, 1, 1).unwrap().quote_prefix); // We enter a string - model.update_cell_with_text(0, 1, 1, "Hello"); + model.update_cell_with_text(0, 1, 1, "Hello").unwrap(); model.evaluate(); assert_eq!(model._get_text("A2"), *"TRUE"); - assert!(!model.get_style_for_cell(0, 1, 1).quote_prefix); + assert!(!model.get_style_for_cell(0, 1, 1).unwrap().quote_prefix); } #[test] fn test_update_quote_prefix_reenter_text_2() { let mut model = new_empty_model(); - model.update_cell_with_text(0, 1, 1, "123"); + model.update_cell_with_text(0, 1, 1, "123").unwrap(); model._set("A2", "=ISTEXT(A1)"); model.evaluate(); assert_eq!(model._get_text("A2"), *"TRUE"); - assert!(model.get_style_for_cell(0, 1, 1).quote_prefix); + assert!(model.get_style_for_cell(0, 1, 1).unwrap().quote_prefix); // We enter another number - model.update_cell_with_text(0, 1, 1, "42"); + model.update_cell_with_text(0, 1, 1, "42").unwrap(); model.evaluate(); assert_eq!(model._get_text("A2"), *"TRUE"); - assert!(model.get_style_for_cell(0, 1, 1).quote_prefix); + assert!(model.get_style_for_cell(0, 1, 1).unwrap().quote_prefix); } diff --git a/base/src/test/test_set_functions_error_handling.rs b/base/src/test/test_set_functions_error_handling.rs new file mode 100644 index 0000000..8ccf967 --- /dev/null +++ b/base/src/test/test_set_functions_error_handling.rs @@ -0,0 +1,449 @@ +use crate::{expressions::token, test::util::new_empty_model, types::Cell}; + +#[test] +fn test_update_cell_with_text() { + let mut model = new_empty_model(); + + // Below are safe inputs + model.set_user_input(0, 1, 1, "Hello".to_string()).unwrap(); + + // Now testing all the possible error scenarios + + // Case1 : Invalid sheet + let update_result = model.update_cell_with_text(1, 1, 1, "new value"); + assert_eq!(update_result, Err("Invalid sheet index".to_string())); + + // Case2 : Invalid Row + let update_result = model.update_cell_with_text(0, 0, 1, "new value"); + assert_eq!(update_result, Err("Incorrect row or column".to_string())); + + // Case3 : Invalid Column + let update_result = model.update_cell_with_text(0, 1, 1048579, "new value"); + assert_eq!(update_result, Err("Incorrect row or column".to_string())); +} + +#[test] +fn test_update_cell_with_number() { + let mut model = new_empty_model(); + + // Below are safe inputs + model.update_cell_with_number(0, 1, 1, 10.0).unwrap(); + + // Now testing all the possible error scenarios + + // Case1 : Invalid sheet + let update_result = model.update_cell_with_number(1, 1, 1, 20.0); + assert_eq!(update_result, Err("Invalid sheet index".to_string())); + + // Case2 : Invalid Row + let update_result = model.update_cell_with_number(0, 0, 1, 20.0); + assert_eq!(update_result, Err("Incorrect row or column".to_string())); + + // Case3 : Invalid Column + let update_result = model.update_cell_with_number(0, 1, 1048579, 20.0); + assert_eq!(update_result, Err("Incorrect row or column".to_string())); +} + +#[test] +fn test_update_cell_with_bool() { + let mut model = new_empty_model(); + + // Below are safe inputs + model.update_cell_with_bool(0, 1, 1, true).unwrap(); + + // Now testing all the possible error scenarios + + // Case1 : Invalid sheet + let update_result = model.update_cell_with_bool(1, 1, 1, false); + assert_eq!(update_result, Err("Invalid sheet index".to_string())); + + // Case2 : Invalid Row + let update_result = model.update_cell_with_bool(0, 0, 1, false); + assert_eq!(update_result, Err("Incorrect row or column".to_string())); + + // Case3 : Invalid Column + let update_result = model.update_cell_with_bool(0, 1, 1048579, false); + assert_eq!(update_result, Err("Incorrect row or column".to_string())); +} + +#[test] +fn test_update_cell_with_formula() { + let mut model = new_empty_model(); + + // Below are safe inputs + model.update_cell_with_number(0, 1, 1, 10.0).unwrap(); + model + .update_cell_with_formula(0, 1, 2, "=A1*2".to_string()) + .unwrap(); + + model.evaluate(); + // Now testing all the possible error scenarios + + // Case1 : Invalid sheet + let update_result = model.update_cell_with_formula(1, 1, 2, "=A1*2".to_string()); + assert_eq!(update_result, Err("Invalid sheet index".to_string())); + + // Case2 : Invalid Row + let update_result = model.update_cell_with_formula(0, 0, 2, "=A1*2".to_string()); + assert_eq!(update_result, Err("Incorrect row or column".to_string())); + + // Case3 : Invalid Column + let update_result = model.update_cell_with_formula(0, 1, 1048579, "=A1*2".to_string()); + assert_eq!(update_result, Err("Incorrect row or column".to_string())); +} + +#[test] +fn test_set_user_input() { + let mut model = new_empty_model(); + + // Below are safe inputs + model.update_cell_with_number(0, 1, 1, 10.0).unwrap(); + model.evaluate(); + // Now testing all the possible error scenarios + + // Case1 : Invalid sheet + let update_result = model.set_user_input(1, 1, 2, "20.0".to_string()); + assert_eq!(update_result, Err("Invalid sheet index".to_string())); + + // Case2 : Invalid Row + let update_result = model.set_user_input(0, 0, 2, "20.0".to_string()); + assert_eq!(update_result, Err("Incorrect row or column".to_string())); + + // Case3 : Invalid Column + let update_result = model.set_user_input(0, 1, 1048579, "20.0".to_string()); + assert_eq!(update_result, Err("Incorrect row or column".to_string())); +} + +#[test] +fn test_get_style_for_cell() { + let mut model = new_empty_model(); + + // Below are safe inputs + model.update_cell_with_number(0, 1, 1, 10.0).unwrap(); + model.evaluate(); + // Now testing all the possible error scenarios + + // Case1 : Invalid sheet + let update_result = model.get_style_for_cell(1, 1, 2); + assert_eq!(update_result, Err("Invalid sheet index".to_string())); + + // ATTENTION : get_cell_style_index tries to get cell using row and col + // if we invalid row or column is given, it will return index 0. + + // Case2 : Invalid Row + let update_result = model.get_style_for_cell(0, 0, 2); + assert_eq!(update_result.is_ok(), true); + + // Case3 : Invalid Column + let update_result = model.get_style_for_cell(0, 1, 1048579); + assert_eq!(update_result.is_ok(), true); +} + +#[test] +fn test_get_cell_style_index() { + let mut model = new_empty_model(); + + // Below are safe inputs + model.update_cell_with_number(0, 1, 1, 10.0).unwrap(); + model.evaluate(); + // Now testing all the possible error scenarios + + // Case1 : Invalid sheet + let update_result = model.get_cell_style_index(1, 1, 2); + assert_eq!(update_result, Err("Invalid sheet index".to_string())); + + // ATTENTION : get_cell_style_index tries to get cell using row and col + // if we invalid row or column is given, it will return index 0. + + // Case2 : Invalid Row + let update_result = model.get_cell_style_index(0, 0, 2); + assert_eq!(update_result, Ok(0)); + + // Case3 : Invalid Column + let update_result = model.get_cell_style_index(0, 1, 1048579); + assert_eq!(update_result, Ok(0)); +} + +#[test] +fn test_worksheet_update_cell() { + let mut model = new_empty_model(); + + // Now testing all the possible error scenarios + + // Case1 : Invalid Row + let update_result = + model + .workbook + .worksheet_mut(0) + .unwrap() + .update_cell(0, 1, Cell::new_number(10.0, 1)); + assert_eq!(update_result, Err("Incorrect row or column".to_string())); + + // Case2 : Invalid Column + let update_result = + model + .workbook + .worksheet_mut(0) + .unwrap() + .update_cell(1, 1048579, Cell::new_number(10.0, 1)); + assert_eq!(update_result, Err("Incorrect row or column".to_string())); +} + +#[test] +fn test_worksheet_set_cell_style() { + let mut model = new_empty_model(); + + // Now testing all the possible error scenarios + + // Case1 : Invalid Row + let update_result = model + .workbook + .worksheet_mut(0) + .unwrap() + .set_cell_style(0, 1, 1); + assert_eq!(update_result, Err("Incorrect row or column".to_string())); + + // Case2 : Invalid Column + let update_result = model + .workbook + .worksheet_mut(0) + .unwrap() + .set_cell_style(1, 1048579, 1); + assert_eq!(update_result, Err("Incorrect row or column".to_string())); +} + +#[test] +fn test_worksheet_set_cell_with_formula() { + let mut model = new_empty_model(); + + // Now testing all the possible error scenarios + + // Case1 : Invalid Row + let update_result = model + .workbook + .worksheet_mut(0) + .unwrap() + .set_cell_with_formula(0, 1, 1, 1); + assert_eq!(update_result, Err("Incorrect row or column".to_string())); + + // Case2 : Invalid Column + let update_result = model + .workbook + .worksheet_mut(0) + .unwrap() + .set_cell_with_formula(1, 1048579, 1, 1); + assert_eq!(update_result, Err("Incorrect row or column".to_string())); +} + +#[test] +fn test_worksheet_set_cell_with_number() { + let mut model = new_empty_model(); + + // Now testing all the possible error scenarios + + // Case1 : Invalid Row + let update_result = model + .workbook + .worksheet_mut(0) + .unwrap() + .set_cell_with_number(0, 1, 1.0, 1); + assert_eq!(update_result, Err("Incorrect row or column".to_string())); + + // Case2 : Invalid Column + let update_result = model + .workbook + .worksheet_mut(0) + .unwrap() + .set_cell_with_number(1, 1048579, 1.0, 1); + assert_eq!(update_result, Err("Incorrect row or column".to_string())); +} + +#[test] +fn test_worksheet_set_cell_with_string() { + let mut model = new_empty_model(); + + // Now testing all the possible error scenarios + + // Case1 : Invalid Row + let update_result = model + .workbook + .worksheet_mut(0) + .unwrap() + .set_cell_with_string(0, 1, 1, 1); + assert_eq!(update_result, Err("Incorrect row or column".to_string())); + + // Case2 : Invalid Column + let update_result = model + .workbook + .worksheet_mut(0) + .unwrap() + .set_cell_with_string(1, 1048579, 1, 1); + assert_eq!(update_result, Err("Incorrect row or column".to_string())); +} + +#[test] +fn test_worksheet_set_cell_with_boolean() { + let mut model = new_empty_model(); + + // Now testing all the possible error scenarios + + // Case1 : Invalid Row + let update_result = model + .workbook + .worksheet_mut(0) + .unwrap() + .set_cell_with_boolean(0, 1, true, 1); + assert_eq!(update_result, Err("Incorrect row or column".to_string())); + + // Case2 : Invalid Column + let update_result = model + .workbook + .worksheet_mut(0) + .unwrap() + .set_cell_with_boolean(1, 1048579, true, 1); + assert_eq!(update_result, Err("Incorrect row or column".to_string())); +} + +#[test] +fn test_worksheet_set_cell_with_error() { + let mut model = new_empty_model(); + + // Now testing all the possible error scenarios + + // Case1: Invalid Row + let update_result = model + .workbook + .worksheet_mut(0) + .unwrap() + .set_cell_with_error(0, 1, token::Error::ERROR, 1); + assert_eq!(update_result, Err("Incorrect row or column".to_string())); + + // Case2 : Invalid Column + let update_result = model + .workbook + .worksheet_mut(0) + .unwrap() + .set_cell_with_error(1, 1048579, token::Error::ERROR, 1); + assert_eq!(update_result, Err("Incorrect row or column".to_string())); +} + +#[test] +fn test_worksheet_cell_clear_contents() { + let mut model = new_empty_model(); + + model + .workbook + .worksheet_mut(0) + .unwrap() + .update_cell(1, 1, Cell::new_number(10.0, 1)) + .unwrap(); + // Now testing all the possible error scenarios + + // Case1 : Invalid Row + let update_result = model + .workbook + .worksheet_mut(0) + .unwrap() + .cell_clear_contents(0, 1); + assert_eq!(update_result, Err("Incorrect row or column".to_string())); + + // Case2 : Invalid Column + let update_result = model + .workbook + .worksheet_mut(0) + .unwrap() + .cell_clear_contents(1, 1048579); + assert_eq!(update_result, Err("Incorrect row or column".to_string())); + + // Case3 : Valid case + let update_result = model + .workbook + .worksheet_mut(0) + .unwrap() + .cell_clear_contents(1, 1); + assert_eq!(update_result, Ok(())) +} + +#[test] +fn test_worksheet_cell_clear_contents_with_style() { + let mut model = new_empty_model(); + + model + .workbook + .worksheet_mut(0) + .unwrap() + .update_cell(1, 1, Cell::new_number(10.0, 1)) + .unwrap(); + // Now testing all the possible error scenarios + + // Case1 : Invalid Row + let update_result = model + .workbook + .worksheet_mut(0) + .unwrap() + .cell_clear_contents_with_style(0, 1, 1); + assert_eq!(update_result, Err("Incorrect row or column".to_string())); + + // Case2 : Invalid Column + let update_result = model + .workbook + .worksheet_mut(0) + .unwrap() + .cell_clear_contents_with_style(1, 1048579, 1); + assert_eq!(update_result, Err("Incorrect row or column".to_string())); + + // Case3 : Valid case + let update_result = model + .workbook + .worksheet_mut(0) + .unwrap() + .cell_clear_contents_with_style(1, 1, 1); + assert_eq!(update_result, Ok(())) +} + +#[test] +fn workbook_styles_get_style_error_handling() { + let model = new_empty_model(); + + // case 1 : Invalid index + assert_eq!( + model.workbook.styles.get_style(15), + Err("Invalid index provided".to_string()) + ); +} + +#[test] +fn workbook_styles_get_style_without_quote_prefix_error_handling() { + let mut model = new_empty_model(); + + // case 1 : Invalid index + assert_eq!( + model.workbook.styles.get_style_without_quote_prefix(15), + Err("Invalid index provided".to_string()) + ); +} + +#[test] +fn workbook_styles_get_style_with_format_error_handling() { + let mut model = new_empty_model(); + + // case 1 : Invalid index + assert_eq!( + model + .workbook + .styles + .get_style_with_format(15, "dummy_num_format"), + Err("Invalid index provided".to_string()) + ); +} + +#[test] +fn workbook_styles_get_style_with_quote_prefix_handling() { + let mut model = new_empty_model(); + + // case 1 : Invalid index + assert_eq!( + model.workbook.styles.get_style_with_quote_prefix(15), + Err("Invalid index provided".to_string()) + ); +} diff --git a/base/src/test/test_set_user_input.rs b/base/src/test/test_set_user_input.rs index c49780b..b39dc8e 100644 --- a/base/src/test/test_set_user_input.rs +++ b/base/src/test/test_set_user_input.rs @@ -5,16 +5,28 @@ use crate::{cell::CellValue, test::util::new_empty_model}; #[test] fn test_currencies() { let mut model = new_empty_model(); - model.set_user_input(0, 1, 1, "$100.348".to_string()); - model.set_user_input(0, 1, 2, "=ISNUMBER(A1)".to_string()); + model + .set_user_input(0, 1, 1, "$100.348".to_string()) + .unwrap(); + model + .set_user_input(0, 1, 2, "=ISNUMBER(A1)".to_string()) + .unwrap(); - model.set_user_input(0, 2, 1, "$ 100.348".to_string()); - model.set_user_input(0, 2, 2, "=ISNUMBER(A2)".to_string()); + model + .set_user_input(0, 2, 1, "$ 100.348".to_string()) + .unwrap(); + model + .set_user_input(0, 2, 2, "=ISNUMBER(A2)".to_string()) + .unwrap(); - model.set_user_input(0, 3, 1, "100$".to_string()); - model.set_user_input(0, 3, 2, "=ISNUMBER(A3)".to_string()); + model.set_user_input(0, 3, 1, "100$".to_string()).unwrap(); + model + .set_user_input(0, 3, 2, "=ISNUMBER(A3)".to_string()) + .unwrap(); - model.set_user_input(0, 4, 1, "3.1415926$".to_string()); + model + .set_user_input(0, 4, 1, "3.1415926$".to_string()) + .unwrap(); model.evaluate(); @@ -43,9 +55,9 @@ fn test_currencies() { #[test] fn scientific() { let mut model = new_empty_model(); - model.set_user_input(0, 1, 1, "3e-4".to_string()); - model.set_user_input(0, 2, 1, "5e-4$".to_string()); - model.set_user_input(0, 3, 1, "6e-4%".to_string()); + model.set_user_input(0, 1, 1, "3e-4".to_string()).unwrap(); + model.set_user_input(0, 2, 1, "5e-4$".to_string()).unwrap(); + model.set_user_input(0, 3, 1, "6e-4%".to_string()).unwrap(); model.evaluate(); @@ -61,9 +73,13 @@ fn scientific() { #[test] fn test_percentage() { let mut model = new_empty_model(); - model.set_user_input(0, 10, 1, "50%".to_string()); - model.set_user_input(0, 10, 2, "=ISNUMBER(A10)".to_string()); - model.set_user_input(0, 11, 1, "55.759%".to_string()); + model.set_user_input(0, 10, 1, "50%".to_string()).unwrap(); + model + .set_user_input(0, 10, 2, "=ISNUMBER(A10)".to_string()) + .unwrap(); + model + .set_user_input(0, 11, 1, "55.759%".to_string()) + .unwrap(); model.evaluate(); @@ -81,8 +97,8 @@ fn test_percentage_ops() { let mut model = new_empty_model(); model._set("A1", "5%"); model._set("A2", "20%"); - model.set_user_input(0, 3, 1, "=A1+A2".to_string()); - model.set_user_input(0, 4, 1, "=A1*A2".to_string()); + model.set_user_input(0, 3, 1, "=A1+A2".to_string()).unwrap(); + model.set_user_input(0, 4, 1, "=A1*A2".to_string()).unwrap(); model.evaluate(); @@ -93,11 +109,19 @@ fn test_percentage_ops() { #[test] fn test_numbers() { let mut model = new_empty_model(); - model.set_user_input(0, 1, 1, "1,000,000".to_string()); + model + .set_user_input(0, 1, 1, "1,000,000".to_string()) + .unwrap(); - model.set_user_input(0, 20, 1, "50,123.549".to_string()); - model.set_user_input(0, 21, 1, "50,12.549".to_string()); - model.set_user_input(0, 22, 1, "1,234567".to_string()); + model + .set_user_input(0, 20, 1, "50,123.549".to_string()) + .unwrap(); + model + .set_user_input(0, 21, 1, "50,12.549".to_string()) + .unwrap(); + model + .set_user_input(0, 22, 1, "1,234567".to_string()) + .unwrap(); model.evaluate(); @@ -131,7 +155,7 @@ fn test_numbers() { #[test] fn test_negative_numbers() { let mut model = new_empty_model(); - model.set_user_input(0, 1, 1, "-100".to_string()); + model.set_user_input(0, 1, 1, "-100".to_string()).unwrap(); model.evaluate(); @@ -144,15 +168,19 @@ fn test_negative_numbers() { #[test] fn test_negative_currencies() { let mut model = new_empty_model(); - model.set_user_input(0, 1, 1, "-$100".to_string()); - model.set_user_input(0, 2, 1, "-$99.123".to_string()); + model.set_user_input(0, 1, 1, "-$100".to_string()).unwrap(); + model + .set_user_input(0, 2, 1, "-$99.123".to_string()) + .unwrap(); // This is valid! - model.set_user_input(0, 3, 1, "$-345".to_string()); + model.set_user_input(0, 3, 1, "$-345".to_string()).unwrap(); - model.set_user_input(0, 1, 2, "-200$".to_string()); - model.set_user_input(0, 2, 2, "-92.689$".to_string()); + model.set_user_input(0, 1, 2, "-200$".to_string()).unwrap(); + model + .set_user_input(0, 2, 2, "-92.689$".to_string()) + .unwrap(); // This is valid! - model.set_user_input(0, 3, 2, "-22$".to_string()); + model.set_user_input(0, 3, 2, "-22$".to_string()).unwrap(); model.evaluate(); @@ -174,8 +202,10 @@ fn test_formulas() { let mut model = new_empty_model(); model._set("A1", "$100"); model._set("A2", "$200"); - model.set_user_input(0, 3, 1, "=A1+A2".to_string()); - model.set_user_input(0, 4, 1, "=SUM(A1:A3)".to_string()); + model.set_user_input(0, 3, 1, "=A1+A2".to_string()).unwrap(); + model + .set_user_input(0, 4, 1, "=SUM(A1:A3)".to_string()) + .unwrap(); model.evaluate(); @@ -198,9 +228,9 @@ fn test_product() { model._set("A2", "$5"); model._set("A3", "4"); - model.set_user_input(0, 1, 2, "=A1*A2".to_string()); - model.set_user_input(0, 2, 2, "=A1*A3".to_string()); - model.set_user_input(0, 3, 2, "=A1*3".to_string()); + model.set_user_input(0, 1, 2, "=A1*A2".to_string()).unwrap(); + model.set_user_input(0, 2, 2, "=A1*A3".to_string()).unwrap(); + model.set_user_input(0, 3, 2, "=A1*3".to_string()).unwrap(); model.evaluate(); @@ -216,10 +246,12 @@ fn test_division() { model._set("A2", "$5"); model._set("A3", "4"); - model.set_user_input(0, 1, 2, "=A1/A2".to_string()); - model.set_user_input(0, 2, 2, "=A1/A3".to_string()); - model.set_user_input(0, 3, 2, "=A1/2".to_string()); - model.set_user_input(0, 4, 2, "=100/A2".to_string()); + model.set_user_input(0, 1, 2, "=A1/A2".to_string()).unwrap(); + model.set_user_input(0, 2, 2, "=A1/A3".to_string()).unwrap(); + model.set_user_input(0, 3, 2, "=A1/2".to_string()).unwrap(); + model + .set_user_input(0, 4, 2, "=100/A2".to_string()) + .unwrap(); model.evaluate(); @@ -235,54 +267,54 @@ fn test_some_complex_examples() { // $3.00 / 2 = $1.50 model._set("A1", "$3.00"); model._set("A2", "2"); - model.set_user_input(0, 3, 1, "=A1/A2".to_string()); + model.set_user_input(0, 3, 1, "=A1/A2".to_string()).unwrap(); // $3 / 2 = $1 model._set("B1", "$3"); model._set("B2", "2"); - model.set_user_input(0, 3, 2, "=B1/B2".to_string()); + model.set_user_input(0, 3, 2, "=B1/B2".to_string()).unwrap(); // $5.00 * 25% = 25% * $5.00 = $1.25 model._set("C1", "$5.00"); model._set("C2", "25%"); - model.set_user_input(0, 3, 3, "=C1*C2".to_string()); - model.set_user_input(0, 4, 3, "=C2*C1".to_string()); + model.set_user_input(0, 3, 3, "=C1*C2".to_string()).unwrap(); + model.set_user_input(0, 4, 3, "=C2*C1".to_string()).unwrap(); // $5 * 75% = 75% * $5 = $1 model._set("D1", "$5"); model._set("D2", "75%"); - model.set_user_input(0, 3, 4, "=D1*D2".to_string()); - model.set_user_input(0, 4, 4, "=D2*D1".to_string()); + model.set_user_input(0, 3, 4, "=D1*D2".to_string()).unwrap(); + model.set_user_input(0, 4, 4, "=D2*D1".to_string()).unwrap(); // $10 + $9.99 = $9.99 + $10 = $19.99 model._set("E1", "$10"); model._set("E2", "$9.99"); - model.set_user_input(0, 3, 5, "=E1+E2".to_string()); - model.set_user_input(0, 4, 5, "=E2+E1".to_string()); + model.set_user_input(0, 3, 5, "=E1+E2".to_string()).unwrap(); + model.set_user_input(0, 4, 5, "=E2+E1".to_string()).unwrap(); // $2 * 2 = 2 * $2 = $4 model._set("F1", "$2"); model._set("F2", "2"); - model.set_user_input(0, 3, 6, "=F1*F2".to_string()); - model.set_user_input(0, 4, 6, "=F2*F1".to_string()); + model.set_user_input(0, 3, 6, "=F1*F2".to_string()).unwrap(); + model.set_user_input(0, 4, 6, "=F2*F1".to_string()).unwrap(); // $2.50 * 2 = 2 * $2.50 = $5.00 model._set("G1", "$2.50"); model._set("G2", "2"); - model.set_user_input(0, 3, 7, "=G1*G2".to_string()); - model.set_user_input(0, 4, 7, "=G2*G1".to_string()); + model.set_user_input(0, 3, 7, "=G1*G2".to_string()).unwrap(); + model.set_user_input(0, 4, 7, "=G2*G1".to_string()).unwrap(); // $2 * 2.5 = 2.5 * $2 = $5 model._set("H1", "$2"); model._set("H2", "2.5"); - model.set_user_input(0, 3, 8, "=H1*H2".to_string()); - model.set_user_input(0, 4, 8, "=H2*H1".to_string()); + model.set_user_input(0, 3, 8, "=H1*H2".to_string()).unwrap(); + model.set_user_input(0, 4, 8, "=H2*H1".to_string()).unwrap(); // 10% * 1,000 = 1,000 * 10% = 100 model._set("I1", "10%"); model._set("I2", "1,000"); - model.set_user_input(0, 3, 9, "=I1*I2".to_string()); - model.set_user_input(0, 4, 9, "=I2*I1".to_string()); + model.set_user_input(0, 3, 9, "=I1*I2".to_string()).unwrap(); + model.set_user_input(0, 4, 9, "=I2*I1".to_string()).unwrap(); model.evaluate(); @@ -320,9 +352,15 @@ fn test_financial_functions() { model._set("A3", "10"); model._set("A4", "$10,000"); - model.set_user_input(0, 5, 1, "=PMT(A2/12,A3,A4)".to_string()); - model.set_user_input(0, 6, 1, "=PMT(A2/12,A3,A4,,1)".to_string()); - model.set_user_input(0, 7, 1, "=PMT(0.2, 3, -200)".to_string()); + model + .set_user_input(0, 5, 1, "=PMT(A2/12,A3,A4)".to_string()) + .unwrap(); + model + .set_user_input(0, 6, 1, "=PMT(A2/12,A3,A4,,1)".to_string()) + .unwrap(); + model + .set_user_input(0, 7, 1, "=PMT(0.2, 3, -200)".to_string()) + .unwrap(); model.evaluate(); @@ -339,9 +377,15 @@ fn test_sum_function() { model._set("A1", "$100"); model._set("A2", "$300"); - model.set_user_input(0, 1, 2, "=SUM(A:A)".to_string()); - model.set_user_input(0, 2, 2, "=SUM(A1:A2)".to_string()); - model.set_user_input(0, 3, 2, "=SUM(A1, A2, A3)".to_string()); + model + .set_user_input(0, 1, 2, "=SUM(A:A)".to_string()) + .unwrap(); + model + .set_user_input(0, 2, 2, "=SUM(A1:A2)".to_string()) + .unwrap(); + model + .set_user_input(0, 3, 2, "=SUM(A1, A2, A3)".to_string()) + .unwrap(); model.evaluate(); @@ -353,7 +397,7 @@ fn test_sum_function() { #[test] fn test_number() { let mut model = new_empty_model(); - model.set_user_input(0, 1, 1, "3".to_string()); + model.set_user_input(0, 1, 1, "3".to_string()).unwrap(); model.evaluate(); @@ -367,7 +411,9 @@ fn test_number() { #[test] fn test_currencies_eur_prefix() { let mut model = new_empty_model(); - model.set_user_input(0, 1, 1, "€100.348".to_string()); + model + .set_user_input(0, 1, 1, "€100.348".to_string()) + .unwrap(); model.evaluate(); @@ -381,19 +427,27 @@ fn test_currencies_eur_prefix() { #[test] fn test_currencies_eur_suffix() { let mut model = new_empty_model(); - model.set_user_input(0, 1, 1, "100.348€".to_string()); - model.set_user_input(0, 2, 1, "25€".to_string()); + model + .set_user_input(0, 1, 1, "100.348€".to_string()) + .unwrap(); + model.set_user_input(0, 2, 1, "25€".to_string()).unwrap(); // negatives - model.set_user_input(0, 1, 2, "-123.348€".to_string()); - model.set_user_input(0, 2, 2, "-42€".to_string()); + model + .set_user_input(0, 1, 2, "-123.348€".to_string()) + .unwrap(); + model.set_user_input(0, 2, 2, "-42€".to_string()).unwrap(); // with a space - model.set_user_input(0, 1, 3, "101.348 €".to_string()); - model.set_user_input(0, 2, 3, "26 €".to_string()); + model + .set_user_input(0, 1, 3, "101.348 €".to_string()) + .unwrap(); + model.set_user_input(0, 2, 3, "26 €".to_string()).unwrap(); - model.set_user_input(0, 1, 4, "-12.348 €".to_string()); - model.set_user_input(0, 2, 4, "-45 €".to_string()); + model + .set_user_input(0, 1, 4, "-12.348 €".to_string()) + .unwrap(); + model.set_user_input(0, 2, 4, "-45 €".to_string()).unwrap(); model.evaluate(); @@ -449,9 +503,15 @@ fn test_sum_function_eur() { model._set("A1", "€100"); model._set("A2", "€300"); - model.set_user_input(0, 1, 2, "=SUM(A:A)".to_string()); - model.set_user_input(0, 2, 2, "=SUM(A1:A2)".to_string()); - model.set_user_input(0, 3, 2, "=SUM(A1, A2, A3)".to_string()); + model + .set_user_input(0, 1, 2, "=SUM(A:A)".to_string()) + .unwrap(); + model + .set_user_input(0, 2, 2, "=SUM(A1:A2)".to_string()) + .unwrap(); + model + .set_user_input(0, 3, 2, "=SUM(A1, A2, A3)".to_string()) + .unwrap(); model.evaluate(); @@ -463,7 +523,9 @@ fn test_sum_function_eur() { #[test] fn input_dates() { let mut model = new_empty_model(); - model.set_user_input(0, 1, 1, "3/4/2025".to_string()); + model + .set_user_input(0, 1, 1, "3/4/2025".to_string()) + .unwrap(); model.evaluate(); @@ -474,7 +536,9 @@ fn input_dates() { ); // further date assignments do not change the format - model.set_user_input(0, 1, 1, "08-08-2028".to_string()); + model + .set_user_input(0, 1, 1, "08-08-2028".to_string()) + .unwrap(); model.evaluate(); assert_eq!(model._get_text("A1"), "8/8/2028"); } diff --git a/base/src/test/test_sheet_markup.rs b/base/src/test/test_sheet_markup.rs index 3403bfe..f8baa04 100644 --- a/base/src/test/test_sheet_markup.rs +++ b/base/src/test/test_sheet_markup.rs @@ -14,7 +14,7 @@ fn test_sheet_markup() { model._set("A4", "Total"); model._set("B4", "=SUM(B2:B3)"); - let mut style = model.get_style_for_cell(0, 1, 1); + let mut style = model.get_style_for_cell(0, 1, 1).unwrap(); style.font.b = true; model.set_cell_style(0, 1, 1, &style).unwrap(); model.set_cell_style(0, 1, 2, &style).unwrap(); diff --git a/base/src/test/test_sheets.rs b/base/src/test/test_sheets.rs index 63f4c4d..5dd2317 100644 --- a/base/src/test/test_sheets.rs +++ b/base/src/test/test_sheets.rs @@ -138,14 +138,14 @@ fn test_insert_sheet() { // Insert the sheet at the end and check the formula assert!(model.insert_sheet("Bacchus", 1, None).is_ok()); - model.set_user_input(1, 3, 1, "42".to_string()); + model.set_user_input(1, 3, 1, "42".to_string()).unwrap(); model.evaluate(); assert_eq!(model._get_text("A1"), "42"); assert_eq!(model._get_text("A2"), "#REF!"); // Insert a sheet in between the other two assert!(model.insert_sheet("Dionysus", 1, None).is_ok()); - model.set_user_input(1, 3, 1, "111".to_string()); + model.set_user_input(1, 3, 1, "111".to_string()).unwrap(); model.evaluate(); assert_eq!(model._get_text("A1"), "42"); assert_eq!(model._get_text("A2"), "111"); @@ -176,7 +176,7 @@ fn test_rename_sheet() { let mut model = new_empty_model(); model.new_sheet(); model._set("A1", "=NewSheet!A3"); - model.set_user_input(1, 3, 1, "25".to_string()); + model.set_user_input(1, 3, 1, "25".to_string()).unwrap(); model.evaluate(); assert_eq!(model._get_text("A1"), "#REF!"); assert!(model.rename_sheet("Sheet2", "NewSheet").is_ok()); @@ -189,7 +189,7 @@ fn test_rename_sheet_by_index() { let mut model = new_empty_model(); model.new_sheet(); model._set("A1", "=NewSheet!A1"); - model.set_user_input(1, 1, 1, "25".to_string()); + model.set_user_input(1, 1, 1, "25".to_string()).unwrap(); model.evaluate(); assert_eq!(model._get_text("A1"), "#REF!"); assert!(model.rename_sheet_by_index(1, "NewSheet").is_ok()); diff --git a/base/src/test/test_styles.rs b/base/src/test/test_styles.rs index 31cd71a..b789d2f 100644 --- a/base/src/test/test_styles.rs +++ b/base/src/test/test_styles.rs @@ -7,10 +7,10 @@ use crate::types::Style; 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, "42".to_string()); // A2 + model.set_user_input(0, 1, 1, "21".to_string()).unwrap(); // A1 + model.set_user_input(0, 2, 1, "42".to_string()).unwrap(); // A2 - let style_base = model.get_style_for_cell(0, 1, 1); + let style_base = model.get_style_for_cell(0, 1, 1).unwrap(); let mut style = style_base.clone(); style.font.b = true; style.num_fmt = "#,##0.00".to_string(); @@ -19,7 +19,7 @@ fn test_model_set_cells_with_values_styles() { let mut style = style_base; style.num_fmt = "#,##0.00".to_string(); assert!(model.set_cell_style(0, 2, 1, &style).is_ok()); - let style: Style = model.get_style_for_cell(0, 2, 1); + let style: Style = model.get_style_for_cell(0, 2, 1).unwrap(); assert_eq!(style.num_fmt, "#,##0.00".to_string()); } @@ -27,21 +27,21 @@ fn test_model_set_cells_with_values_styles() { fn test_named_styles() { let mut model = new_empty_model(); model._set("A1", "42"); - let mut style = model.get_style_for_cell(0, 1, 1); + let mut style = model.get_style_for_cell(0, 1, 1).unwrap(); style.font.b = true; assert!(model.set_cell_style(0, 1, 1, &style).is_ok()); - let bold_style_index = model.get_cell_style_index(0, 1, 1); + let bold_style_index = model.get_cell_style_index(0, 1, 1).unwrap(); let e = model .workbook .styles .add_named_cell_style("bold", bold_style_index); assert!(e.is_ok()); model._set("A2", "420"); - let a2_style_index = model.get_cell_style_index(0, 2, 1); + let a2_style_index = model.get_cell_style_index(0, 2, 1).unwrap(); assert!(a2_style_index != bold_style_index); let e = model.set_cell_style_by_name(0, 2, 1, "bold"); assert!(e.is_ok()); - assert_eq!(model.get_cell_style_index(0, 2, 1), bold_style_index); + assert_eq!(model.get_cell_style_index(0, 2, 1), Ok(bold_style_index)); } #[test] @@ -49,7 +49,7 @@ fn test_create_named_style() { let mut model = new_empty_model(); model._set("A1", "42"); - let mut style = model.get_style_for_cell(0, 1, 1); + let mut style = model.get_style_for_cell(0, 1, 1).unwrap(); assert!(!style.font.b); style.font.b = true; @@ -59,6 +59,6 @@ fn test_create_named_style() { let e = model.set_cell_style_by_name(0, 1, 1, "bold"); assert!(e.is_ok()); - let style = model.get_style_for_cell(0, 1, 1); + let style = model.get_style_for_cell(0, 1, 1).unwrap(); assert!(style.font.b); } diff --git a/base/src/test/test_worksheet.rs b/base/src/test/test_worksheet.rs index da0a8ec..587a7de 100644 --- a/base/src/test/test_worksheet.rs +++ b/base/src/test/test_worksheet.rs @@ -100,7 +100,9 @@ fn test_worksheet_dimension_progressive() { } ); - model.set_user_input(0, 30, 50, "Hello World".to_string()); + model + .set_user_input(0, 30, 50, "Hello World".to_string()) + .unwrap(); assert_eq!( model.workbook.worksheet(0).unwrap().dimension(), WorksheetDimension { @@ -111,7 +113,9 @@ fn test_worksheet_dimension_progressive() { } ); - model.set_user_input(0, 10, 15, "Hello World".to_string()); + model + .set_user_input(0, 10, 15, "Hello World".to_string()) + .unwrap(); assert_eq!( model.workbook.worksheet(0).unwrap().dimension(), WorksheetDimension { @@ -122,7 +126,9 @@ fn test_worksheet_dimension_progressive() { } ); - model.set_user_input(0, 5, 25, "Hello World".to_string()); + model + .set_user_input(0, 5, 25, "Hello World".to_string()) + .unwrap(); assert_eq!( model.workbook.worksheet(0).unwrap().dimension(), WorksheetDimension { @@ -133,7 +139,9 @@ fn test_worksheet_dimension_progressive() { } ); - model.set_user_input(0, 10, 250, "Hello World".to_string()); + model + .set_user_input(0, 10, 250, "Hello World".to_string()) + .unwrap(); assert_eq!( model.workbook.worksheet(0).unwrap().dimension(), WorksheetDimension { @@ -162,12 +170,14 @@ fn test_worksheet_navigate_to_edge_in_direction() { for (row_index, row) in inline_spreadsheet.into_iter().enumerate() { for (column_index, value) in row.into_iter().enumerate() { if value != 0 { - model.update_cell_with_number( - 0, - (row_index as i32) + 1, - (column_index as i32) + 1, - value.into(), - ); + model + .update_cell_with_number( + 0, + (row_index as i32) + 1, + (column_index as i32) + 1, + value.into(), + ) + .unwrap(); } } } diff --git a/base/src/test/util.rs b/base/src/test/util.rs index 6f818a7..a33eb3f 100644 --- a/base/src/test/util.rs +++ b/base/src/test/util.rs @@ -20,7 +20,8 @@ impl Model { let cell_reference = self._parse_reference(cell); let column = cell_reference.column; let row = cell_reference.row; - self.set_user_input(cell_reference.sheet, row, column, value.to_string()); + self.set_user_input(cell_reference.sheet, row, column, value.to_string()) + .unwrap(); } pub fn _has_formula(&self, cell: &str) -> bool { self._get_formula_opt(cell).is_some() diff --git a/base/src/units.rs b/base/src/units.rs index 16522d8..bc71bd1 100644 --- a/base/src/units.rs +++ b/base/src/units.rs @@ -86,12 +86,15 @@ fn get_units_from_format_string(num_fmt: &str) -> Option { impl Model { fn compute_cell_units(&self, cell_reference: &CellReferenceIndex) -> Option { - let style = &self.get_style_for_cell( + let cell_style_res = &self.get_style_for_cell( cell_reference.sheet, cell_reference.row, cell_reference.column, ); - get_units_from_format_string(&style.num_fmt) + match cell_style_res { + Ok(style) => get_units_from_format_string(&style.num_fmt), + Err(_) => None, + } } pub(crate) fn compute_node_units( diff --git a/base/src/user_model/common.rs b/base/src/user_model/common.rs index c8f84d7..4c7f3c2 100644 --- a/base/src/user_model/common.rs +++ b/base/src/user_model/common.rs @@ -331,7 +331,7 @@ impl UserModel { .cell(row, column) .cloned(); self.model - .set_user_input(sheet, row, column, value.to_string()); + .set_user_input(sheet, row, column, value.to_string())?; self.evaluate_if_not_paused(); @@ -457,7 +457,7 @@ impl UserModel { .worksheet(sheet)? .cell(row, column) .cloned(); - let old_style = self.model.get_style_for_cell(sheet, row, column); + let old_style = self.model.get_style_for_cell(sheet, row, column)?; self.model.cell_clear_all(sheet, row, column)?; diff_list.push(Diff::CellClearAll { sheet, @@ -720,7 +720,7 @@ impl UserModel { let row_index = ((row - row_start) % styles_heigh) as usize; let column_index = ((column - column_start) % styles_width) as usize; let style = &styles[row_index][column_index]; - let old_value = self.model.get_style_for_cell(sheet, row, column); + let old_value = self.model.get_style_for_cell(sheet, row, column)?; self.model.set_cell_style(sheet, row, column, style)?; diff_list.push(Diff::SetCellStyle { sheet, @@ -755,7 +755,7 @@ impl UserModel { let last_column = range.column + range.width - 1; for row in range.row..=last_row { for column in range.column..=last_column { - let old_value = self.model.get_style_for_cell(sheet, row, column); + let old_value = self.model.get_style_for_cell(sheet, row, column)?; let mut style = old_value.clone(); // First remove all existing borders @@ -852,7 +852,7 @@ impl UserModel { let mut diff_list = Vec::new(); for row in range.row..range.row + range.height { for column in range.column..range.column + range.width { - let old_value = self.model.get_style_for_cell(sheet, row, column); + let old_value = self.model.get_style_for_cell(sheet, row, column)?; let mut style = old_value.clone(); match style_path { "font.b" => { @@ -951,7 +951,7 @@ impl UserModel { /// * [Model::get_style_for_cell] #[inline] pub fn get_cell_style(&mut self, sheet: u32, row: i32, column: i32) -> Result { - Ok(self.model.get_style_for_cell(sheet, row, column)) + self.model.get_style_for_cell(sheet, row, column) } /// Fills the cells from `source_area` until `to_row`. @@ -1017,7 +1017,7 @@ impl UserModel { .worksheet(sheet)? .cell(row, column) .cloned(); - let old_style = self.model.get_style_for_cell(sheet, row, column); + let old_style = self.model.get_style_for_cell(sheet, row, column)?; // compute the new value and set it let source_row = anchor_row + index; @@ -1025,10 +1025,10 @@ impl UserModel { .model .extend_to(sheet, source_row, column, row, column)?; self.model - .set_user_input(sheet, row, column, target_value.to_string()); + .set_user_input(sheet, row, column, target_value.to_string())?; // Compute the new style and set it - let new_style = self.model.get_style_for_cell(sheet, source_row, column); + let new_style = self.model.get_style_for_cell(sheet, source_row, column)?; self.model.set_cell_style(sheet, row, column, &new_style)?; // Add the diffs @@ -1118,7 +1118,7 @@ impl UserModel { .worksheet(sheet)? .cell(row, column) .cloned(); - let old_style = self.model.get_style_for_cell(sheet, row, column); + let old_style = self.model.get_style_for_cell(sheet, row, column)?; // compute the new value and set it let source_column = anchor_column + index; @@ -1126,10 +1126,10 @@ impl UserModel { .model .extend_to(sheet, row, source_column, row, column)?; self.model - .set_user_input(sheet, row, column, target_value.to_string()); + .set_user_input(sheet, row, column, target_value.to_string())?; // Compute the new style and set it - let new_style = self.model.get_style_for_cell(sheet, row, source_column); + let new_style = self.model.get_style_for_cell(sheet, row, source_column)?; self.model.set_cell_style(sheet, row, column, &new_style)?; // Add the diffs @@ -1216,7 +1216,7 @@ impl UserModel { self.model .workbook .worksheet_mut(*sheet)? - .update_cell(*row, *column, value); + .update_cell(*row, *column, value)?; } None => { self.model.cell_clear_all(*sheet, *row, *column)?; @@ -1246,7 +1246,7 @@ impl UserModel { self.model .workbook .worksheet_mut(*sheet)? - .update_cell(*row, *column, value); + .update_cell(*row, *column, value)?; } } Diff::CellClearAll { @@ -1261,7 +1261,7 @@ impl UserModel { self.model .workbook .worksheet_mut(*sheet)? - .update_cell(*row, *column, value); + .update_cell(*row, *column, value)?; self.model .set_cell_style(*sheet, *row, *column, old_style)?; } @@ -1307,7 +1307,7 @@ impl UserModel { // puts all the data back let worksheet = self.model.workbook.worksheet_mut(*sheet)?; for (row, cell) in &old_data.data { - worksheet.update_cell(*row, *column, cell.clone()); + worksheet.update_cell(*row, *column, cell.clone())?; } // makes sure that the width and style is correct if let Some(col) = &old_data.column { @@ -1375,7 +1375,7 @@ impl UserModel { } => { needs_evaluation = true; self.model - .set_user_input(*sheet, *row, *column, new_value.to_string()); + .set_user_input(*sheet, *row, *column, new_value.to_string())?; } Diff::SetColumnWidth { sheet, diff --git a/base/src/worksheet.rs b/base/src/worksheet.rs index e26c17c..94d038d 100644 --- a/base/src/worksheet.rs +++ b/base/src/worksheet.rs @@ -42,7 +42,17 @@ impl Worksheet { self.sheet_data.get_mut(&row)?.get_mut(&column) } - pub(crate) fn update_cell(&mut self, row: i32, column: i32, new_cell: Cell) { + pub(crate) fn update_cell( + &mut self, + row: i32, + column: i32, + new_cell: Cell, + ) -> Result<(), String> { + // validate row and column arg before updating cell of worksheet + if !is_valid_row(row) || !is_valid_column_number(column) { + return Err("Incorrect row or column".to_string()); + } + match self.sheet_data.get_mut(&row) { Some(column_data) => match column_data.get(&column) { Some(_cell) => { @@ -58,6 +68,7 @@ impl Worksheet { self.sheet_data.insert(row, column_data); } } + Ok(()) } // TODO [MVP]: Pass the cell style from the model @@ -128,53 +139,94 @@ impl Worksheet { Ok(()) } - pub fn set_cell_style(&mut self, row: i32, column: i32, style_index: i32) { + pub fn set_cell_style( + &mut self, + row: i32, + column: i32, + style_index: i32, + ) -> Result<(), String> { match self.cell_mut(row, column) { Some(cell) => { cell.set_style(style_index); } None => { - self.cell_clear_contents_with_style(row, column, style_index); + self.cell_clear_contents_with_style(row, column, style_index)?; } } + Ok(()) // TODO: cleanup check if the old cell style is still in use } - pub fn set_cell_with_formula(&mut self, row: i32, column: i32, index: i32, style: i32) { + pub fn set_cell_with_formula( + &mut self, + row: i32, + column: i32, + index: i32, + style: i32, + ) -> Result<(), String> { let cell = Cell::new_formula(index, style); - self.update_cell(row, column, cell); + self.update_cell(row, column, cell) } - pub fn set_cell_with_number(&mut self, row: i32, column: i32, value: f64, style: i32) { + pub fn set_cell_with_number( + &mut self, + row: i32, + column: i32, + value: f64, + style: i32, + ) -> Result<(), String> { let cell = Cell::new_number(value, style); - self.update_cell(row, column, cell); + self.update_cell(row, column, cell) } - pub fn set_cell_with_string(&mut self, row: i32, column: i32, index: i32, style: i32) { + pub fn set_cell_with_string( + &mut self, + row: i32, + column: i32, + index: i32, + style: i32, + ) -> Result<(), String> { let cell = Cell::new_string(index, style); - self.update_cell(row, column, cell); + self.update_cell(row, column, cell) } - pub fn set_cell_with_boolean(&mut self, row: i32, column: i32, value: bool, style: i32) { + pub fn set_cell_with_boolean( + &mut self, + row: i32, + column: i32, + value: bool, + style: i32, + ) -> Result<(), String> { let cell = Cell::new_boolean(value, style); - self.update_cell(row, column, cell); + self.update_cell(row, column, cell) } - pub fn set_cell_with_error(&mut self, row: i32, column: i32, error: Error, style: i32) { + pub fn set_cell_with_error( + &mut self, + row: i32, + column: i32, + error: Error, + style: i32, + ) -> Result<(), String> { let cell = Cell::new_error(error, style); - self.update_cell(row, column, cell); + self.update_cell(row, column, cell) } - pub fn cell_clear_contents(&mut self, row: i32, column: i32) { + pub fn cell_clear_contents(&mut self, row: i32, column: i32) -> Result<(), String> { let s = self.get_style(row, column); let cell = Cell::EmptyCell { s }; - self.update_cell(row, column, cell); + self.update_cell(row, column, cell) } - pub fn cell_clear_contents_with_style(&mut self, row: i32, column: i32, style: i32) { + pub fn cell_clear_contents_with_style( + &mut self, + row: i32, + column: i32, + style: i32, + ) -> Result<(), String> { let cell = Cell::EmptyCell { s: style }; - self.update_cell(row, column, cell); + self.update_cell(row, column, cell) } pub fn set_frozen_rows(&mut self, frozen_rows: i32) -> Result<(), String> { diff --git a/xlsx/examples/hello_calc.rs b/xlsx/examples/hello_calc.rs index d1244a6..7dcabeb 100644 --- a/xlsx/examples/hello_calc.rs +++ b/xlsx/examples/hello_calc.rs @@ -9,7 +9,9 @@ fn main() -> Result<(), Box> { for row in 1..100 { for column in 1..100 { let value = row * column; - model.set_user_input(0, row, column, format!("{}", value)); + model + .set_user_input(0, row, column, format!("{}", value)) + .unwrap(); } } // Adds a new sheet @@ -17,7 +19,7 @@ fn main() -> Result<(), Box> { // column 100 is CV let last_column = number_to_column(100).unwrap(); let formula = format!("=SUM(Sheet1!A1:{}100)", last_column); - model.set_user_input(1, 1, 1, formula); + model.set_user_input(1, 1, 1, formula).unwrap(); // evaluates model.evaluate(); diff --git a/xlsx/examples/hello_styles.rs b/xlsx/examples/hello_styles.rs index fe21f04..437c77b 100644 --- a/xlsx/examples/hello_styles.rs +++ b/xlsx/examples/hello_styles.rs @@ -5,7 +5,7 @@ fn main() -> Result<(), Box> { // We are going to change styles in cell A1 let (sheet, row, column) = (0, 1, 1); - let mut style = model.get_style_for_cell(sheet, row, column); + let mut style = model.get_style_for_cell(sheet, row, column)?; style.fill.fg_color = Some("#FF9011".to_string()); style.font.b = true; style.font.color = Some("#E91E63".to_string()); diff --git a/xlsx/src/export/test/test_export.rs b/xlsx/src/export/test/test_export.rs index 09eac2e..8300f24 100644 --- a/xlsx/src/export/test/test_export.rs +++ b/xlsx/src/export/test/test_export.rs @@ -15,16 +15,26 @@ pub fn new_empty_model() -> Model { fn test_values() { let mut model = new_empty_model(); // numbers - model.set_user_input(0, 1, 1, "123.456".to_string()); + model + .set_user_input(0, 1, 1, "123.456".to_string()) + .unwrap(); // strings - model.set_user_input(0, 2, 1, "Hello world!".to_string()); - model.set_user_input(0, 3, 1, "Hello world!".to_string()); - model.set_user_input(0, 4, 1, "你好世界!".to_string()); + model + .set_user_input(0, 2, 1, "Hello world!".to_string()) + .unwrap(); + model + .set_user_input(0, 3, 1, "Hello world!".to_string()) + .unwrap(); + model + .set_user_input(0, 4, 1, "你好世界!".to_string()) + .unwrap(); // booleans - model.set_user_input(0, 5, 1, "TRUE".to_string()); - model.set_user_input(0, 6, 1, "FALSE".to_string()); + model.set_user_input(0, 5, 1, "TRUE".to_string()).unwrap(); + model.set_user_input(0, 6, 1, "FALSE".to_string()).unwrap(); // errors - model.set_user_input(0, 7, 1, "#VALUE!".to_string()); + model + .set_user_input(0, 7, 1, "#VALUE!".to_string()) + .unwrap(); // noop model.evaluate(); @@ -81,14 +91,16 @@ fn test_values() { #[test] fn test_formulas() { let mut model = new_empty_model(); - model.set_user_input(0, 1, 1, "5.5".to_string()); - model.set_user_input(0, 2, 1, "6.5".to_string()); - model.set_user_input(0, 3, 1, "7.5".to_string()); + model.set_user_input(0, 1, 1, "5.5".to_string()).unwrap(); + model.set_user_input(0, 2, 1, "6.5".to_string()).unwrap(); + model.set_user_input(0, 3, 1, "7.5".to_string()).unwrap(); - model.set_user_input(0, 1, 2, "=A1*2".to_string()); - model.set_user_input(0, 2, 2, "=A2*2".to_string()); - model.set_user_input(0, 3, 2, "=A3*2".to_string()); - model.set_user_input(0, 4, 2, "=SUM(A1:B3)".to_string()); + model.set_user_input(0, 1, 2, "=A1*2".to_string()).unwrap(); + model.set_user_input(0, 2, 2, "=A2*2".to_string()).unwrap(); + model.set_user_input(0, 3, 2, "=A3*2".to_string()).unwrap(); + model + .set_user_input(0, 4, 2, "=SUM(A1:B3)".to_string()) + .unwrap(); model.evaluate(); let temp_file_name = "temp_file_test_formulas.xlsx"; @@ -127,12 +139,12 @@ fn test_sheets() { #[test] fn test_named_styles() { let mut model = new_empty_model(); - model.set_user_input(0, 1, 1, "5.5".to_string()); - let mut style = model.get_style_for_cell(0, 1, 1); + model.set_user_input(0, 1, 1, "5.5".to_string()).unwrap(); + let mut style = model.get_style_for_cell(0, 1, 1).unwrap(); style.font.b = true; style.font.i = true; assert!(model.set_cell_style(0, 1, 1, &style).is_ok()); - let bold_style_index = model.get_cell_style_index(0, 1, 1); + let bold_style_index = model.get_cell_style_index(0, 1, 1).unwrap(); let e = model .workbook .styles diff --git a/xlsx/tests/test.rs b/xlsx/tests/test.rs index 1de1a1a..904ef04 100644 --- a/xlsx/tests/test.rs +++ b/xlsx/tests/test.rs @@ -158,42 +158,42 @@ fn test_split() { fn test_model_has_correct_styles(model: &Model) { // A1 is bold - let style_a1 = model.get_style_for_cell(0, 1, 1); + let style_a1 = model.get_style_for_cell(0, 1, 1).unwrap(); assert!(style_a1.font.b); assert!(!style_a1.font.i); assert!(!style_a1.font.u); // B1 is Italics - let style_b1 = model.get_style_for_cell(0, 1, 2); + let style_b1 = model.get_style_for_cell(0, 1, 2).unwrap(); assert!(style_b1.font.i); assert!(!style_b1.font.b); assert!(!style_b1.font.u); // C1 Underlined - let style_c1 = model.get_style_for_cell(0, 1, 3); + let style_c1 = model.get_style_for_cell(0, 1, 3).unwrap(); assert!(style_c1.font.u); assert!(!style_c1.font.b); assert!(!style_c1.font.i); // D1 Bold and Italics - let style_d1 = model.get_style_for_cell(0, 1, 4); + let style_d1 = model.get_style_for_cell(0, 1, 4).unwrap(); assert!(style_d1.font.b); assert!(style_d1.font.i); assert!(!style_d1.font.u); // E1 Bold, italics and underlined - let style_e1 = model.get_style_for_cell(0, 1, 5); + let style_e1 = model.get_style_for_cell(0, 1, 5).unwrap(); assert!(style_e1.font.b); assert!(style_e1.font.i); assert!(style_e1.font.u); assert!(!style_e1.font.strike); // F1 strikethrough - let style_f1 = model.get_style_for_cell(0, 1, 6); + let style_f1 = model.get_style_for_cell(0, 1, 6).unwrap(); assert!(style_f1.font.strike); // G1 Double underlined just get simple underlined - let style_g1 = model.get_style_for_cell(0, 1, 7); + let style_g1 = model.get_style_for_cell(0, 1, 7).unwrap(); assert!(style_g1.font.u); let height_row_3 = model.workbook.worksheet(0).unwrap().row_height(3).unwrap(); @@ -204,44 +204,84 @@ fn test_model_has_correct_styles(model: &Model) { // Second sheet has alignment // Horizontal - let alignment = model.get_style_for_cell(1, 2, 1).alignment; + let alignment = model.get_style_for_cell(1, 2, 1).unwrap().alignment; assert_eq!(alignment, None); - let alignment = model.get_style_for_cell(1, 3, 1).alignment.unwrap(); + let alignment = model + .get_style_for_cell(1, 3, 1) + .unwrap() + .alignment + .unwrap(); assert_eq!(alignment.horizontal, HorizontalAlignment::Left); - let alignment = model.get_style_for_cell(1, 4, 1).alignment.unwrap(); + let alignment = model + .get_style_for_cell(1, 4, 1) + .unwrap() + .alignment + .unwrap(); assert_eq!(alignment.horizontal, HorizontalAlignment::Distributed); - let alignment = model.get_style_for_cell(1, 5, 1).alignment.unwrap(); + let alignment = model + .get_style_for_cell(1, 5, 1) + .unwrap() + .alignment + .unwrap(); assert_eq!(alignment.horizontal, HorizontalAlignment::Right); - let alignment = model.get_style_for_cell(1, 6, 1).alignment.unwrap(); + let alignment = model + .get_style_for_cell(1, 6, 1) + .unwrap() + .alignment + .unwrap(); assert_eq!(alignment.horizontal, HorizontalAlignment::Center); - let alignment = model.get_style_for_cell(1, 7, 1).alignment.unwrap(); + let alignment = model + .get_style_for_cell(1, 7, 1) + .unwrap() + .alignment + .unwrap(); assert_eq!(alignment.horizontal, HorizontalAlignment::Fill); - let alignment = model.get_style_for_cell(1, 8, 1).alignment.unwrap(); + let alignment = model + .get_style_for_cell(1, 8, 1) + .unwrap() + .alignment + .unwrap(); assert_eq!(alignment.horizontal, HorizontalAlignment::Justify); // Vertical - let alignment = model.get_style_for_cell(1, 2, 2).alignment; + let alignment = model.get_style_for_cell(1, 2, 2).unwrap().alignment; assert_eq!(alignment, None); - let alignment = model.get_style_for_cell(1, 3, 2).alignment; + let alignment = model.get_style_for_cell(1, 3, 2).unwrap().alignment; assert_eq!(alignment, None); - let alignment = model.get_style_for_cell(1, 4, 2).alignment.unwrap(); + let alignment = model + .get_style_for_cell(1, 4, 2) + .unwrap() + .alignment + .unwrap(); assert_eq!(alignment.vertical, VerticalAlignment::Top); - let alignment = model.get_style_for_cell(1, 5, 2).alignment.unwrap(); + let alignment = model + .get_style_for_cell(1, 5, 2) + .unwrap() + .alignment + .unwrap(); assert_eq!(alignment.vertical, VerticalAlignment::Center); - let alignment = model.get_style_for_cell(1, 6, 2).alignment.unwrap(); + let alignment = model + .get_style_for_cell(1, 6, 2) + .unwrap() + .alignment + .unwrap(); assert_eq!(alignment.vertical, VerticalAlignment::Justify); - let alignment = model.get_style_for_cell(1, 7, 2).alignment.unwrap(); + let alignment = model + .get_style_for_cell(1, 7, 2) + .unwrap() + .alignment + .unwrap(); assert_eq!(alignment.vertical, VerticalAlignment::Distributed); } @@ -280,7 +320,9 @@ fn test_defined_names_casing() { ("=NaMeD3", "33"), ]; for (formula, expected_value) in test_cases { - model.set_user_input(0, row, column, formula.to_string()); + model + .set_user_input(0, row, column, formula.to_string()) + .unwrap(); model.evaluate(); assert_eq!( model.get_formatted_cell_value(0, row, column).unwrap(),