mirror of
https://github.com/storytold/figcraft.git
synced 2026-10-27 11:56:50 -06:00
M1: swap defaults past the layer cap say so (#981)
Instance swap defaults that name an in-file main skipped by the layer cap were reported as "isn't in the file": only instance targets fed the capped-mains list. Defaults now feed it too.
This commit is contained in:
@@ -103,6 +103,27 @@ fn instances_of_a_main_the_cap_kept_out_say_so() {
|
||||
assert!(!doc.nodes().any(|n| n.name == "Local main"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn swap_defaults_the_cap_kept_out_say_so() {
|
||||
// A kept main's instance swap default names a main with no instances, which comes after
|
||||
// enough layers to be skipped at the cap.
|
||||
let swap = o(vec![
|
||||
("id", g(70)),
|
||||
("name", Kv::Str("Icon".into())),
|
||||
("type", Kv::Enum("INSTANCE_SWAP")),
|
||||
("initialValue", o(vec![("guidValue", g(900))])),
|
||||
]);
|
||||
let mut nodes = vec![node(1, None, "DOCUMENT", "Document", vec![]), node(2, Some(1), "CANVAS", "Page", vec![])];
|
||||
nodes.push(node(50, Some(2), "SYMBOL", "Card", vec![("size", xy(10.0, 10.0)), ("componentPropDefs", Kv::Array(vec![swap]))]));
|
||||
nodes.extend(main(60, 2, "Filler", 40));
|
||||
nodes.extend(main(900, 2, "Icon main", 10));
|
||||
let (doc, warnings) = import_at(&o(vec![("nodeChanges", Kv::Array(nodes))]), 30);
|
||||
assert!(doc.nodes().any(|n| n.name == "Card"));
|
||||
assert!(!doc.nodes().any(|n| n.name == "Icon main"));
|
||||
assert!(warnings.iter().any(|w| w.starts_with("instance swap properties whose default component was past the layer limit")), "{warnings:?}");
|
||||
assert!(!warnings.iter().any(|w| w.contains("isn't in the file")), "{warnings:?}");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn a_whole_file_past_the_cap_keeps_its_library_links_and_says_so_once() {
|
||||
// A 1 001-layer library main used 210 times: about 210 000 layers in a file far too small to
|
||||
|
||||
@@ -45,7 +45,7 @@ pub(super) fn to_rest(msg: &Kv, name: &str, max_nodes: usize) -> (Value, Vec<Str
|
||||
// Mains in the file that the layer cap kept out: their instances are told apart from those of
|
||||
// components the file doesn't have (#981).
|
||||
if m.count >= m.max_nodes {
|
||||
let capped: Vec<Value> = m.instance_mains.difference(&m.mapped_mains).map(|id| json!(id)).collect();
|
||||
let capped: Vec<Value> = m.referenced_mains.difference(&m.mapped_mains).map(|id| json!(id)).collect();
|
||||
if !capped.is_empty() {
|
||||
out[crate::rest::FIG_CAPPED_MAINS_FIELD] = Value::Array(capped);
|
||||
}
|
||||
@@ -397,9 +397,9 @@ struct Mapper<'a> {
|
||||
library_scan_count: usize,
|
||||
warnings: Vec<String>,
|
||||
count: usize,
|
||||
/// The mains in the file that instances name, and the mains mapped as layers: the difference
|
||||
/// is what the layer cap kept out.
|
||||
instance_mains: BTreeSet<String>,
|
||||
/// The mains in the file that instances or instance swap defaults name, and the mains mapped
|
||||
/// as layers: the difference is what the layer cap kept out.
|
||||
referenced_mains: BTreeSet<String>,
|
||||
mapped_mains: BTreeSet<String>,
|
||||
/// Most layers produced or scanned, instance expansion included; the one place the cap comes
|
||||
/// from (see [`super::layer_budget`]).
|
||||
@@ -478,7 +478,7 @@ impl<'a> Mapper<'a> {
|
||||
library_scan_count: 0,
|
||||
warnings: Vec::new(),
|
||||
count: 0,
|
||||
instance_mains: BTreeSet::new(),
|
||||
referenced_mains: BTreeSet::new(),
|
||||
mapped_mains: BTreeSet::new(),
|
||||
max_nodes,
|
||||
networks: Vec::new(),
|
||||
@@ -1869,7 +1869,12 @@ impl<'a> Mapper<'a> {
|
||||
"BOOL" => json!({"type": "BOOLEAN", "defaultValue": init.and_then(|i| i.get("boolValue")).and_then(Kv::bool).unwrap_or(true)}),
|
||||
"TEXT" => json!({"type": "TEXT", "defaultValue": init.and_then(prop_text).unwrap_or("")}),
|
||||
"INSTANCE_SWAP" => match init.and_then(|i| i.get("guidValue")).and_then(guid) {
|
||||
Some(g) => json!({"type": "INSTANCE_SWAP", "defaultValue": g}),
|
||||
Some(g) => {
|
||||
if self.nodes.contains_key(&g) {
|
||||
self.referenced_mains.insert(g.clone());
|
||||
}
|
||||
json!({"type": "INSTANCE_SWAP", "defaultValue": g})
|
||||
}
|
||||
None => continue,
|
||||
},
|
||||
"VARIANT" => json!({"type": "VARIANT"}),
|
||||
@@ -2013,8 +2018,8 @@ impl<'a> Mapper<'a> {
|
||||
self.warn("instances of components that aren't in the file show no layers");
|
||||
return None;
|
||||
}
|
||||
if !self.instance_mains.contains(&sym) {
|
||||
self.instance_mains.insert(sym.clone());
|
||||
if !self.referenced_mains.contains(&sym) {
|
||||
self.referenced_mains.insert(sym.clone());
|
||||
}
|
||||
if outer.is_some_and(|i| i.symbols.contains(&sym)) {
|
||||
return None;
|
||||
|
||||
Reference in New Issue
Block a user