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() {