Engine: Stop Action runs on its own and is not recorded

Run from inside another command, automate.stopAction rolled back that
command's own group, pulling the workbook from under the rest of its run; and
the recording buffer kept it, so a recording could replay the stop inside the
run it was part of. Nested, the command is refused and the group stays; the
recorder leaves it out (record::NOT_RECORDED).
This commit is contained in:
prxnvt
2026-10-24 02:18:07 -04:00
parent f040b4ecaa
commit 6cd4cebfb7
5 changed files with 48 additions and 1 deletions
+26
View File
@@ -820,6 +820,32 @@ fn a_call_that_only_opens_a_dialog_is_not_recorded() {
assert_eq!(s.stop_recording().unwrap().dropped, 0);
}
#[test]
fn stop_action_runs_only_on_its_own_and_is_not_recorded() {
// A step of an action in progress may not stop the action: nested, the command is refused
// and the action's group stays. Nor is Stop Action a step of the person's work: a recording
// leaves it out, so playing the recording back never stops the run it is part of.
let mut s = s();
s.start_recording();
let r: crate::Result<()> = s.grouped("Outer", |s| {
set(s, "A1", "one");
let err = s.execute_nested("automate.stopAction", json!({})).unwrap_err().to_string();
assert!(err.contains("on its own"), "{err}");
set(s, "A2", "two");
Ok(())
});
r.unwrap();
assert_eq!(v(&s, "A2").display(), "two");
assert_eq!(undo_labels(&s), ["Outer"], "the action kept its group");
// On its own it stops a group left open; the recording keeps the edits and not the stop.
let _left = s.group_begin("Left open").unwrap();
set(&mut s, "A3", "three");
assert_eq!(s.execute("automate.stopAction", json!({})).unwrap(), json!({"stopped": true}));
assert!(v(&s, "A3").is_empty());
assert_eq!(recorded_ids(&s), ["cell.set", "cell.set", "cell.set"]);
assert_eq!(s.stop_recording().unwrap().dropped, 0);
}
#[test]
fn the_recorder_keeps_top_level_calls_with_where_they_ran() {
let mut s = s();