diff --git a/crates/engine/src/lib.rs b/crates/engine/src/lib.rs index fb2a5736..1321fbde 100644 --- a/crates/engine/src/lib.rs +++ b/crates/engine/src/lib.rs @@ -1573,13 +1573,17 @@ impl Session { st.selection.clone_from(&it.selection); } } + // The previous preview's paint is undone with it. + self.pending_paint = None; let rw = cmd::distortcmds::perspective_rewrite(self, cmd, params); let (cmd, params) = rw.as_ref().map_or((cmd, params), |(c, p)| (c.as_str(), p)); let r = self.execute(cmd, params); let params = self.noted(params); let st = self.doc_mut()?; if let Some(it) = &mut st.interaction { - it.preview = Some((cmd.to_string(), params)); + // A failed preview leaves the document at the snapshot, so nothing is left to commit + // (not even an earlier successful preview, which the reset above already undid). + it.preview = r.is_ok().then(|| (cmd.to_string(), params)); } r } diff --git a/crates/engine/src/tests_journal.rs b/crates/engine/src/tests_journal.rs index 810be573..60db6894 100644 --- a/crates/engine/src/tests_journal.rs +++ b/crates/engine/src/tests_journal.rs @@ -371,3 +371,25 @@ fn a_move_drag_is_named_for_whether_it_copied() { assert_eq!(last(&s).as_deref(), Some(label), "begun as {begin}, copy: {copy}"); } } + +#[test] +fn a_failed_preview_is_not_journaled_at_commit() { + let mut s = Session::new(); + s.execute("file.new", &json!({"width": 400, "height": 300})).unwrap(); + s.execute("shape.rectangle", &json!({"x": 10, "y": 10, "width": 100, "height": 50})).unwrap(); + let journal = s.journal.len(); + + // Only a failing preview: committing records nothing. + s.begin_interaction("Bad").unwrap(); + assert!(s.preview("no.such.command", &json!({})).is_err()); + s.commit_interaction().unwrap(); + assert_eq!(s.journal.len(), journal); + + // A good preview followed by a failing one: the document is back at the snapshot, so the + // earlier preview is not journaled either. + s.begin_interaction("Opacity").unwrap(); + s.preview("transparency.set", &json!({"opacity": 50})).unwrap(); + assert!(s.preview("no.such.command", &json!({})).is_err()); + s.commit_interaction().unwrap(); + assert_eq!(s.journal.len(), journal); +} diff --git a/crates/engine/src/tests_paintproxy.rs b/crates/engine/src/tests_paintproxy.rs index db11c3ac..2e2c0d5c 100644 --- a/crates/engine/src/tests_paintproxy.rs +++ b/crates/engine/src/tests_paintproxy.rs @@ -210,6 +210,11 @@ fn live_previews_remember_only_the_committed_colour() { s.preview("paint.setFill", &json!({"color": "#400000"})).unwrap(); s.cancel_interaction().unwrap(); assert_eq!(hexes(&s), ["#300000"], "a cancelled preview is forgotten"); + s.begin_interaction("Color").unwrap(); + s.preview("paint.setFill", &json!({"color": "#500000"})).unwrap(); + assert!(s.preview("no.such.command", &json!({})).is_err()); + s.commit_interaction().unwrap(); + assert_eq!(hexes(&s), ["#300000"], "a preview undone by a failed one is forgotten"); } #[test]