mirror of
https://github.com/storytold/figcraft.git
synced 2026-10-30 05:16:56 -06:00
Implement centralized transactional fix for command batch failures (#229)
* Agent Host changes for agents/fix-command-batch-history-restore * Implement centralized transactional fix for command batch failures - #1 * The batch rollback tests compile, are formatted and expect the tab that was in front The new module used a private helper of plugins_tests and an unused import; the plugin test asserted tab 0 was in front, but it opens a second file first, which is the one in front when the plugin starts and the one the rollback puts back. --------- Co-authored-by: bflatastic <bombayapirat@gmail.com>
This commit is contained in:
co-authored by
bflatastic
parent
f7e726714a
commit
ac65168417
@@ -0,0 +1,63 @@
|
||||
use serde_json::json;
|
||||
|
||||
use crate::plugins_tests::{OnRefusal, install, manifest, script};
|
||||
use crate::{EngineError, Session};
|
||||
|
||||
fn id(value: &serde_json::Value) -> crate::NodeId {
|
||||
crate::params::id_of(&value["id"]).unwrap()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn failed_group_closes_documents_opened_inside_it() {
|
||||
let mut s = Session::new();
|
||||
let original = id(&s.execute("shape.rectangle", &json!({"x": 0, "y": 0, "width": 10, "height": 10})).unwrap());
|
||||
let before_journal = s.journal.clone();
|
||||
let before_history = s.ds().unwrap().history.undo.len();
|
||||
|
||||
let result = s.execute(
|
||||
"command.batch",
|
||||
&json!({
|
||||
"label": "Open then fail",
|
||||
"commands": [
|
||||
{"command": "file.new", "params": {"name": "Temporary"}},
|
||||
{"command": "shape.rectangle", "params": {"x": 20, "y": 20, "width": 10, "height": 10}},
|
||||
{"command": "node.set", "params": {"id": 999999, "props": {"name": "must fail"}}}
|
||||
]
|
||||
}),
|
||||
);
|
||||
|
||||
assert!(result.is_err());
|
||||
assert_eq!(s.docs.len(), 1);
|
||||
assert_eq!(s.active, 0);
|
||||
assert!(s.doc().unwrap().contains(original));
|
||||
assert_eq!(s.ds().unwrap().history.undo.len(), before_history);
|
||||
assert_eq!(s.journal, before_journal);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn failed_plugin_run_restores_each_document_without_restoring_unrelated_state() {
|
||||
let mut s = Session::new();
|
||||
s.execute("file.new", &json!({"name": "Second"})).unwrap();
|
||||
let before_history: Vec<_> = s.docs.iter().map(|ds| ds.history.undo.len()).collect();
|
||||
let calls = [
|
||||
("shape.rectangle", json!({"x": 0, "y": 0, "width": 10, "height": 10})),
|
||||
("doc.nextTab", json!({})),
|
||||
("shape.rectangle", json!({"x": 20, "y": 0, "width": 10, "height": 10})),
|
||||
("node.set", json!({"id": 999999, "props": {"name": "must fail"}})),
|
||||
];
|
||||
install(&mut s, manifest("org.test.rollback", "write", &[]), &script(&calls, OnRefusal::Fail, ""));
|
||||
s.message = Some("keep this".into());
|
||||
let before_journal = s.journal.clone();
|
||||
let before_message = s.message.clone();
|
||||
// The new file is the one in front when the plugin starts.
|
||||
let before_active = s.active;
|
||||
|
||||
let result = s.execute("plugin.run", &json!({"id": "org.test.rollback"}));
|
||||
|
||||
assert!(matches!(result, Err(EngineError::Other(_))));
|
||||
assert_eq!(s.docs.iter().map(|ds| ds.doc.node(ds.page).map_or(0, |page| page.children.len())).collect::<Vec<_>>(), vec![0, 0]);
|
||||
assert_eq!(s.active, before_active, "the tab in front is put back");
|
||||
assert_eq!(s.docs.iter().map(|ds| ds.history.undo.len()).collect::<Vec<_>>(), before_history);
|
||||
assert_eq!(s.journal, before_journal);
|
||||
assert_eq!(s.message, before_message);
|
||||
}
|
||||
Reference in New Issue
Block a user