mirror of
https://github.com/storytold/gridcraft.git
synced 2026-10-29 13:16:50 -06:00
Merge pull request #627 from MarekSpodBiedry:issue-531
This commit is contained in:
@@ -249,10 +249,14 @@ fn cancel_copy_mode(s: &mut Session) {
|
||||
|
||||
fn insert_lines(s: &mut Session, p: &Json, axis: Axis) -> Result<Json> {
|
||||
let (at, count) = lines(s, p, axis)?;
|
||||
let limit = if axis == Axis::Rows { MAX_ROWS } else { MAX_COLS };
|
||||
if at.checked_add(count).is_none_or(|end| end > limit) {
|
||||
let cmd = if axis == Axis::Rows { "home.insertRows" } else { "home.insertColumns" };
|
||||
return Err(bad(cmd, "the inserted lines would extend past the end of the worksheet"));
|
||||
}
|
||||
check_lines_protection(s, p, axis, at, count, true)?;
|
||||
let sheet = target_sheet(s, p)?;
|
||||
// Refuse to push data off the sheet.
|
||||
let limit = if axis == Axis::Rows { MAX_ROWS } else { MAX_COLS };
|
||||
if let Some(u) = s.doc()?.wb.sheet(sheet).and_then(|sh| sh.used_range()) {
|
||||
let last = if axis == Axis::Rows { u.end.row } else { u.end.col };
|
||||
if last >= at && last as u64 + count as u64 >= limit as u64 {
|
||||
@@ -290,6 +294,9 @@ fn insert_lines(s: &mut Session, p: &Json, axis: Axis) -> Result<Json> {
|
||||
|
||||
fn delete_lines(s: &mut Session, p: &Json, axis: Axis) -> Result<Json> {
|
||||
let (at, count) = lines(s, p, axis)?;
|
||||
let limit = if axis == Axis::Rows { MAX_ROWS } else { MAX_COLS };
|
||||
// Deleting past the last line only removes up to the end of the worksheet.
|
||||
let count = count.min(limit.saturating_sub(at)).max(1);
|
||||
check_lines_protection(s, p, axis, at, count, false)?;
|
||||
let sheet = target_sheet(s, p)?;
|
||||
let out = edit(s, |cx| {
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
use gridcraft_engine::{EngineError, Session};
|
||||
use serde_json::json;
|
||||
|
||||
fn session() -> Session {
|
||||
let mut session = Session::new();
|
||||
session.new_workbook();
|
||||
session
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn insert_with_an_out_of_range_count_is_a_normal_error() {
|
||||
for (id, key, at) in [("home.insertRows", "rows", "3:3"), ("home.insertColumns", "cols", "C:C")] {
|
||||
let mut session = session();
|
||||
let err = session.execute(id, json!({ key: at, "count": u32::MAX })).unwrap_err();
|
||||
assert!(matches!(err, EngineError::BadParams { .. }), "{id}: {err:?}");
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn insert_after_a_formatted_line_with_an_out_of_range_count_is_a_normal_error() {
|
||||
// A custom size on the preceding line and no cells: the used-range guard has nothing to check.
|
||||
let mut session = session();
|
||||
session.execute("home.rowHeight", json!({"rows": "2:2", "height": 30})).unwrap();
|
||||
let err = session.execute("home.insertRows", json!({"rows": "3:3", "count": u32::MAX})).unwrap_err();
|
||||
assert!(matches!(err, EngineError::BadParams { .. }), "{err:?}");
|
||||
|
||||
let mut session = session();
|
||||
session.execute("home.columnWidth", json!({"cols": "B:B", "width": 100})).unwrap();
|
||||
let err = session.execute("home.insertColumns", json!({"cols": "C:C", "count": u32::MAX})).unwrap_err();
|
||||
assert!(matches!(err, EngineError::BadParams { .. }), "{err:?}");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn delete_with_an_out_of_range_count_does_not_panic() {
|
||||
for (id, key, at) in [("home.deleteRows", "rows", "3:3"), ("home.deleteColumns", "cols", "C:C")] {
|
||||
let mut session = session();
|
||||
let res = session.execute(id, json!({ key: at, "count": u32::MAX }));
|
||||
assert!(!matches!(res, Err(EngineError::Internal(..))), "{id}: {res:?}");
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn insert_and_delete_with_a_small_count_still_work() {
|
||||
let mut session = session();
|
||||
session.execute("home.insertRows", json!({"rows": "1:1", "count": 3})).unwrap();
|
||||
session.execute("home.deleteRows", json!({"rows": "1:1", "count": 3})).unwrap();
|
||||
}
|
||||
Reference in New Issue
Block a user