use super::*;
use ifc_lite_core::{build_entity_index, EntityDecoder};
fn grouped_rel_defines_content() -> &'static [u8] {
b"ISO-10303-21;\nHEADER;\nENDSEC;\nDATA;\n\
#20=IFCPROPERTYSET('gid1',$,'Pset_A',$,(#30));\n\
#22=IFCELEMENTQUANTITY('gid2',$,'Qto_B',$,$,(#31));\n\
#40=IFCRELDEFINESBYPROPERTIES('gid3',$,$,$,(#50),(#20,#22));\n\
ENDSEC;\nEND-ISO-10303-21;\n"
}
#[test]
fn collects_both_property_sets_from_a_grouped_relating_property_definition() {
let content = grouped_rel_defines_content();
let index = build_entity_index(content);
let mut decoder = EntityDecoder::with_index(content, index);
let rel_defines = decoder
.decode_by_id(40)
.expect("IFCRELDEFINESBYPROPERTIES #40 should decode");
let link = collect_rel_defines_by_properties_link(&rel_defines)
.expect("a grouped RelatingPropertyDefinition must not be silently dropped");
assert_eq!(
link.property_set_ids,
vec![20, 22],
"both entries of the grouped IfcPropertySetDefinitionSet must be collected, \
not just the first (or none, if get_ref alone returned None for the list)"
);
assert_eq!(link.related_object_ids, vec![50]);
}
#[test]
fn collects_a_single_bare_relating_property_definition() {
let content = b"ISO-10303-21;\nHEADER;\nENDSEC;\nDATA;\n\
#20=IFCPROPERTYSET('gid1',$,'Pset_A',$,(#30));\n\
#40=IFCRELDEFINESBYPROPERTIES('gid3',$,$,$,(#50),#20);\n\
ENDSEC;\nEND-ISO-10303-21;\n";
let index = build_entity_index(content);
let mut decoder = EntityDecoder::with_index(content, index);
let rel_defines = decoder
.decode_by_id(40)
.expect("IFCRELDEFINESBYPROPERTIES #40 should decode");
let link = collect_rel_defines_by_properties_link(&rel_defines)
.expect("a bare RelatingPropertyDefinition must still resolve");
assert_eq!(link.property_set_ids, vec![20]);
assert_eq!(link.related_object_ids, vec![50]);
}
#[test]
fn direct_assignment_applies_every_grouped_property_set() {
let mut jobs = vec![EntityJob {
id: 50,
ifc_type: IfcType::IfcSpace,
start: 0,
end: 0,
product_definition_shape_id: None,
element_color: [0.0; 4],
global_id: None,
name: None,
presentation_layer: None,
space_zone_properties: None,
representation_map_id: None,
}];
let property_values_by_id = FxHashMap::from_iter([
(30, ("PropA".to_string(), "value-a".to_string())),
(31, ("PropB".to_string(), "value-b".to_string())),
]);
let property_sets_by_id = FxHashMap::from_iter([
(
20,
PropertySetDefinition {
name: Some("Pset_A".to_string()),
property_ids: vec![30],
},
),
(
22,
PropertySetDefinition {
name: Some("Pset_B".to_string()),
property_ids: vec![31],
},
),
]);
let links = [RelDefinesByPropertiesLink {
property_set_ids: vec![20, 22],
related_object_ids: vec![50],
}];
assign_space_zone_properties(
&mut jobs,
&property_values_by_id,
&property_sets_by_id,
&links,
);
let properties = jobs[0]
.space_zone_properties
.as_ref()
.expect("direct assignment should retain both grouped property sets");
assert_eq!(
properties.get("Pset_A.PropA").map(String::as_str),
Some("value-a")
);
assert_eq!(
properties.get("Pset_B.PropB").map(String::as_str),
Some("value-b")
);
}