diff --git a/crates/engine/src/lib.rs b/crates/engine/src/lib.rs index 399bb1c88..c1de0c401 100644 --- a/crates/engine/src/lib.rs +++ b/crates/engine/src/lib.rs @@ -454,6 +454,10 @@ impl Session { if i < self.docs.len() { let d = self.docs.remove(i); self.groups.retain(|g| g.doc != d.uid); + // A macro being debugged in this workbook ends with it; its group just went. + if self.macro_debug.as_ref().is_some_and(|m| m.doc == d.uid) { + self.macro_debug = None; + } if self.active >= self.docs.len() { self.active = self.docs.len().saturating_sub(1); } diff --git a/crates/engine/src/tests/macros.rs b/crates/engine/src/tests/macros.rs index 207e4c944..95e3b632e 100644 --- a/crates/engine/src/tests/macros.rs +++ b/crates/engine/src/tests/macros.rs @@ -232,6 +232,26 @@ fn shifting_makes_room_and_is_checked_again() { assert!(Arc::ptr_eq(&s.doc().unwrap().wb, &start)); } +#[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 + // the document, and so must the debugger, or the next workbook could not debug anything and + // the state would report that no document is open. + 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(); + assert!(s.macro_debug.is_some()); + s.execute("file.close", json!({"force": true})).unwrap(); + assert!(s.macro_debug.is_none(), "the debugger ended with its workbook"); + s.new_workbook(); + data(&mut s); + put(&mut s, totals()); + s.execute("macro.debug", json!({"action": "start", "name": "Totals", "inputs": "B2:C5", "breakpoints": ["1"]})).unwrap(); + assert!(s.execute("macro.debug", json!({})).is_ok(), "the new workbook can be debugged"); + s.execute("macro.debug", json!({"action": "stop"})).unwrap(); +} + #[test] fn the_footprint_covers_other_sheets_objects_and_edges() { let mut s = s();