| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203 |
- """Unit tests for plate object extraction from 3MF model_settings.config."""
- import pytest
- from defusedxml import ElementTree as ET
- class TestPlateObjectExtraction:
- """Tests for extracting object IDs and names from model_settings.config XML."""
- def test_extract_object_names_from_xml(self):
- """Verify object names are extracted from model_settings.config XML."""
- xml_content = """<?xml version="1.0" encoding="UTF-8"?>
- <config>
- <object id="1">
- <metadata key="name" value="Cube"/>
- </object>
- <object id="2">
- <metadata key="name" value="Sphere"/>
- </object>
- <object id="3">
- <metadata key="name" value="Cylinder"/>
- </object>
- </config>
- """
- root = ET.fromstring(xml_content)
- object_names_by_id = {}
- for obj in root.findall(".//object"):
- obj_id = obj.get("id")
- if obj_id:
- name_meta = obj.find("./metadata[@key='name']")
- if name_meta is not None:
- object_names_by_id[obj_id] = name_meta.get("value", f"Object {obj_id}")
- else:
- object_names_by_id[obj_id] = f"Object {obj_id}"
- assert object_names_by_id == {
- "1": "Cube",
- "2": "Sphere",
- "3": "Cylinder",
- }
- def test_extract_object_names_missing_name(self):
- """Verify objects without names get default names."""
- xml_content = """<?xml version="1.0" encoding="UTF-8"?>
- <config>
- <object id="1">
- <metadata key="name" value="Named Object"/>
- </object>
- <object id="2">
- <!-- No name metadata -->
- </object>
- </config>
- """
- root = ET.fromstring(xml_content)
- object_names_by_id = {}
- for obj in root.findall(".//object"):
- obj_id = obj.get("id")
- if obj_id:
- name_meta = obj.find("./metadata[@key='name']")
- if name_meta is not None:
- object_names_by_id[obj_id] = name_meta.get("value", f"Object {obj_id}")
- else:
- object_names_by_id[obj_id] = f"Object {obj_id}"
- assert object_names_by_id == {
- "1": "Named Object",
- "2": "Object 2",
- }
- def test_extract_plate_object_associations(self):
- """Verify plate-to-object associations are extracted correctly."""
- xml_content = """<?xml version="1.0" encoding="UTF-8"?>
- <config>
- <plate>
- <metadata key="plater_id" value="1"/>
- <model_instance>
- <metadata key="object_id" value="1"/>
- </model_instance>
- <model_instance>
- <metadata key="object_id" value="2"/>
- </model_instance>
- </plate>
- <plate>
- <metadata key="plater_id" value="2"/>
- <model_instance>
- <metadata key="object_id" value="3"/>
- </model_instance>
- </plate>
- </config>
- """
- root = ET.fromstring(xml_content)
- plate_object_ids = {}
- for plate in root.findall(".//plate"):
- plate_id = None
- for meta in plate.findall("metadata"):
- if meta.get("key") in ("plater_id", "plate_id"):
- plate_id = meta.get("value")
- break
- if plate_id:
- object_ids = []
- for instance in plate.findall(".//model_instance"):
- for meta in instance.findall("metadata"):
- if meta.get("key") == "object_id":
- object_ids.append(meta.get("value"))
- plate_object_ids[plate_id] = object_ids
- assert plate_object_ids == {
- "1": ["1", "2"],
- "2": ["3"],
- }
- def test_extract_plate_object_associations_empty_plate(self):
- """Verify empty plates have empty object lists."""
- xml_content = """<?xml version="1.0" encoding="UTF-8"?>
- <config>
- <plate>
- <metadata key="plater_id" value="1"/>
- <!-- No model_instances -->
- </plate>
- </config>
- """
- root = ET.fromstring(xml_content)
- plate_object_ids = {}
- for plate in root.findall(".//plate"):
- plate_id = None
- for meta in plate.findall("metadata"):
- if meta.get("key") in ("plater_id", "plate_id"):
- plate_id = meta.get("value")
- break
- if plate_id:
- object_ids = []
- for instance in plate.findall(".//model_instance"):
- for meta in instance.findall("metadata"):
- if meta.get("key") == "object_id":
- object_ids.append(meta.get("value"))
- plate_object_ids[plate_id] = object_ids
- assert plate_object_ids == {"1": []}
- def test_object_count_matches_objects_length(self):
- """Verify object_count equals len(objects)."""
- objects = ["Cube", "Sphere", "Cylinder"]
- object_count = len(objects)
- assert object_count == 3
- def test_resolve_object_names_from_ids(self):
- """Verify object IDs are resolved to names."""
- object_names_by_id = {
- "1": "Cube",
- "2": "Sphere",
- "3": "Cylinder",
- }
- plate_object_ids = ["1", "3"]
- resolved_names = [object_names_by_id.get(obj_id, f"Object {obj_id}") for obj_id in plate_object_ids]
- assert resolved_names == ["Cube", "Cylinder"]
- def test_resolve_object_names_missing_id(self):
- """Verify missing object IDs get fallback names."""
- object_names_by_id = {
- "1": "Cube",
- }
- plate_object_ids = ["1", "99"] # 99 doesn't exist
- resolved_names = [object_names_by_id.get(obj_id, f"Object {obj_id}") for obj_id in plate_object_ids]
- assert resolved_names == ["Cube", "Object 99"]
- def test_plate_id_alternatives(self):
- """Verify both 'plater_id' and 'plate_id' keys are supported."""
- xml_with_plater_id = """<?xml version="1.0" encoding="UTF-8"?>
- <config>
- <plate>
- <metadata key="plater_id" value="1"/>
- </plate>
- </config>
- """
- xml_with_plate_id = """<?xml version="1.0" encoding="UTF-8"?>
- <config>
- <plate>
- <metadata key="plate_id" value="2"/>
- </plate>
- </config>
- """
- def extract_plate_id(xml_content):
- root = ET.fromstring(xml_content)
- for plate in root.findall(".//plate"):
- for meta in plate.findall("metadata"):
- if meta.get("key") in ("plater_id", "plate_id"):
- return meta.get("value")
- return None
- assert extract_plate_id(xml_with_plater_id) == "1"
- assert extract_plate_id(xml_with_plate_id) == "2"
|