use crate::engine::VertexEditor;
use crate::engine::graph::DependencyGraph;
use crate::reference::{CellRef, Coord};
use formualizer_common::LiteralValue;
use formualizer_parse::parser::parse;
fn lit_num(value: f64) -> LiteralValue {
LiteralValue::Number(value)
}
fn sheet1_cell(graph: &DependencyGraph, row: u32, col: u32) -> CellRef {
let sid = graph.sheet_id("Sheet1").unwrap();
CellRef::new(sid, Coord::from_excel(row, col, true, true))
}
#[test]
fn test_insert_columns() {
let mut graph = super::common::graph_truth_graph();
graph.set_cell_value("Sheet1", 1, 1, lit_num(10.0)).unwrap();
graph.set_cell_value("Sheet1", 1, 2, lit_num(20.0)).unwrap();
graph.set_cell_value("Sheet1", 1, 3, lit_num(30.0)).unwrap();
let sum_result = graph
.set_cell_formula("Sheet1", 1, 4, parse("=SUM(A1:C1)").unwrap())
.unwrap();
let sum_id = sum_result.affected_vertices[0];
let a1_id = *graph
.get_vertex_id_for_address(&sheet1_cell(&graph, 1, 1))
.unwrap();
let b1_id = *graph
.get_vertex_id_for_address(&sheet1_cell(&graph, 1, 2))
.unwrap();
let c1_id = *graph
.get_vertex_id_for_address(&sheet1_cell(&graph, 1, 3))
.unwrap();
let mut editor = VertexEditor::new(&mut graph);
let summary = editor.insert_columns(0, 1, 2).unwrap();
drop(editor);
assert_eq!(
graph.get_vertex_id_for_address(&sheet1_cell(&graph, 1, 1)),
Some(&a1_id)
);
assert_eq!(
graph.get_vertex_id_for_address(&sheet1_cell(&graph, 1, 4)),
Some(&b1_id)
);
assert_eq!(
graph.get_vertex_id_for_address(&sheet1_cell(&graph, 1, 5)),
Some(&c1_id)
);
assert_eq!(
graph.get_vertex_id_for_address(&sheet1_cell(&graph, 1, 6)),
Some(&sum_id)
);
let formula = graph.get_formula(sum_id);
assert!(formula.is_some());
assert_eq!(summary.vertices_moved.len(), 3); assert_eq!(summary.formulas_updated, 1); }
#[test]
fn test_delete_columns() {
let mut graph = super::common::graph_truth_graph();
for i in 1..=5 {
graph
.set_cell_value("Sheet1", 1, i, lit_num(i as f64 * 10.0))
.unwrap();
}
let a1_id = *graph
.get_vertex_id_for_address(&sheet1_cell(&graph, 1, 1))
.unwrap();
let d1_id = *graph
.get_vertex_id_for_address(&sheet1_cell(&graph, 1, 4))
.unwrap();
let e1_id = *graph
.get_vertex_id_for_address(&sheet1_cell(&graph, 1, 5))
.unwrap();
let formula_result = graph
.set_cell_formula("Sheet1", 1, 7, parse("=SUM(A1:E1)").unwrap())
.unwrap();
let mut editor = VertexEditor::new(&mut graph);
let summary = editor.delete_columns(0, 1, 2).unwrap();
drop(editor);
assert_eq!(
graph.get_vertex_id_for_address(&sheet1_cell(&graph, 1, 1)),
Some(&a1_id)
);
assert_eq!(
graph.get_vertex_id_for_address(&sheet1_cell(&graph, 1, 2)),
Some(&d1_id)
);
assert_eq!(
graph.get_vertex_id_for_address(&sheet1_cell(&graph, 1, 3)),
Some(&e1_id)
);
assert!(
graph
.get_vertex_id_for_address(&sheet1_cell(&graph, 1, 4))
.is_none()
);
assert_eq!(summary.vertices_deleted.len(), 2);
assert_eq!(summary.vertices_moved.len(), 3); }
#[test]
fn test_insert_columns_adjusts_formulas() {
let mut graph = super::common::graph_truth_graph();
graph.set_cell_value("Sheet1", 1, 1, lit_num(10.0)).unwrap();
graph.set_cell_value("Sheet1", 1, 3, lit_num(30.0)).unwrap();
graph
.set_cell_formula("Sheet1", 2, 1, parse("=A1*2").unwrap())
.unwrap();
let c2_result = graph
.set_cell_formula("Sheet1", 2, 3, parse("=C1+5").unwrap())
.unwrap();
let c2_id = c2_result.affected_vertices[0];
let mut editor = VertexEditor::new(&mut graph);
editor.insert_columns(0, 1, 1).unwrap();
drop(editor);
let d2_formula = graph.get_formula(c2_id);
assert!(d2_formula.is_some());
}
#[test]
fn test_delete_column_creates_ref_error() {
let mut graph = super::common::graph_truth_graph();
graph.set_cell_value("Sheet1", 1, 1, lit_num(10.0)).unwrap();
graph.set_cell_value("Sheet1", 1, 2, lit_num(20.0)).unwrap();
let b2_result = graph
.set_cell_formula("Sheet1", 2, 2, parse("=B1*2").unwrap())
.unwrap();
let b2_id = b2_result.affected_vertices[0];
let mut editor = VertexEditor::new(&mut graph);
editor.delete_columns(0, 1, 1).unwrap();
drop(editor);
assert!(graph.is_deleted(b2_id));
assert!(
graph
.get_vertex_id_for_address(&sheet1_cell(&graph, 1, 2))
.is_none()
);
}
#[test]
fn test_insert_columns_with_absolute_references() {
let mut graph = super::common::graph_truth_graph();
graph
.set_cell_value("Sheet1", 1, 1, lit_num(100.0))
.unwrap();
graph
.set_cell_value("Sheet1", 1, 5, lit_num(500.0))
.unwrap();
let formula_result = graph
.set_cell_formula("Sheet1", 2, 5, parse("=$A$1+E1").unwrap())
.unwrap();
let formula_id = formula_result.affected_vertices[0];
let mut editor = VertexEditor::new(&mut graph);
editor.insert_columns(0, 2, 2).unwrap();
drop(editor);
let updated_formula = graph.get_formula(formula_id);
assert!(updated_formula.is_some());
}
#[test]
fn test_multiple_column_operations() {
let mut graph = super::common::graph_truth_graph();
for i in 1..=10 {
graph
.set_cell_value("Sheet1", 1, i, lit_num(i as f64))
.unwrap();
}
let a1_id = *graph
.get_vertex_id_for_address(&sheet1_cell(&graph, 1, 1))
.unwrap();
let mut editor = VertexEditor::new(&mut graph);
editor.begin_batch();
editor.insert_columns(0, 2, 2).unwrap();
editor.delete_columns(0, 9, 1).unwrap();
editor.insert_columns(0, 0, 1).unwrap();
editor.commit_batch();
drop(editor);
assert_eq!(
graph.get_vertex_id_for_address(&sheet1_cell(&graph, 1, 2)),
Some(&a1_id)
);
}
#[test]
fn test_mixed_row_column_operations() {
let mut graph = super::common::graph_truth_graph();
for row in 1..=3 {
for col in 1..=3 {
graph
.set_cell_value("Sheet1", row, col, lit_num((row * 10 + col) as f64))
.unwrap();
}
}
let a1_id = *graph
.get_vertex_id_for_address(&sheet1_cell(&graph, 1, 1))
.unwrap();
let b1_id = *graph
.get_vertex_id_for_address(&sheet1_cell(&graph, 1, 2))
.unwrap();
let a2_id = *graph
.get_vertex_id_for_address(&sheet1_cell(&graph, 2, 1))
.unwrap();
let b2_id = *graph
.get_vertex_id_for_address(&sheet1_cell(&graph, 2, 2))
.unwrap();
let formula_result = graph
.set_cell_formula("Sheet1", 4, 4, parse("=SUM(A1:C3)").unwrap())
.unwrap();
let formula_id = formula_result.affected_vertices[0];
let mut editor = VertexEditor::new(&mut graph);
editor.begin_batch();
editor.insert_rows(0, 1, 1).unwrap();
editor.insert_columns(0, 1, 1).unwrap();
editor.commit_batch();
drop(editor);
assert_eq!(
graph.get_vertex_id_for_address(&sheet1_cell(&graph, 1, 1)),
Some(&a1_id)
);
assert_eq!(
graph.get_vertex_id_for_address(&sheet1_cell(&graph, 1, 3)),
Some(&b1_id)
);
assert_eq!(
graph.get_vertex_id_for_address(&sheet1_cell(&graph, 3, 1)),
Some(&a2_id)
);
assert_eq!(
graph.get_vertex_id_for_address(&sheet1_cell(&graph, 3, 3)),
Some(&b2_id)
);
let updated_formula = graph.get_formula(formula_id);
assert!(updated_formula.is_some());
}
#[test]
fn test_delete_columns_with_dependencies() {
let mut graph = super::common::graph_truth_graph();
graph.set_cell_value("Sheet1", 1, 1, lit_num(10.0)).unwrap();
graph
.set_cell_formula("Sheet1", 1, 2, parse("=A1*2").unwrap())
.unwrap();
let c1_result = graph
.set_cell_formula("Sheet1", 1, 3, parse("=B1+5").unwrap())
.unwrap();
let c1_id = c1_result.affected_vertices[0];
graph
.set_cell_formula("Sheet1", 1, 4, parse("=C1").unwrap())
.unwrap();
let mut editor = VertexEditor::new(&mut graph);
editor.delete_columns(0, 1, 1).unwrap();
drop(editor);
assert!(graph.is_ref_error(c1_id));
}