Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/Ultimaker/Cura.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDiego Prado Gesto <d.pradogesto@ultimaker.com>2019-09-10 12:08:21 +0300
committerDiego Prado Gesto <d.pradogesto@ultimaker.com>2019-09-10 12:08:21 +0300
commitb18565d9cf71cfb92565c6838e7b940958ac434f (patch)
tree007f4dccbc9b511c4ef43d19c44c069915fed62d /plugins/XmlMaterialProfile
parent3f3aac7ce5ef63fb0dbedb0323736711451a654f (diff)
parentf561218346fb638ae73ec2c2aaf216b76a4bec68 (diff)
Merge branch 'master' into feature_intent_container_tree
Diffstat (limited to 'plugins/XmlMaterialProfile')
-rw-r--r--plugins/XmlMaterialProfile/XmlMaterialProfile.py46
-rw-r--r--plugins/XmlMaterialProfile/product_to_id.json1
-rw-r--r--plugins/XmlMaterialProfile/tests/TestXmlMaterialProfile.py79
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()