mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-10-14 19:26:56 -04:00
M1: fix paste into a compound path when undo made a new object reuse the active layer's id (active layer / isolation must still be a layer / group); regression test
Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
1 parent
6a6e3d4bb1
commit
4d1eb16424
2 files changed
+24
-3
No files matched your search
@@ -115,6 +115,25 @@ mod tests {
|
||||
assert!((b.width() - 30.0).abs() < 1e-6 && (b.height() - 40.0).abs() < 1e-6);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn paste_never_lands_in_an_object_that_reused_an_undone_layers_id() {
|
||||
// Found by the model-based test: undo restores the id counter, so a compound path made
|
||||
// after undoing New Layer gets the dead layer's id, which was still the active layer.
|
||||
let mut s = session();
|
||||
let r = s.execute("shape.rectangle", &json!({"x": 0, "y": 0, "width": 10, "height": 10})).unwrap()["id"].clone();
|
||||
s.execute("select.set", &json!({"ids": [r]})).unwrap();
|
||||
s.execute("edit.copy", &json!({})).unwrap();
|
||||
let layer = s.execute("layer.new", &json!({})).unwrap()["id"].as_u64().unwrap();
|
||||
s.execute("edit.undo", &json!({})).unwrap();
|
||||
s.execute("select.set", &json!({"ids": [r]})).unwrap();
|
||||
let c = s.execute("object.compoundPath.make", &json!({})).unwrap()["id"].as_u64().unwrap();
|
||||
assert_eq!(c, layer, "the scenario needs the id to be reused");
|
||||
s.execute("edit.paste", &json!({})).unwrap();
|
||||
let d = &s.doc().unwrap().doc;
|
||||
let compound = d.node(NodeId(c)).unwrap();
|
||||
assert!(compound.children().unwrap().iter().all(|ch| matches!(ch.kind, drawcraft_doc::NodeKind::Path { .. })));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn foreign_svg_and_non_svg_text() {
|
||||
let mut s = session();
|
||||
|
||||
@@ -13,7 +13,7 @@ mod tooling;
|
||||
use std::sync::Arc;
|
||||
|
||||
use drawcraft_color::{Color, Paint};
|
||||
use drawcraft_doc::{Document, NodeId, Selection};
|
||||
use drawcraft_doc::{Document, NodeId, NodeKind, Selection};
|
||||
use drawcraft_geom::Affine;
|
||||
use drawcraft_tools::{PaintDefaults, Tool};
|
||||
use serde_json::Value;
|
||||
@@ -130,12 +130,14 @@ impl DocState {
|
||||
}
|
||||
/// Where new art is inserted: the isolation container, else the active layer.
|
||||
pub fn insertion_parent(&self) -> Option<NodeId> {
|
||||
// Ids are reused after undo (the id counter is part of the document), so a remembered
|
||||
// layer or isolated group must still be one: a pasted group must never land in a path.
|
||||
if let Some(i) = self.isolation
|
||||
&& self.doc.node(i).is_some()
|
||||
&& self.doc.node(i).is_some_and(|n| matches!(n.kind, NodeKind::Group { .. } | NodeKind::Layer { .. }))
|
||||
{
|
||||
return Some(i);
|
||||
}
|
||||
self.active_layer.filter(|l| self.doc.node(*l).is_some_and(|n| !n.locked)).or_else(|| self.doc.default_layer())
|
||||
self.active_layer.filter(|l| self.doc.node(*l).is_some_and(|n| n.is_layer() && !n.locked)).or_else(|| self.doc.default_layer())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user