#[cfg(test)]
mod region_lock_tests {
use formualizer_parse::{ExcelErrorKind, LiteralValue};
use crate::engine::eval::ShimSpillManager;
use crate::engine::spill::{Region, RegionLockManager, SpillMeta, SpillShape};
use crate::engine::vertex::VertexId;
use crate::engine::{Engine, EvalConfig};
#[test]
fn region_lock_overlap_fails() {
let mut mgr = RegionLockManager::default();
let a = Region {
sheet_id: 1,
row_start: 1,
row_end: 2,
col_start: 1,
col_end: 3,
};
let b = Region {
sheet_id: 1,
row_start: 2,
row_end: 3,
col_start: 3,
col_end: 4,
}; let id1 = mgr.reserve(a, VertexId(1)).expect("first reserve ok");
assert!(id1 > 0);
let err = mgr.reserve(b, VertexId(2)).unwrap_err();
assert_eq!(err.kind, ExcelErrorKind::Spill);
mgr.release(id1);
}
#[test]
fn spill_lock_released_on_plan_failure() {
let wb = crate::test_workbook::TestWorkbook::new();
let mut engine = Engine::new(wb, EvalConfig::default());
engine
.set_cell_formula(
"Sheet1",
1,
1,
formualizer_parse::parser::parse("={1,2}").unwrap(),
)
.unwrap();
engine
.set_cell_value("Sheet1", 1, 2, LiteralValue::Text("X".into()))
.unwrap();
let anchor_vertex = engine
.graph
.get_vertex_id_for_address(&engine.graph.make_cell_ref("Sheet1", 1, 1))
.copied()
.expect("anchor vertex");
let anchor_cell = engine.graph.make_cell_ref("Sheet1", 1, 1);
let mut shim = ShimSpillManager::default();
let store_ptr: *const crate::arrow_store::SheetStore = engine.sheet_store();
shim.reserve(
anchor_vertex,
anchor_cell,
SpillShape { rows: 1, cols: 2 },
SpillMeta {
epoch: engine.recalc_epoch,
config: engine.config.spill,
},
)
.expect("reserve ok");
assert!(!shim.active_locks.is_empty());
let targets = vec![
engine.graph.make_cell_ref("Sheet1", 1, 1),
engine.graph.make_cell_ref("Sheet1", 1, 2),
];
let values = vec![vec![LiteralValue::Number(1.0), LiteralValue::Number(2.0)]];
let res = shim.commit_array_with_value_probe(
&mut engine.graph,
anchor_vertex,
&targets,
values,
None,
|g, cell| unsafe {
let sheet_name = g.sheet_name(cell.sheet_id);
let asheet = (*store_ptr).sheet(sheet_name)?;
let v = asheet.get_cell_value(cell.coord.row() as usize, cell.coord.col() as usize);
if matches!(v, LiteralValue::Empty) {
None
} else {
Some(v)
}
},
);
assert!(res.is_err());
assert!(shim.active_locks.is_empty());
}
}