更新组件绑定验证逻辑以支持已有独立素材验证
- 调整验证逻辑以支持引用项目中已存在的素材,同时拒绝不存在的素材 - 补充相关测试,验证未知素材与跨批次素材引用行为
This commit is contained in:
@@ -107,7 +107,7 @@ fn collect_editable_nodes<'a>(node: &'a Node, output: &mut Vec<EditableNodeConte
|
||||
fn validate_and_materialize(
|
||||
changes: Vec<BindingChangeDraft>,
|
||||
editable_ids: &HashSet<NodeId>,
|
||||
batch_sprite_ids: &HashSet<SpriteAssetId>,
|
||||
known_sprite_ids: &HashSet<SpriteAssetId>,
|
||||
) -> Result<BindingDTO, String> {
|
||||
let mut changed_ids = HashSet::new();
|
||||
let mut materialized = Vec::with_capacity(changes.len());
|
||||
@@ -126,9 +126,9 @@ fn validate_and_materialize(
|
||||
if image
|
||||
.target_graphic
|
||||
.as_ref()
|
||||
.is_some_and(|id| !batch_sprite_ids.contains(id))
|
||||
.is_some_and(|id| !known_sprite_ids.contains(id))
|
||||
{
|
||||
return Err("组件绑定引用了不属于当前批次的独立素材".to_string());
|
||||
return Err("组件绑定引用了不存在的独立素材".to_string());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -258,7 +258,8 @@ pub(crate) async fn bind_components_impl(
|
||||
.ok_or_else(|| "LLM 未返回 bind_ui_components 工具调用".to_string())?;
|
||||
let parsed = serde_json::from_str::<BindingResponse>(&call.arguments)
|
||||
.map_err(|error| format!("组件绑定工具参数无效:{error}"))?;
|
||||
let result = validate_and_materialize(parsed.changes, &editable_ids, &batch_sprite_ids)?;
|
||||
let known_sprite_ids = state.sprite_assets.keys().cloned().collect::<HashSet<_>>();
|
||||
let result = validate_and_materialize(parsed.changes, &editable_ids, &known_sprite_ids)?;
|
||||
eprintln!(
|
||||
"ui_binding.completed ui_images={} sprites={} editable_nodes={} changes={}",
|
||||
state.ui_design_images.len(),
|
||||
@@ -280,21 +281,27 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn materialization_rejects_unapproved_node_and_foreign_sprite() {
|
||||
fn materialization_rejects_unapproved_node_and_unknown_sprite() {
|
||||
let editable = HashSet::from([id("editable")]);
|
||||
let sprites = HashSet::from([SpriteAssetId::new("sprite").expect("valid sprite")]);
|
||||
let known = HashSet::from([
|
||||
SpriteAssetId::new("sprite").expect("valid sprite"),
|
||||
SpriteAssetId::new("other-batch-sprite").expect("valid sprite"),
|
||||
]);
|
||||
let unapproved = BindingChangeDraft {
|
||||
node_id: id("other"),
|
||||
components: Vec::new(),
|
||||
components_status: DraftStatus::NoProblem,
|
||||
};
|
||||
assert!(validate_and_materialize(vec![unapproved], &editable, &sprites).is_err());
|
||||
assert!(validate_and_materialize(vec![unapproved], &editable, &known).is_err());
|
||||
|
||||
let foreign = BindingChangeDraft {
|
||||
// References to sprites from another batch are allowed once they exist in the project.
|
||||
let other_batch = BindingChangeDraft {
|
||||
node_id: id("editable"),
|
||||
components: vec![Component::Image(
|
||||
crate::ui_editor::component::image::ImageComponent {
|
||||
target_graphic: Some(SpriteAssetId::new("foreign").expect("valid sprite")),
|
||||
target_graphic: Some(
|
||||
SpriteAssetId::new("other-batch-sprite").expect("valid sprite"),
|
||||
),
|
||||
image_type: crate::ui_editor::component::image::ImageType::Simple {
|
||||
preserve_aspect: false,
|
||||
},
|
||||
@@ -302,7 +309,22 @@ mod tests {
|
||||
)],
|
||||
components_status: DraftStatus::NoProblem,
|
||||
};
|
||||
assert!(validate_and_materialize(vec![foreign], &editable, &sprites).is_err());
|
||||
assert!(validate_and_materialize(vec![other_batch], &editable, &known).is_ok());
|
||||
|
||||
// References to sprites that do not exist in the project at all are still rejected.
|
||||
let unknown = BindingChangeDraft {
|
||||
node_id: id("editable"),
|
||||
components: vec![Component::Image(
|
||||
crate::ui_editor::component::image::ImageComponent {
|
||||
target_graphic: Some(SpriteAssetId::new("unknown").expect("valid sprite")),
|
||||
image_type: crate::ui_editor::component::image::ImageType::Simple {
|
||||
preserve_aspect: false,
|
||||
},
|
||||
},
|
||||
)],
|
||||
components_status: DraftStatus::NoProblem,
|
||||
};
|
||||
assert!(validate_and_materialize(vec![unknown], &editable, &known).is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
Reference in New Issue
Block a user