diff --git a/base/src/expressions/parser/mod.rs b/base/src/expressions/parser/mod.rs index 5f10755..f396a75 100644 --- a/base/src/expressions/parser/mod.rs +++ b/base/src/expressions/parser/mod.rs @@ -59,6 +59,9 @@ mod test_move_formula; #[cfg(test)] mod test_tables; +#[cfg(test)] +mod test_issue_155; + pub(crate) fn parse_range(formula: &str) -> Result<(i32, i32, i32, i32), String> { let mut lexer = lexer::Lexer::new( formula, @@ -522,20 +525,6 @@ impl Parser { let mut absolute_row1 = left.absolute_row; let mut absolute_row2 = right.absolute_row; - if self.lexer.is_a1_mode() { - if !left.absolute_row { - row1 -= context.row - }; - if !left.absolute_column { - column1 -= context.column - }; - if !right.absolute_row { - row2 -= context.row - }; - if !right.absolute_column { - column2 -= context.column - }; - } if row1 > row2 { (row2, row1) = (row1, row2); (absolute_row2, absolute_row1) = (absolute_row1, absolute_row2); @@ -544,6 +533,22 @@ impl Parser { (column2, column1) = (column1, column2); (absolute_column2, absolute_column1) = (absolute_column1, absolute_column2); } + + if self.lexer.is_a1_mode() { + if !absolute_row1 { + row1 -= context.row + }; + if !absolute_column1 { + column1 -= context.column + }; + if !absolute_row2 { + row2 -= context.row + }; + if !absolute_column2 { + column2 -= context.column + }; + } + match sheet_index { Some(index) => Node::RangeKind { sheet_name: sheet, diff --git a/base/src/expressions/parser/test_issue_155.rs b/base/src/expressions/parser/test_issue_155.rs new file mode 100644 index 0000000..7144cc6 --- /dev/null +++ b/base/src/expressions/parser/test_issue_155.rs @@ -0,0 +1,69 @@ +#![allow(clippy::panic)] + +use std::collections::HashMap; + +use super::super::parser::stringify::to_string; +use super::super::types::CellReferenceRC; +use super::Parser; + +#[test] +fn issue_155_parser() { + let worksheets = vec!["Sheet1".to_string()]; + let mut parser = Parser::new(worksheets, HashMap::new()); + + // Reference cell is Sheet1!A1 + let cell_reference = CellReferenceRC { + sheet: "Sheet1".to_string(), + row: 2, + column: 2, + }; + let t = parser.parse("A$1:A2", &Some(cell_reference.clone())); + assert_eq!(to_string(&t, &cell_reference), "A$1:A2"); +} + +#[test] +fn issue_155_parser_case_2() { + let worksheets = vec!["Sheet1".to_string()]; + let mut parser = Parser::new(worksheets, HashMap::new()); + + // Reference cell is Sheet1!A1 + let cell_reference = CellReferenceRC { + sheet: "Sheet1".to_string(), + row: 20, + column: 20, + }; + let t = parser.parse("C$1:D2", &Some(cell_reference.clone())); + assert_eq!(to_string(&t, &cell_reference), "C$1:D2"); +} + +#[test] +fn issue_155_parser_only_row() { + let worksheets = vec!["Sheet1".to_string()]; + let mut parser = Parser::new(worksheets, HashMap::new()); + + // Reference cell is Sheet1!A1 + let cell_reference = CellReferenceRC { + sheet: "Sheet1".to_string(), + row: 20, + column: 20, + }; + // This is tricky, I am not sure what to do in these cases + let t = parser.parse("A$2:B1", &Some(cell_reference.clone())); + assert_eq!(to_string(&t, &cell_reference), "A1:B$2"); +} + +#[test] +fn issue_155_parser_only_column() { + let worksheets = vec!["Sheet1".to_string()]; + let mut parser = Parser::new(worksheets, HashMap::new()); + + // Reference cell is Sheet1!A1 + let cell_reference = CellReferenceRC { + sheet: "Sheet1".to_string(), + row: 20, + column: 20, + }; + // This is tricky, I am not sure what to do in these cases + let t = parser.parse("D1:$A3", &Some(cell_reference.clone())); + assert_eq!(to_string(&t, &cell_reference), "$A1:D3"); +} diff --git a/base/src/test/mod.rs b/base/src/test/mod.rs index 222fe1b..65c7fa6 100644 --- a/base/src/test/mod.rs +++ b/base/src/test/mod.rs @@ -53,6 +53,7 @@ mod test_extend; mod test_fn_type; mod test_frozen_rows_and_columns; mod test_get_cell_content; +mod test_issue_155; mod test_percentage; mod test_set_functions_error_handling; mod test_today; diff --git a/base/src/test/test_issue_155.rs b/base/src/test/test_issue_155.rs new file mode 100644 index 0000000..c66189a --- /dev/null +++ b/base/src/test/test_issue_155.rs @@ -0,0 +1,14 @@ +#![allow(clippy::unwrap_used)] + +use crate::test::util::new_empty_model; + +#[test] +fn issue_155() { + let mut model = new_empty_model(); + model._set("A1", "1"); + model._set("A2", "2"); + model._set("B2", "=A$1:A2"); + model.evaluate(); + + assert_eq!(model._get_formula("B2"), "=A$1:A2".to_string()); +}