From 87cdfb2ba1fe98674536f2b12fece9419c882851 Mon Sep 17 00:00:00 2001 From: BrianHung Date: Sun, 13 Jul 2025 00:15:53 -0700 Subject: [PATCH] add tests for user model insert delete rows columns --- base/src/test/user_model/mod.rs | 1 + .../test/user_model/test_multi_row_column.rs | 173 ++++++++++++++++++ 2 files changed, 174 insertions(+) create mode 100644 base/src/test/user_model/test_multi_row_column.rs diff --git a/base/src/test/user_model/mod.rs b/base/src/test/user_model/mod.rs index 257b2e3..658c1bd 100644 --- a/base/src/test/user_model/mod.rs +++ b/base/src/test/user_model/mod.rs @@ -12,6 +12,7 @@ mod test_general; mod test_grid_lines; mod test_keyboard_navigation; mod test_last_empty_cell; +mod test_multi_row_column; mod test_on_area_selection; mod test_on_expand_selected_range; mod test_on_paste_styles; diff --git a/base/src/test/user_model/test_multi_row_column.rs b/base/src/test/user_model/test_multi_row_column.rs new file mode 100644 index 0000000..828499c --- /dev/null +++ b/base/src/test/user_model/test_multi_row_column.rs @@ -0,0 +1,173 @@ +#![allow(clippy::unwrap_used)] + +use crate::{ + constants::{LAST_COLUMN, LAST_ROW}, + test::util::new_empty_model, + UserModel, +}; + +#[test] +fn insert_multiple_rows_shifts_cells() { + let model = new_empty_model(); + let mut model = UserModel::from_model(model); + // Place a value below the insertion point. + model.set_user_input(0, 10, 1, "42").unwrap(); + + // Insert 3 rows starting at row 5. + assert!(model.insert_rows(0, 5, 3).is_ok()); + + // The original value should have moved down by 3 rows. + assert_eq!(model.get_formatted_cell_value(0, 13, 1).unwrap(), "42"); + + // Undo / redo cycle should restore the same behaviour. + model.undo().unwrap(); + assert_eq!(model.get_formatted_cell_value(0, 10, 1).unwrap(), "42"); + model.redo().unwrap(); + assert_eq!(model.get_formatted_cell_value(0, 13, 1).unwrap(), "42"); +} + +#[test] +fn insert_rows_errors() { + let model = new_empty_model(); + let mut model = UserModel::from_model(model); + + // Negative or zero counts are rejected. + assert_eq!( + model.insert_rows(0, 1, -2), + Err("Cannot add a negative number of cells :)".to_string()) + ); + assert_eq!( + model.insert_rows(0, 1, 0), + Err("Cannot add a negative number of cells :)".to_string()) + ); + + // Inserting too many rows so that the sheet would overflow. + let too_many = LAST_ROW; // This guarantees max_row + too_many > LAST_ROW. + assert_eq!( + model.insert_rows(0, 1, too_many), + Err( + "Cannot shift cells because that would delete cells at the end of a column".to_string() + ) + ); +} + +#[test] +fn insert_multiple_columns_shifts_cells() { + let model = new_empty_model(); + let mut model = UserModel::from_model(model); + // Place a value to the right of the insertion point. + model.set_user_input(0, 1, 10, "99").unwrap(); + + // Insert 3 columns starting at column 5. + assert!(model.insert_columns(0, 5, 3).is_ok()); + + // The original value should have moved right by 3 columns. + assert_eq!(model.get_formatted_cell_value(0, 1, 13).unwrap(), "99"); + + // Undo / redo cycle. + model.undo().unwrap(); + assert_eq!(model.get_formatted_cell_value(0, 1, 10).unwrap(), "99"); + model.redo().unwrap(); + assert_eq!(model.get_formatted_cell_value(0, 1, 13).unwrap(), "99"); +} + +#[test] +fn insert_columns_errors() { + let model = new_empty_model(); + let mut model = UserModel::from_model(model); + + // Negative or zero counts are rejected. + assert_eq!( + model.insert_columns(0, 1, -2), + Err("Cannot add a negative number of cells :)".to_string()) + ); + assert_eq!( + model.insert_columns(0, 1, 0), + Err("Cannot add a negative number of cells :)".to_string()) + ); + + // Overflow to the right. + let too_many = LAST_COLUMN; // Ensures max_column + too_many > LAST_COLUMN + assert_eq!( + model.insert_columns(0, 1, too_many), + Err("Cannot shift cells because that would delete cells at the end of a row".to_string()) + ); +} + +#[test] +fn delete_multiple_rows_shifts_cells_upwards() { + let model = new_empty_model(); + let mut model = UserModel::from_model(model); + + // Populate rows 10..14 (to be deleted) so that the diff builder does not fail. + for r in 10..15 { + model.set_user_input(0, r, 1, "del").unwrap(); + } + // Place a value below the deletion range. + model.set_user_input(0, 20, 1, "keep").unwrap(); + + // Delete 5 rows starting at row 10. + assert!(model.delete_rows(0, 10, 5).is_ok()); + + // The value originally at row 20 should now be at row 15. + assert_eq!(model.get_formatted_cell_value(0, 15, 1).unwrap(), "keep"); + + // Undo / redo cycle. + model.undo().unwrap(); + assert_eq!(model.get_formatted_cell_value(0, 20, 1).unwrap(), "keep"); + model.redo().unwrap(); + assert_eq!(model.get_formatted_cell_value(0, 15, 1).unwrap(), "keep"); +} + +#[test] +fn delete_rows_errors() { + let model = new_empty_model(); + let mut model = UserModel::from_model(model); + + // Negative or zero counts are rejected. + assert_eq!( + model.delete_rows(0, 1, -3), + Err("Please use insert rows instead".to_string()) + ); + assert_eq!( + model.delete_rows(0, 1, 0), + Err("Please use insert rows instead".to_string()) + ); +} + +#[test] +fn delete_multiple_columns_shifts_cells_left() { + let model = new_empty_model(); + let mut model = UserModel::from_model(model); + + // Place a value to the right of the deletion range. + model.set_user_input(0, 1, 15, "88").unwrap(); + + // Delete 4 columns starting at column 5. + assert!(model.delete_columns(0, 5, 4).is_ok()); + + // The value originally at column 15 should now be at column 11. + assert_eq!(model.get_formatted_cell_value(0, 1, 11).unwrap(), "88"); + + // Undo / redo cycle. + model.undo().unwrap(); + assert_eq!(model.get_formatted_cell_value(0, 1, 15).unwrap(), "88"); + model.redo().unwrap(); + assert_eq!(model.get_formatted_cell_value(0, 1, 11).unwrap(), "88"); +} + +#[test] +fn delete_columns_errors() { + let model = new_empty_model(); + let mut model = UserModel::from_model(model); + + // Negative or zero counts are rejected. + assert_eq!( + model.delete_columns(0, 1, -4), + Err("Please use insert columns instead".to_string()) + ); + assert_eq!( + model.delete_columns(0, 1, 0), + Err("Please use insert columns instead".to_string()) + ); +}