mirror of
https://github.com/storytold/gridcraft.git
synced 2026-10-28 04:36:51 -06:00
Merge PR #1434: Refuse table names that clash with defined names or R1C1 references
Conflicts: crates/engine/src/cmd/insert.rs (both appended a test at the end of tests; kept both)
This commit is contained in:
@@ -237,7 +237,7 @@ fn valid_name(n: &str) -> bool {
|
||||
|
||||
/// Looks like an R1C1 reference (`R`, `C`, `RC`, `R2`, `C3`, `R1C1`), which Excel doesn't
|
||||
/// accept as a name.
|
||||
fn is_r1c1(n: &str) -> bool {
|
||||
pub(crate) fn is_r1c1(n: &str) -> bool {
|
||||
let digits = |s: &str| s.bytes().take_while(u8::is_ascii_digit).count();
|
||||
let mut rest = n;
|
||||
if let Some(r) = rest.strip_prefix(['R', 'r']) {
|
||||
|
||||
@@ -474,6 +474,7 @@ fn valid_table_name(name: &str) -> bool {
|
||||
name.chars().count() <= 255
|
||||
&& name.starts_with(|c: char| c.is_alphabetic() || c == '_' || c == '\\')
|
||||
&& CellRef::parse(name).is_none()
|
||||
&& !super::formulas::is_r1c1(name)
|
||||
&& name.chars().enumerate().all(|(i, c)| c.is_alphanumeric() || c == '_' || c == '.' || (i == 0 && c == '\\'))
|
||||
}
|
||||
|
||||
@@ -483,7 +484,8 @@ fn table_rename(s: &mut Session, p: &Json) -> Result<Json> {
|
||||
if !valid_table_name(&name) {
|
||||
return Err(EngineError::Other("The name that you entered is not valid.".into()));
|
||||
}
|
||||
if s.doc()?.wb.table(&name).is_some_and(|x| x != (si, ti)) {
|
||||
let wb = &s.doc()?.wb;
|
||||
if wb.table(&name).is_some_and(|x| x != (si, ti)) || wb.names.iter().any(|n| n.name.eq_ignore_ascii_case(&name)) {
|
||||
return Err(EngineError::Other("The name entered already exists. Enter a unique name.".into()));
|
||||
}
|
||||
edit(s, |cx| {
|
||||
@@ -1581,4 +1583,25 @@ mod tests {
|
||||
assert_eq!(other["formula"], "=Sheet1!A3");
|
||||
assert_eq!(other["value"], json!(20.0));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn table_names_refuse_defined_names_and_r1c1() {
|
||||
let mut s = Session::new();
|
||||
s.new_workbook();
|
||||
s.execute("range.setValues", json!({"range": "A1:A2", "values": [["h"], ["1"]]})).unwrap();
|
||||
s.execute("formulas.defineName", json!({"name": "Rate", "refersTo": "=0.2"})).unwrap();
|
||||
s.execute("insert.table", json!({"range": "A1:A2"})).unwrap();
|
||||
let e = s.execute("table.rename", json!({"table": "Table1", "name": "Rate"})).unwrap_err();
|
||||
assert!(e.to_string().contains("already exists"), "{e}");
|
||||
let e = s.execute("table.rename", json!({"table": "Table1", "name": "rate"})).unwrap_err();
|
||||
assert!(e.to_string().contains("already exists"), "{e}");
|
||||
for n in ["R2C3", "c", "r", "RC", "C5"] {
|
||||
let e = s.execute("table.rename", json!({"table": "Table1", "name": n})).unwrap_err();
|
||||
assert!(e.to_string().contains("not valid"), "{n}: {e}");
|
||||
let e = s.execute("insert.table", json!({"range": "C1:C2", "name": n})).unwrap_err();
|
||||
assert!(e.to_string().contains("not valid"), "{n}: {e}");
|
||||
}
|
||||
s.execute("table.rename", json!({"table": "Table1", "name": "Table1"})).unwrap();
|
||||
s.execute("table.rename", json!({"table": "Table1", "name": "Rates"})).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user