use crate::engine::{Engine, EvalConfig};
use crate::reference::{CellRef, Coord, RangeRef};
use formualizer_common::{ExcelErrorKind, LiteralValue};
#[test]
fn structured_ref_table_column_tracks_cell_edits_via_table_vertex() {
let ctx = crate::test_workbook::TestWorkbook::new();
let mut engine: Engine<_> = Engine::new(ctx, EvalConfig::default());
engine.add_sheet("Sheet1").unwrap();
engine
.set_cell_value("Sheet1", 2, 1, LiteralValue::Number(5.0))
.unwrap();
engine
.set_cell_value("Sheet1", 2, 2, LiteralValue::Number(10.0))
.unwrap();
engine
.set_cell_value("Sheet1", 3, 1, LiteralValue::Number(7.0))
.unwrap();
engine
.set_cell_value("Sheet1", 3, 2, LiteralValue::Number(20.0))
.unwrap();
let sheet_id = engine.sheet_id("Sheet1").unwrap();
let start = CellRef::new(sheet_id, Coord::from_excel(1, 1, true, true));
let end = CellRef::new(sheet_id, Coord::from_excel(3, 2, true, true));
let range = RangeRef::new(start, end);
engine
.define_table(
"Sales",
range,
true,
vec!["Region".into(), "Amount".into()],
false,
)
.unwrap();
let ast = formualizer_parse::parser::parse("=SUM(Sales[Amount])").unwrap();
engine.set_cell_formula("Sheet1", 1, 4, ast).unwrap();
let v = engine
.evaluate_cell("Sheet1", 1, 4)
.unwrap()
.expect("computed value");
assert_eq!(v, LiteralValue::Number(30.0));
engine
.set_cell_value("Sheet1", 2, 2, LiteralValue::Number(100.0))
.unwrap();
let v2 = engine
.evaluate_cell("Sheet1", 1, 4)
.unwrap()
.expect("computed value");
assert_eq!(v2, LiteralValue::Number(120.0));
}
#[test]
fn structured_ref_this_row_column_rewrites_to_concrete_cell() {
let ctx = crate::test_workbook::TestWorkbook::new();
let mut engine: Engine<_> = Engine::new(ctx, EvalConfig::default());
engine.add_sheet("Sheet1").unwrap();
engine
.set_cell_value("Sheet1", 2, 1, LiteralValue::Text("N".into()))
.unwrap();
engine
.set_cell_value("Sheet1", 2, 2, LiteralValue::Number(10.0))
.unwrap();
engine
.set_cell_value("Sheet1", 3, 1, LiteralValue::Text("S".into()))
.unwrap();
engine
.set_cell_value("Sheet1", 3, 2, LiteralValue::Number(20.0))
.unwrap();
let sheet_id = engine.sheet_id("Sheet1").unwrap();
let start = CellRef::new(sheet_id, Coord::from_excel(1, 1, true, true));
let end = CellRef::new(sheet_id, Coord::from_excel(3, 3, true, true));
let range = RangeRef::new(start, end);
engine
.define_table(
"Sales",
range,
true,
vec!["Region".into(), "Amount".into(), "Double".into()],
false,
)
.unwrap();
let f2 = formualizer_parse::parser::parse("=[@Amount]*2").unwrap();
engine.set_cell_formula("Sheet1", 2, 3, f2).unwrap();
let f3 = formualizer_parse::parser::parse("=[@[Amount]]*2").unwrap();
engine.set_cell_formula("Sheet1", 3, 3, f3).unwrap();
let v2 = engine
.evaluate_cell("Sheet1", 2, 3)
.unwrap()
.expect("computed value");
assert_eq!(v2, LiteralValue::Number(20.0));
let v3 = engine
.evaluate_cell("Sheet1", 3, 3)
.unwrap()
.expect("computed value");
assert_eq!(v3, LiteralValue::Number(40.0));
engine
.set_cell_value("Sheet1", 2, 2, LiteralValue::Number(100.0))
.unwrap();
let v2b = engine
.evaluate_cell("Sheet1", 2, 3)
.unwrap()
.expect("computed value");
assert_eq!(v2b, LiteralValue::Number(200.0));
}
#[test]
fn structured_ref_bracket_table_shorthand_selects_data_body() {
let ctx = crate::test_workbook::TestWorkbook::new();
let mut engine: Engine<_> = Engine::new(ctx, EvalConfig::default());
engine.add_sheet("Sheet1").unwrap();
engine
.set_cell_value("Sheet1", 1, 2, LiteralValue::Number(100.0))
.unwrap();
engine
.set_cell_value("Sheet1", 2, 1, LiteralValue::Number(5.0))
.unwrap();
engine
.set_cell_value("Sheet1", 2, 2, LiteralValue::Number(10.0))
.unwrap();
engine
.set_cell_value("Sheet1", 3, 1, LiteralValue::Number(7.0))
.unwrap();
engine
.set_cell_value("Sheet1", 3, 2, LiteralValue::Number(20.0))
.unwrap();
let sheet_id = engine.sheet_id("Sheet1").unwrap();
let start = CellRef::new(sheet_id, Coord::from_excel(1, 1, true, true));
let end = CellRef::new(sheet_id, Coord::from_excel(3, 2, true, true));
let range = RangeRef::new(start, end);
engine
.define_table(
"Sales",
range,
true,
vec!["Region".into(), "Amount".into()],
false,
)
.unwrap();
let ast = formualizer_parse::parser::parse("=SUM([Sales])").unwrap();
engine.set_cell_formula("Sheet1", 1, 4, ast).unwrap();
let v = engine
.evaluate_cell("Sheet1", 1, 4)
.unwrap()
.expect("computed value");
assert_eq!(v, LiteralValue::Number(42.0));
}
#[test]
fn structured_ref_table_name_resolution_is_case_insensitive_by_default() {
let ctx = crate::test_workbook::TestWorkbook::new();
let mut engine: Engine<_> = Engine::new(ctx, EvalConfig::default());
engine.add_sheet("Sheet1").unwrap();
engine
.set_cell_value("Sheet1", 2, 2, LiteralValue::Number(10.0))
.unwrap();
engine
.set_cell_value("Sheet1", 3, 2, LiteralValue::Number(20.0))
.unwrap();
let sheet_id = engine.sheet_id("Sheet1").unwrap();
let start = CellRef::new(sheet_id, Coord::from_excel(1, 1, true, true));
let end = CellRef::new(sheet_id, Coord::from_excel(3, 2, true, true));
let range = RangeRef::new(start, end);
engine
.define_table(
"Sales",
range,
true,
vec!["Region".into(), "Amount".into()],
false,
)
.unwrap();
let ast = formualizer_parse::parser::parse("=SUM(sales[Amount])").unwrap();
engine.set_cell_formula("Sheet1", 1, 4, ast).unwrap();
let v = engine
.evaluate_cell("Sheet1", 1, 4)
.unwrap()
.expect("computed value");
assert_eq!(v, LiteralValue::Number(30.0));
}
#[test]
fn structured_ref_unicode_table_and_column_resolution_is_case_insensitive_by_default() {
let ctx = crate::test_workbook::TestWorkbook::new();
let mut engine: Engine<_> = Engine::new(ctx, EvalConfig::default());
engine.add_sheet("Sheet1").unwrap();
engine
.set_cell_value("Sheet1", 2, 2, LiteralValue::Number(10.0))
.unwrap();
engine
.set_cell_value("Sheet1", 3, 2, LiteralValue::Number(20.0))
.unwrap();
let sheet_id = engine.sheet_id("Sheet1").unwrap();
let start = CellRef::new(sheet_id, Coord::from_excel(1, 1, true, true));
let end = CellRef::new(sheet_id, Coord::from_excel(3, 2, true, true));
let range = RangeRef::new(start, end);
engine
.define_table(
"Продажи",
range,
true,
vec!["Регион".into(), "Сумма".into()],
false,
)
.unwrap();
let ast = formualizer_parse::parser::parse("=SUM(продажи[сумма])").unwrap();
engine.set_cell_formula("Sheet1", 1, 4, ast).unwrap();
let v = engine
.evaluate_cell("Sheet1", 1, 4)
.unwrap()
.expect("computed value");
assert_eq!(v, LiteralValue::Number(30.0));
}
#[test]
fn table_definition_rejects_case_insensitive_collisions() {
let ctx = crate::test_workbook::TestWorkbook::new();
let mut engine: Engine<_> = Engine::new(ctx, EvalConfig::default());
engine.add_sheet("Sheet1").unwrap();
let sheet_id = engine.sheet_id("Sheet1").unwrap();
let start = CellRef::new(sheet_id, Coord::from_excel(1, 1, true, true));
let end = CellRef::new(sheet_id, Coord::from_excel(1, 1, true, true));
let range = RangeRef::new(start, end);
engine
.define_table("Sales", range, true, vec!["A".into()], false)
.unwrap();
let err = engine
.define_table("sales", range, true, vec!["A".into()], false)
.expect_err("expected collision error");
assert_eq!(err.kind, ExcelErrorKind::Name);
}