diff options
author | Diego Prado Gesto <d.pradogesto@ultimaker.com> | 2019-09-10 12:08:21 +0300 |
---|---|---|
committer | Diego Prado Gesto <d.pradogesto@ultimaker.com> | 2019-09-10 12:08:21 +0300 |
commit | b18565d9cf71cfb92565c6838e7b940958ac434f (patch) | |
tree | 007f4dccbc9b511c4ef43d19c44c069915fed62d /plugins/XmlMaterialProfile | |
parent | 3f3aac7ce5ef63fb0dbedb0323736711451a654f (diff) | |
parent | f561218346fb638ae73ec2c2aaf216b76a4bec68 (diff) |
Merge branch 'master' into feature_intent_container_tree
Diffstat (limited to 'plugins/XmlMaterialProfile')
-rw-r--r-- | plugins/XmlMaterialProfile/XmlMaterialProfile.py | 46 | ||||
-rw-r--r-- | plugins/XmlMaterialProfile/product_to_id.json | 1 | ||||
-rw-r--r-- | plugins/XmlMaterialProfile/tests/TestXmlMaterialProfile.py | 79 |
3 files changed, 105 insertions, 21 deletions
diff --git a/plugins/XmlMaterialProfile/XmlMaterialProfile.py b/plugins/XmlMaterialProfile/XmlMaterialProfile.py index 5ec14fe60c..5a1abf0dfb 100644 --- a/plugins/XmlMaterialProfile/XmlMaterialProfile.py +++ b/plugins/XmlMaterialProfile/XmlMaterialProfile.py @@ -6,7 +6,7 @@ import io import json #To parse the product-to-id mapping file. import os.path #To find the product-to-id mapping. import sys -from typing import Any, Dict, List, Optional, Tuple, cast, Set +from typing import Any, Dict, List, Optional, Tuple, cast, Set, Union import xml.etree.ElementTree as ET from UM.Resources import Resources @@ -20,7 +20,10 @@ from cura.CuraApplication import CuraApplication from cura.Machines.ContainerTree import ContainerTree from cura.Machines.VariantType import VariantType -from .XmlMaterialValidator import XmlMaterialValidator +try: + from .XmlMaterialValidator import XmlMaterialValidator +except (ImportError, SystemError): + import XmlMaterialValidator # type: ignore # This fixes the tests not being able to import. ## Handles serializing and deserializing material containers from an XML file @@ -41,11 +44,11 @@ class XmlMaterialProfile(InstanceContainer): # # \param xml_version: The version number found in an XML file. # \return The corresponding setting_version. - @classmethod - def xmlVersionToSettingVersion(cls, xml_version: str) -> int: + @staticmethod + def xmlVersionToSettingVersion(xml_version: str) -> int: if xml_version == "1.3": return CuraApplication.SettingVersion - return 0 #Older than 1.3. + return 0 # Older than 1.3. def getInheritedFiles(self): return self._inherited_files @@ -407,7 +410,8 @@ class XmlMaterialProfile(InstanceContainer): self._combineElement(self._expandMachinesXML(result), self._expandMachinesXML(second)) return result - def _createKey(self, element): + @staticmethod + def _createKey(element): key = element.tag.split("}")[-1] if "key" in element.attrib: key += " key:" + element.attrib["key"] @@ -423,15 +427,15 @@ class XmlMaterialProfile(InstanceContainer): # Recursively merges XML elements. Updates either the text or children if another element is found in first. # If it does not exist, copies it from second. - def _combineElement(self, first, second): + @staticmethod + def _combineElement(first, second): # Create a mapping from tag name to element. - mapping = {} for element in first: - key = self._createKey(element) + key = XmlMaterialProfile._createKey(element) mapping[key] = element for element in second: - key = self._createKey(element) + key = XmlMaterialProfile._createKey(element) if len(element): # Check if element has children. try: if "setting" in element.tag and not "settings" in element.tag: @@ -441,7 +445,7 @@ class XmlMaterialProfile(InstanceContainer): for child in element: mapping[key].append(child) else: - self._combineElement(mapping[key], element) # Multiple elements, handle those. + XmlMaterialProfile._combineElement(mapping[key], element) # Multiple elements, handle those. except KeyError: mapping[key] = element first.append(element) @@ -742,9 +746,9 @@ class XmlMaterialProfile(InstanceContainer): ContainerRegistry.getInstance().addContainer(container_to_add) @classmethod - def _getSettingsDictForNode(cls, node) -> Tuple[dict, dict]: - node_mapped_settings_dict = dict() - node_unmapped_settings_dict = dict() + def _getSettingsDictForNode(cls, node) -> Tuple[Dict[str, Any], Dict[str, Any]]: + node_mapped_settings_dict = dict() # type: Dict[str, Any] + node_unmapped_settings_dict = dict() # type: Dict[str, Any] # Fetch settings in the "um" namespace um_settings = node.iterfind("./um:setting", cls.__namespaces) @@ -1039,8 +1043,8 @@ class XmlMaterialProfile(InstanceContainer): builder.data(data) builder.end(tag_name) - @classmethod - def _profile_name(cls, material_name, color_name): + @staticmethod + def _profile_name(material_name, color_name): if material_name is None: return "Unknown Material" if color_name != "Generic": @@ -1048,8 +1052,8 @@ class XmlMaterialProfile(InstanceContainer): else: return material_name - @classmethod - def getPossibleDefinitionIDsFromName(cls, name): + @staticmethod + def getPossibleDefinitionIDsFromName(name): name_parts = name.lower().split(" ") merged_name_parts = [] for part in name_parts: @@ -1087,8 +1091,8 @@ class XmlMaterialProfile(InstanceContainer): return product_to_id_map ## Parse the value of the "material compatible" property. - @classmethod - def _parseCompatibleValue(cls, value: str): + @staticmethod + def _parseCompatibleValue(value: str): return value in {"yes", "unknown"} ## Small string representation for debugging. @@ -1117,7 +1121,7 @@ class XmlMaterialProfile(InstanceContainer): "break position": "material_break_retracted_position", "break speed": "material_break_speed", "break temperature": "material_break_temperature" - } + } # type: Dict[str, str] __unmapped_settings = [ "hardware compatible", "hardware recommended" diff --git a/plugins/XmlMaterialProfile/product_to_id.json b/plugins/XmlMaterialProfile/product_to_id.json index 6b78d3fe64..a48eb20a18 100644 --- a/plugins/XmlMaterialProfile/product_to_id.json +++ b/plugins/XmlMaterialProfile/product_to_id.json @@ -6,6 +6,7 @@ "Ultimaker 2+": "ultimaker2_plus", "Ultimaker 3": "ultimaker3", "Ultimaker 3 Extended": "ultimaker3_extended", + "Ultimaker S3": "ultimaker_s3", "Ultimaker S5": "ultimaker_s5", "Ultimaker Original": "ultimaker_original", "Ultimaker Original+": "ultimaker_original_plus", diff --git a/plugins/XmlMaterialProfile/tests/TestXmlMaterialProfile.py b/plugins/XmlMaterialProfile/tests/TestXmlMaterialProfile.py new file mode 100644 index 0000000000..1bc19f773a --- /dev/null +++ b/plugins/XmlMaterialProfile/tests/TestXmlMaterialProfile.py @@ -0,0 +1,79 @@ +from unittest.mock import patch, MagicMock +import sys +import os + +# Prevents error: "PyCapsule_GetPointer called with incorrect name" with conflicting SIP configurations between Arcus and PyQt: Import Arcus and Savitar first! +import Savitar # Dont remove this line +import Arcus # No really. Don't. It needs to be there! +from UM.Qt.QtApplication import QtApplication # QtApplication import is required, even though it isn't used. + +import pytest +import XmlMaterialProfile + +def createXmlMaterialProfile(material_id): + try: + return XmlMaterialProfile.XmlMaterialProfile.XmlMaterialProfile(material_id) + except AttributeError: + return XmlMaterialProfile.XmlMaterialProfile(material_id) + + +def test_setName(): + material_1 = createXmlMaterialProfile("herpderp") + material_2 = createXmlMaterialProfile("OMGZOMG") + + material_1.getMetaData()["base_file"] = "herpderp" + material_2.getMetaData()["base_file"] = "herpderp" + + container_registry = MagicMock() + container_registry.isReadOnly = MagicMock(return_value = False) + container_registry.findInstanceContainers = MagicMock(return_value = [material_1, material_2]) + + with patch("UM.Settings.ContainerRegistry.ContainerRegistry.getInstance", MagicMock(return_value = container_registry)): + material_1.setName("beep!") + + assert material_1.getName() == "beep!" + assert material_2.getName() == "beep!" + + +def test_setDirty(): + material_1 = createXmlMaterialProfile("herpderp") + material_2 = createXmlMaterialProfile("OMGZOMG") + + material_1.getMetaData()["base_file"] = "herpderp" + material_2.getMetaData()["base_file"] = "herpderp" + + container_registry = MagicMock() + container_registry.isReadOnly = MagicMock(return_value=False) + container_registry.findContainers = MagicMock(return_value=[material_1, material_2]) + + # Sanity check. Since we did a hacky thing to set the metadata, the container should not be dirty. + # But this test assumes that it works like that, so we need to validate that. + assert not material_1.isDirty() + assert not material_2.isDirty() + + with patch("UM.Settings.ContainerRegistry.ContainerRegistry.getInstance", MagicMock(return_value=container_registry)): + material_2.setDirty(True) + + assert material_1.isDirty() + assert material_2.isDirty() + + # Setting the base material dirty does not set it's child as dirty. + with patch("UM.Settings.ContainerRegistry.ContainerRegistry.getInstance", MagicMock(return_value=container_registry)): + material_1.setDirty(False) + + assert not material_1.isDirty() + assert material_2.isDirty() + + +def test_serializeNonBaseMaterial(): + material_1 = createXmlMaterialProfile("herpderp") + material_1.getMetaData()["base_file"] = "omgzomg" + + container_registry = MagicMock() + container_registry.isReadOnly = MagicMock(return_value=False) + container_registry.findContainers = MagicMock(return_value=[material_1]) + + with patch("UM.Settings.ContainerRegistry.ContainerRegistry.getInstance", MagicMock(return_value=container_registry)): + with pytest.raises(NotImplementedError): + # This material is not a base material, so it can't be serialized! + material_1.serialize() |