mirror of
https://github.com/storytold/figcraft.git
synced 2026-11-13 05:42:38 +00:00
codeConnect.import: index components by name and describe each once (#2265)
This commit is contained in:
1 parent
6bc8bbaef1
commit
6e9582c0a0
2 files changed
+22
-4
No files matched your search
@@ -285,3 +285,16 @@ fn vue_layer_trees_import_connected_components_in_script_setup() {
|
||||
assert!(code.starts_with(want), "{code}");
|
||||
assert_eq!(code.matches("import Card").count(), 1, "{code}");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn many_entries_for_one_component_each_link() {
|
||||
let mut s = Session::new();
|
||||
let (_, hover) = button(&mut s);
|
||||
let links: Vec<Value> = (0..crate::code_connect::MAX_FILE_LINKS)
|
||||
.map(|i| json!({"component": "Button", "language": if i % 2 == 0 { "react" } else { "vue" }, "name": "Button", "template": "<Button />"}))
|
||||
.collect();
|
||||
let r = ex(&mut s, "codeConnect.import", json!({"json": {"version": 1, "links": links}}));
|
||||
assert_eq!(r["linked"], crate::code_connect::MAX_FILE_LINKS, "{r}");
|
||||
let i = idv(&ex(&mut s, "instance.create", json!({"component": hover, "x": 0, "y": 500})));
|
||||
assert_eq!(code(&mut s, i, "react"), "<Button />\n");
|
||||
}
|
||||
@@ -669,7 +669,12 @@ fn import(s: &mut Session, p: &Value) -> Result<Value> {
|
||||
}
|
||||
let doc = s.doc()?;
|
||||
// Components and sets by name (variants are linked through their set).
|
||||
let owners: Vec<(String, NodeId)> = doc.nodes().filter(|n| owner(doc, n.id) == Some(n.id)).map(|n| (n.name.clone(), n.id)).collect();
|
||||
let mut owners: std::collections::HashMap<&str, Vec<NodeId>> = std::collections::HashMap::new();
|
||||
for n in doc.nodes().filter(|n| owner(doc, n.id) == Some(n.id)) {
|
||||
owners.entry(n.name.as_str()).or_default().push(n.id);
|
||||
}
|
||||
// What each component looks like, worked out once however many entries name it.
|
||||
let mut described: std::collections::HashMap<NodeId, Option<Component>> = std::collections::HashMap::new();
|
||||
let mut warnings: Vec<String> = Vec::new();
|
||||
let mut apply: Vec<(NodeId, CodeLink)> = Vec::new();
|
||||
for (i, e) in entries.iter().enumerate() {
|
||||
@@ -689,13 +694,13 @@ fn import(s: &mut Session, p: &Value) -> Result<Value> {
|
||||
name: name.into(),
|
||||
template: template.into(),
|
||||
};
|
||||
let matches: Vec<NodeId> = owners.iter().filter(|(n, _)| n == component).map(|(_, id)| *id).collect();
|
||||
let matches = owners.get(component).cloned().unwrap_or_default();
|
||||
if matches.is_empty() {
|
||||
warnings.push(format!("link {}: no component named {component:?}", i + 1));
|
||||
}
|
||||
for id in matches {
|
||||
let Some(c) = main_of(doc, id).and_then(|m| describe(doc, m)) else { continue };
|
||||
match check(&c, &link, lang) {
|
||||
let Some(c) = described.entry(id).or_insert_with(|| main_of(doc, id).and_then(|m| describe(doc, m))).as_ref() else { continue };
|
||||
match check(c, &link, lang) {
|
||||
Ok(_) => apply.push((id, link.clone())),
|
||||
Err(err) => warnings.push(format!("link {} ({component}): {err}", i + 1)),
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user