From 5c9bb79b1abe44e57ec919499127b37138a9d14a Mon Sep 17 00:00:00 2001 From: mortezanaeemi-ops Date: Mon, 2 Nov 2026 10:34:09 +0330 Subject: [PATCH] Add files via upload --- crates/format/src/fig/map.rs | 6 +++++ crates/format/src/fig/tests.rs | 48 ++++++++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+) diff --git a/crates/format/src/fig/map.rs b/crates/format/src/fig/map.rs index e125028c8..927c233a2 100644 --- a/crates/format/src/fig/map.rs +++ b/crates/format/src/fig/map.rs @@ -517,6 +517,12 @@ impl VarCanon { VAR_CANON.with(|c| c.borrow().as_ref().and_then(|t| t.sets_by_key.get(key).cloned())) } + /// Whether a table is installed on this thread (for tests: none outlives the mapping). + #[cfg(test)] + pub(crate) fn installed() -> bool { + VAR_CANON.with(|c| c.borrow().is_some()) + } + /// Whether variable node `id` is an older copy another one replaces. pub(super) fn superseded(id: &str) -> bool { VAR_CANON.with(|c| c.borrow().as_ref().and_then(|t| t.by_id.get(id)).is_some_and(|canon| canon != id)) diff --git a/crates/format/src/fig/tests.rs b/crates/format/src/fig/tests.rs index d365ff9f7..787c70865 100644 --- a/crates/format/src/fig/tests.rs +++ b/crates/format/src/fig/tests.rs @@ -1675,3 +1675,51 @@ fn removed_library_collection_copies_give_way_to_live_ones() { let page = doc.nodes().find(|n| n.name == "Page").unwrap(); assert_eq!(page.var_modes.get("1:9").map(String::as_str), Some("1:92"), "{warnings:?}"); } + +/// Two copies of a library collection with the same version: the choice doesn't depend on the order +/// of the node changes (the higher guid wins), and the thread's lookup table is gone after the import. +#[test] +fn same_version_library_copies_resolve_deterministically_and_leave_no_table() { + let mode = |id, name: &'static str| o(vec![("id", g(id)), ("name", s(name)), ("sortPosition", s("!"))]); + let set = |id, modes: Vec>| { + node(id, Some((2, "!")), "VARIABLE_SET", "Products", vec![("variableSetModes", arr(modes)), ("key", s("products")), ("version", s("20:1"))]) + }; + let page = node( + 1, + Some((0, "!")), + "CANVAS", + "Page", + vec![( + "variableModeBySetMap", + o(vec![( + "entries", + arr(vec![o(vec![("variableSetID", o(vec![("assetRef", o(vec![("key", s("products"))]))])), ("variableModeID", g(90))])]), + )]), + )], + ); + let base = || { + vec![ + node(0, None, "DOCUMENT", "Document", vec![]), + page.clone(), + node(2, Some((0, "~")), "CANVAS", "Internal", vec![("internalOnly", Kv::Bool(true))]), + ] + }; + let mut picked = Vec::new(); + for swap in [false, true] { + let (a, b) = (set(4, vec![mode(90, "Blue")]), set(6, vec![mode(90, "Blue")])); + let mut nodes = base(); + if swap { + nodes.extend([b, a]); + } else { + nodes.extend([a, b]); + } + let (doc, _) = import(&canvas(&schema(), &o(vec![("nodeChanges", arr(nodes))])), "x").unwrap(); + assert_eq!(doc.variables.collections.len(), 1, "{:?}", doc.variables.collections); + let id = doc.variables.collections[0].id.clone(); + let page = doc.nodes().find(|n| n.name == "Page").unwrap(); + assert_eq!(page.var_modes.get(&id).map(String::as_str), Some("1:90")); + picked.push(id); + assert!(!super::map::VarCanon::installed()); + } + assert_eq!(picked, ["1:6", "1:6"]); +}