Engine: a stopped recording reports the steps cut at the macro step limit in dropped

A recording keeps up to 100,000 commands, and inlined macro and script runs can add more, but a macro holds at most 10,000 steps. Stopping truncated the converted steps to that limit without saying so: dropped counted only the recorder's own overflow, so a 10,005-step recording saved a 10,000-step macro and reported nothing missing. The steps cut at the macro limit are now added to dropped.
This commit is contained in:
prxnvt
2026-10-22 02:26:33 -04:00
parent 3f5f6ea4f1
commit ea691f703c
3 changed files with 32 additions and 5 deletions
+5 -1
View File
@@ -223,6 +223,8 @@ fn save_recording(s: &mut Session, p: &Json, rec: &crate::record::Recorder, star
None => crate::macros::next_name(&wb),
};
let mut converted = crate::macros::recorder::convert(&name, &start, &rec.steps, &wb);
// Steps past the macro limit are left out and counted with the ones the recorder dropped.
let cut = converted.mac.steps.len().saturating_sub(gridcraft_model::MAX_MACRO_STEPS);
converted.mac.steps.truncate(gridcraft_model::MAX_MACRO_STEPS);
if let Some(desc) = str_param(p, "description") {
converted.mac.description = desc.chars().take(gridcraft_model::MAX_MACRO_TEXT).collect();
@@ -235,5 +237,7 @@ fn save_recording(s: &mut Session, p: &Json, rec: &crate::record::Recorder, star
let saved = s.execute("macro.save", json!({"macro": crate::macros::macro_json(&converted.mac), "replace": false}));
s.set_active(active);
saved?;
Ok(json!({"recording": false, "saved": name, "steps": steps, "dropped": rec.dropped, "skipped": converted.skipped, "inputs": inputs}))
Ok(
json!({"recording": false, "saved": name, "steps": steps, "dropped": rec.dropped.saturating_add(cut), "skipped": converted.skipped, "inputs": inputs}),
)
}
+22
View File
@@ -1141,3 +1141,25 @@ fn a_name_given_when_recording_stops_never_replaces_a_macro() {
assert_eq!(recorded(&mut s, "Tidy"), ["cell.set {\"cell\":\"Z9\",\"input\":\"mine\"}"]);
assert_eq!(recorded(&mut s, "tidy (2)"), ["cell.set {\"cell\":\"A1\",\"input\":\"recorded\"}"]);
}
#[test]
fn steps_past_the_macro_limit_are_counted_as_dropped() {
let mut s = s();
s.execute("macro.record", json!({"relative": false})).unwrap();
let (doc, selection) = (s.doc().unwrap().uid, s.doc().unwrap().selection.clone());
let rec = s.recorder.as_mut().unwrap();
for i in 0..gridcraft_model::MAX_MACRO_STEPS + 5 {
rec.push(crate::record::RecordedStep {
doc,
sheet: 0,
sheet_name: "Sheet1".into(),
selection: selection.clone(),
id: "cell.set".into(),
params: json!({"cell": "A1", "input": i.to_string()}),
});
}
rec.dropped = 3;
let r = s.execute("macro.record", json!({"stop": true, "name": "Long"})).unwrap();
assert_eq!(r["steps"], gridcraft_model::MAX_MACRO_STEPS);
assert_eq!(r["dropped"], 8, "{r}");
}
+5 -4
View File
@@ -123,10 +123,11 @@ of the step that just ran, and the cells changed so far.
stopping never replaces a macro). The macro is saved in the workbook where recording started, even if
another one is active; if that workbook was closed, stopping ends the recording without saving it.
When saving the recording fails (a name the check refuses, a workbook at its macro limit),
recording goes on, so stopping again keeps what was recorded. With relative references the
selection when recording starts is the example input: references in and near it on its sheet become
tokens (on another sheet `C4` stays that sheet's `C4`), and the input's shape, header and column
types are inferred. Toggles such as Bold are recorded with the state they set
recording goes on, so stopping again keeps what was recorded. A recording keeps up to 100,000
commands and a macro up to 10,000 steps; steps past either limit are left out and counted in
`dropped`. With relative references the selection when recording starts is the example input:
references in and near it on its sheet become tokens (on another sheet `C4` stays that sheet's
`C4`), and the input's shape, header and column types are inferred. Toggles such as Bold are recorded with the state they set
(`"on": true`), so playing them back sets them rather than flipping them. Commands a macro may not
run are left out and listed in the result, also from the steps of a macro or script run while
recording; a macro run while recording is replaced by its steps when it has no inputs, no output