mirror of
https://github.com/storytold/gridcraft.git
synced 2026-10-30 13:46:47 -06:00
Engine: Stop Action waits while a macro is being debugged
`automate.stopAction` rolls back the undo groups open on the workbook. While a macro was being
debugged it rolled back the debugger's own group and left the debugger set, pointing at a group
that was gone. It is now refused under the debugger's lock with "Finish or stop the macro first",
as edits are; `macro.debug {action: "stop"}` ends the run.
- Test: `stop_action_waits_while_a_macro_is_being_debugged`.
This commit is contained in:
@@ -615,7 +615,10 @@ impl Session {
|
||||
// recording, so stopping again after the run keeps what was recorded.
|
||||
let stops_record_actions =
|
||||
id == "automate.recordActions" && (params.get("stop").and_then(Json::as_bool) == Some(true) || self.recording.is_some());
|
||||
if (spec.undoable || stops_record_actions) && id != "macro.debug" && locked {
|
||||
// Stop Action rolls back the open groups, the debugger's among them, and would leave the
|
||||
// debugger pointing at a group that is gone: stopping the macro is the debugger's own.
|
||||
let stops_groups = id == "automate.stopAction";
|
||||
if (spec.undoable || stops_record_actions || stops_groups) && id != "macro.debug" && locked {
|
||||
return Err(EngineError::Disabled(id.to_string(), macros::debug::BUSY.into()));
|
||||
}
|
||||
let before = self.active().map(|d| (d.uid, d.wb.clone(), d.selection.clone()));
|
||||
|
||||
@@ -295,6 +295,22 @@ fn shifting_makes_room_and_is_checked_again() {
|
||||
assert!(Arc::ptr_eq(&s.doc().unwrap().wb, &start));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn stop_action_waits_while_a_macro_is_being_debugged() {
|
||||
// Stop Action rolls back the open undo groups; the debugger's is one, so it waits for the
|
||||
// debugger, which stops the macro itself.
|
||||
let mut s = s();
|
||||
data(&mut s);
|
||||
put(&mut s, totals());
|
||||
s.execute("macro.debug", json!({"action": "start", "name": "Totals", "inputs": "B2:C5", "breakpoints": ["1"]})).unwrap();
|
||||
let r = s.execute("automate.stopAction", json!({}));
|
||||
assert!(matches!(&r, Err(EngineError::Disabled(_, why)) if why == crate::macros::debug::BUSY), "{r:?}");
|
||||
assert!(s.macro_debug.is_some(), "the debugger is still there");
|
||||
s.execute("macro.debug", json!({"action": "stop"})).unwrap();
|
||||
assert!(s.macro_debug.is_none());
|
||||
s.execute("automate.stopAction", json!({})).unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn closing_the_debugged_workbook_ends_the_debugger() {
|
||||
// `file.close` is not an edit, so the debugger's lock lets it through; the group went with
|
||||
|
||||
+3
-2
@@ -150,8 +150,9 @@ on, as after any recalculation.
|
||||
be given with any action; `breakpointsOnly: true` makes the list replace the steps' own flags. The
|
||||
run stays one undo step; while it is open, edits of the workbooks it touched (its own, and any
|
||||
other its steps changed) are refused with "Finish or stop the macro first", also when another
|
||||
command makes them (stopping Record Actions saves a script), and other workbooks stay
|
||||
editable. Each answer gives the next step with its parameters as they would run, the parameters
|
||||
command makes them (stopping Record Actions saves a script), and so is Automate › Stop Action,
|
||||
which would roll the run's undo group back under the debugger; `stop` ends the run instead. Other
|
||||
workbooks stay editable. Each answer gives the next step with its parameters as they would run, the parameters
|
||||
of the step that just ran, and the cells changed so far.
|
||||
|
||||
## Storage
|
||||
|
||||
Reference in New Issue
Block a user