From e49e102032735b263b027868caa480748eb43121 Mon Sep 17 00:00:00 2001 From: dotCooCoo Date: Sun, 1 Nov 2026 08:43:56 -0800 Subject: [PATCH 1/2] Variables: Lock Variables' description names the refused import variable.lock's params text and the doc comment on Variables::locked said every dataset command still runs while the variables are locked. dataset.import is refused when its header would define a variable; both texts now say so, as docs/mcp.md and dataset.import's params already do. --- crates/doc/src/variables.rs | 3 ++- crates/engine/src/cmd/variablecmds.rs | 2 +- crates/engine/src/tests/variables.rs | 11 ++++++++++- 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/crates/doc/src/variables.rs b/crates/doc/src/variables.rs index 96bccbd0a..09682a106 100644 --- a/crates/doc/src/variables.rs +++ b/crates/doc/src/variables.rs @@ -117,7 +117,8 @@ pub struct Variables { #[serde(default, skip_serializing_if = "Option::is_none")] pub active_dataset: Option, /// Lock Variables: while set, variables can't be defined, deleted or renamed. Objects can - /// still be bound to them and unbound, and datasets still change and apply. + /// still be bound to them and unbound, and datasets still change and apply, except that an + /// import whose header would define a variable is refused. #[serde(default, skip_serializing_if = "std::ops::Not::not")] pub locked: bool, } diff --git a/crates/engine/src/cmd/variablecmds.rs b/crates/engine/src/cmd/variablecmds.rs index 116149ec7..0d7883227 100644 --- a/crates/engine/src/cmd/variablecmds.rs +++ b/crates/engine/src/cmd/variablecmds.rs @@ -641,7 +641,7 @@ pub fn specs() -> Vec { "Lock Variables", ["Window", "Variables"], None, - "{locked?: bool} lock or unlock the variables (default: toggle); saved with the document; a change is one undo step. While locked, variable.define, variable.delete, variable.rename, variable.make…Dynamic and a variable.loadLibrary that would delete or define a variable are refused; binding, unbinding and the dataset commands still run → {locked}", + "{locked?: bool} lock or unlock the variables (default: toggle); saved with the document; a change is one undo step. While locked, variable.define, variable.delete, variable.rename, variable.make…Dynamic and a variable.loadLibrary that would delete or define a variable are refused; binding, unbinding and the dataset commands still run, except a dataset.import whose header would define a variable → {locked}", has_doc, lock ), diff --git a/crates/engine/src/tests/variables.rs b/crates/engine/src/tests/variables.rs index bdacd0e1b..73cdccb85 100644 --- a/crates/engine/src/tests/variables.rs +++ b/crates/engine/src/tests/variables.rs @@ -409,7 +409,8 @@ fn make_dynamic_errors_name_the_command() { } /// Lock Variables refuses defining, deleting and renaming variables, Make … Dynamic included, -/// while binding, unbinding and the dataset commands still run. +/// while binding, unbinding and the dataset commands still run (an import that would define a +/// variable is refused; see `locked_variables_refuse_header_cells_that_define_variables`). #[test] fn locked_variables_refuse_new_deleted_and_renamed_variables() { let mut s = session(); @@ -1324,6 +1325,14 @@ fn locked_variables_refuse_header_cells_that_define_variables() { assert_eq!(imp["defined"], json!(["New"])); } +/// `variable.lock`'s params text names the dataset command it refuses: an import whose header +/// would define a variable. +#[test] +fn the_lock_params_text_names_the_refused_import() { + let params = cmd::find_command("variable.lock").unwrap().params; + assert!(params.contains("the dataset commands still run, except a dataset.import whose header would define a variable"), "{params}"); +} + /// Import / export datasets as CSV: header `name` then variables; round-trip keeps values. #[test] fn datasets_csv_round_trips_and_rejects_bad_input() { From 39e69e8446f5815859d0ddc912e998c5ee9527b7 Mon Sep 17 00:00:00 2001 From: dotCooCoo Date: Sun, 1 Nov 2026 11:48:41 -0800 Subject: [PATCH 2/2] Tests: move the lock params text test next to the lock test --- crates/engine/src/tests/variables.rs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/crates/engine/src/tests/variables.rs b/crates/engine/src/tests/variables.rs index 73cdccb85..cfcdbe6bb 100644 --- a/crates/engine/src/tests/variables.rs +++ b/crates/engine/src/tests/variables.rs @@ -454,6 +454,14 @@ fn locked_variables_refuse_new_deleted_and_renamed_variables() { s.execute("variable.define", &json!({"name": "Other", "kind": "text"})).unwrap(); } +/// `variable.lock`'s params text names the dataset command it refuses: an import whose header +/// would define a variable. +#[test] +fn the_lock_params_text_names_the_refused_import() { + let params = cmd::find_command("variable.lock").unwrap().params; + assert!(params.contains("the dataset commands still run, except a dataset.import whose header would define a variable"), "{params}"); +} + /// Locking is an undo step only when it changes the state, and the lock is saved with the /// document: a file saved locked opens locked, and a file without the key opens unlocked. #[test] @@ -1325,14 +1333,6 @@ fn locked_variables_refuse_header_cells_that_define_variables() { assert_eq!(imp["defined"], json!(["New"])); } -/// `variable.lock`'s params text names the dataset command it refuses: an import whose header -/// would define a variable. -#[test] -fn the_lock_params_text_names_the_refused_import() { - let params = cmd::find_command("variable.lock").unwrap().params; - assert!(params.contains("the dataset commands still run, except a dataset.import whose header would define a variable"), "{params}"); -} - /// Import / export datasets as CSV: header `name` then variables; round-trip keeps values. #[test] fn datasets_csv_round_trips_and_rejects_bad_input() {