diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index ef59d5a7f6..4dee5ae813 100755 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -1,11 +1,10 @@ # Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. -import copy import os import sys import time -from typing import cast, TYPE_CHECKING, Optional +from typing import cast, TYPE_CHECKING import numpy @@ -105,6 +104,7 @@ from cura.Settings.ExtrudersModel import ExtrudersModel from cura.Settings.MaterialSettingsVisibilityHandler import MaterialSettingsVisibilityHandler from cura.Settings.ContainerManager import ContainerManager from cura.Settings.SidebarCustomMenuItemsModel import SidebarCustomMenuItemsModel +import cura.Settings.cura_empty_instance_containers from cura.ObjectsModel import ObjectsModel @@ -368,42 +368,23 @@ class CuraApplication(QtApplication): # Add empty variant, material and quality containers. # Since they are empty, they should never be serialized and instead just programmatically created. # We need them to simplify the switching between materials. - empty_container = self._container_registry.getEmptyInstanceContainer() - self.empty_container = empty_container + self.empty_container = cura.Settings.cura_empty_instance_containers.empty_container - empty_definition_changes_container = copy.deepcopy(empty_container) - empty_definition_changes_container.setMetaDataEntry("id", "empty_definition_changes") - empty_definition_changes_container.setMetaDataEntry("type", "definition_changes") - self._container_registry.addContainer(empty_definition_changes_container) - self.empty_definition_changes_container = empty_definition_changes_container + self._container_registry.addContainer( + cura.Settings.cura_empty_instance_containers.empty_definition_changes_container) + self.empty_definition_changes_container = cura.Settings.cura_empty_instance_containers.empty_definition_changes_container - empty_variant_container = copy.deepcopy(empty_container) - empty_variant_container.setMetaDataEntry("id", "empty_variant") - empty_variant_container.setMetaDataEntry("type", "variant") - self._container_registry.addContainer(empty_variant_container) - self.empty_variant_container = empty_variant_container + self._container_registry.addContainer(cura.Settings.cura_empty_instance_containers.empty_variant_container) + self.empty_variant_container = cura.Settings.cura_empty_instance_containers.empty_variant_container - empty_material_container = copy.deepcopy(empty_container) - empty_material_container.setMetaDataEntry("id", "empty_material") - empty_material_container.setMetaDataEntry("type", "material") - self._container_registry.addContainer(empty_material_container) - self.empty_material_container = empty_material_container + self._container_registry.addContainer(cura.Settings.cura_empty_instance_containers.empty_material_container) + self.empty_material_container = cura.Settings.cura_empty_instance_containers.empty_material_container - empty_quality_container = copy.deepcopy(empty_container) - empty_quality_container.setMetaDataEntry("id", "empty_quality") - empty_quality_container.setName("Not Supported") - empty_quality_container.setMetaDataEntry("quality_type", "not_supported") - empty_quality_container.setMetaDataEntry("type", "quality") - empty_quality_container.setMetaDataEntry("supported", False) - self._container_registry.addContainer(empty_quality_container) - self.empty_quality_container = empty_quality_container + self._container_registry.addContainer(cura.Settings.cura_empty_instance_containers.empty_quality_container) + self.empty_quality_container = cura.Settings.cura_empty_instance_containers.empty_quality_container - empty_quality_changes_container = copy.deepcopy(empty_container) - empty_quality_changes_container.setMetaDataEntry("id", "empty_quality_changes") - empty_quality_changes_container.setMetaDataEntry("type", "quality_changes") - empty_quality_changes_container.setMetaDataEntry("quality_type", "not_supported") - self._container_registry.addContainer(empty_quality_changes_container) - self.empty_quality_changes_container = empty_quality_changes_container + self._container_registry.addContainer(cura.Settings.cura_empty_instance_containers.empty_quality_changes_container) + self.empty_quality_changes_container = cura.Settings.cura_empty_instance_containers.empty_quality_changes_container # Initializes the version upgrade manager with by providing the paths for each resource type and the latest # versions. diff --git a/cura/OneAtATimeIterator.py b/cura/OneAtATimeIterator.py index e7ad833e1c..a08f3ed2bf 100644 --- a/cura/OneAtATimeIterator.py +++ b/cura/OneAtATimeIterator.py @@ -76,6 +76,8 @@ class OneAtATimeIterator(Iterator): continue bounding_box = node.getBoundingBox() + if not bounding_box: + continue from UM.Math.Polygon import Polygon bounding_box_polygon = Polygon([[bounding_box.left, bounding_box.front], [bounding_box.left, bounding_box.back], diff --git a/cura/Settings/CuraContainerStack.py b/cura/Settings/CuraContainerStack.py index bd3380dfb2..c8d1d9e370 100755 --- a/cura/Settings/CuraContainerStack.py +++ b/cura/Settings/CuraContainerStack.py @@ -1,7 +1,7 @@ # Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. -from typing import Any, cast, List, Optional, Union +from typing import Any, cast, List, Optional from PyQt5.QtCore import pyqtProperty, pyqtSignal, QObject from UM.Application import Application @@ -13,6 +13,7 @@ from UM.Settings.InstanceContainer import InstanceContainer from UM.Settings.DefinitionContainer import DefinitionContainer from UM.Settings.ContainerRegistry import ContainerRegistry from UM.Settings.Interfaces import ContainerInterface, DefinitionContainerInterface +from cura.Settings import cura_empty_instance_containers from . import Exceptions @@ -39,14 +40,12 @@ class CuraContainerStack(ContainerStack): def __init__(self, container_id: str) -> None: super().__init__(container_id) - self._container_registry = ContainerRegistry.getInstance() #type: ContainerRegistry + self._empty_instance_container = cura_empty_instance_containers.empty_container #type: InstanceContainer - self._empty_instance_container = self._container_registry.getEmptyInstanceContainer() #type: InstanceContainer - - self._empty_quality_changes = self._container_registry.findInstanceContainers(id = "empty_quality_changes")[0] #type: InstanceContainer - self._empty_quality = self._container_registry.findInstanceContainers(id = "empty_quality")[0] #type: InstanceContainer - self._empty_material = self._container_registry.findInstanceContainers(id = "empty_material")[0] #type: InstanceContainer - self._empty_variant = self._container_registry.findInstanceContainers(id = "empty_variant")[0] #type: InstanceContainer + self._empty_quality_changes = cura_empty_instance_containers.empty_quality_changes_container #type: InstanceContainer + self._empty_quality = cura_empty_instance_containers.empty_quality_container #type: InstanceContainer + self._empty_material = cura_empty_instance_containers.empty_material_container #type: InstanceContainer + self._empty_variant = cura_empty_instance_containers.empty_variant_container #type: InstanceContainer self._containers = [self._empty_instance_container for i in range(len(_ContainerIndexes.IndexTypeMap))] #type: List[ContainerInterface] self._containers[_ContainerIndexes.QualityChanges] = self._empty_quality_changes diff --git a/cura/Settings/ExtruderStack.py b/cura/Settings/ExtruderStack.py index 47846fc1dd..ca687e358b 100644 --- a/cura/Settings/ExtruderStack.py +++ b/cura/Settings/ExtruderStack.py @@ -139,9 +139,6 @@ class ExtruderStack(CuraContainerStack): super().deserialize(contents, file_name) if "enabled" not in self.getMetaData(): self.setMetaDataEntry("enabled", "True") - stacks = ContainerRegistry.getInstance().findContainerStacks(id=self.getMetaDataEntry("machine", "")) - if stacks: - self.setNextStack(stacks[0]) def _onPropertiesChanged(self, key: str, properties: Dict[str, Any]) -> None: # When there is a setting that is not settable per extruder that depends on a value from a setting that is, diff --git a/cura/Settings/cura_empty_instance_containers.py b/cura/Settings/cura_empty_instance_containers.py new file mode 100644 index 0000000000..d76407ed79 --- /dev/null +++ b/cura/Settings/cura_empty_instance_containers.py @@ -0,0 +1,56 @@ +# Copyright (c) 2018 Ultimaker B.V. +# Cura is released under the terms of the LGPLv3 or higher. + +import copy + +from UM.Settings.constant_instance_containers import EMPTY_CONTAINER_ID, empty_container + + +# Empty definition changes +EMPTY_DEFINITION_CHANGES_CONTAINER_ID = "empty_definition_changes" +empty_definition_changes_container = copy.deepcopy(empty_container) +empty_definition_changes_container.setMetaDataEntry("id", EMPTY_DEFINITION_CHANGES_CONTAINER_ID) +empty_definition_changes_container.setMetaDataEntry("type", "definition_changes") + +# Empty variant +EMPTY_VARIANT_CONTAINER_ID = "empty_variant" +empty_variant_container = copy.deepcopy(empty_container) +empty_variant_container.setMetaDataEntry("id", EMPTY_VARIANT_CONTAINER_ID) +empty_variant_container.setMetaDataEntry("type", "variant") + +# Empty material +EMPTY_MATERIAL_CONTAINER_ID = "empty_material" +empty_material_container = copy.deepcopy(empty_container) +empty_material_container.setMetaDataEntry("id", EMPTY_MATERIAL_CONTAINER_ID) +empty_material_container.setMetaDataEntry("type", "material") + +# Empty quality +EMPTY_QUALITY_CONTAINER_ID = "empty_quality" +empty_quality_container = copy.deepcopy(empty_container) +empty_quality_container.setMetaDataEntry("id", EMPTY_QUALITY_CONTAINER_ID) +empty_quality_container.setName("Not Supported") +empty_quality_container.setMetaDataEntry("quality_type", "not_supported") +empty_quality_container.setMetaDataEntry("type", "quality") +empty_quality_container.setMetaDataEntry("supported", False) + +# Empty quality changes +EMPTY_QUALITY_CHANGES_CONTAINER_ID = "empty_quality_changes" +empty_quality_changes_container = copy.deepcopy(empty_container) +empty_quality_changes_container.setMetaDataEntry("id", EMPTY_QUALITY_CHANGES_CONTAINER_ID) +empty_quality_changes_container.setMetaDataEntry("type", "quality_changes") +empty_quality_changes_container.setMetaDataEntry("quality_type", "not_supported") + + +__all__ = ["EMPTY_CONTAINER_ID", + "empty_container", # For convenience + "EMPTY_DEFINITION_CHANGES_CONTAINER_ID", + "empty_definition_changes_container", + "EMPTY_VARIANT_CONTAINER_ID", + "empty_variant_container", + "EMPTY_MATERIAL_CONTAINER_ID", + "empty_material_container", + "EMPTY_QUALITY_CHANGES_CONTAINER_ID", + "empty_quality_changes_container", + "EMPTY_QUALITY_CONTAINER_ID", + "empty_quality_container" + ] diff --git a/tests/Settings/TestCuraContainerRegistry.py b/tests/Settings/TestCuraContainerRegistry.py index 38b2e0f6ea..af478c3b2b 100644 --- a/tests/Settings/TestCuraContainerRegistry.py +++ b/tests/Settings/TestCuraContainerRegistry.py @@ -1,61 +1,15 @@ -# Copyright (c) 2017 Ultimaker B.V. +# Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. import os #To find the directory with test files and find the test files. -import pytest #This module contains unit tests. -import shutil #To copy files to make a temporary file. import unittest.mock #To mock and monkeypatch stuff. -import urllib.parse -import copy -import cura.CuraApplication -from cura.Settings.CuraContainerRegistry import CuraContainerRegistry #The class we're testing. +from UM.Settings.DefinitionContainer import DefinitionContainer from cura.Settings.ExtruderStack import ExtruderStack #Testing for returning the correct types of stacks. from cura.Settings.GlobalStack import GlobalStack #Testing for returning the correct types of stacks. -from UM.Resources import Resources #Mocking some functions of this. import UM.Settings.InstanceContainer #Creating instance containers to register. import UM.Settings.ContainerRegistry #Making empty container stacks. import UM.Settings.ContainerStack #Setting the container registry here properly. -from UM.Settings.DefinitionContainer import DefinitionContainer -from UM.Settings.ContainerRegistry import ContainerRegistry - -def creteEmptyContainers(): - empty_container = ContainerRegistry.getInstance().getEmptyInstanceContainer() - empty_variant_container = copy.deepcopy(empty_container) - empty_variant_container.setMetaDataEntry("id", "empty_variant") - empty_variant_container.setMetaDataEntry("type", "variant") - ContainerRegistry.getInstance().addContainer(empty_variant_container) - - empty_material_container = copy.deepcopy(empty_container) - empty_material_container.setMetaDataEntry("id", "empty_material") - empty_material_container.setMetaDataEntry("type", "material") - ContainerRegistry.getInstance().addContainer(empty_material_container) - - empty_quality_container = copy.deepcopy(empty_container) - empty_quality_container.setMetaDataEntry("id", "empty_quality") - empty_quality_container.setName("Not Supported") - empty_quality_container.setMetaDataEntry("quality_type", "not_supported") - empty_quality_container.setMetaDataEntry("type", "quality") - empty_quality_container.setMetaDataEntry("supported", False) - ContainerRegistry.getInstance().addContainer(empty_quality_container) - - empty_quality_changes_container = copy.deepcopy(empty_container) - empty_quality_changes_container.setMetaDataEntry("id", "empty_quality_changes") - empty_quality_changes_container.setMetaDataEntry("type", "quality_changes") - ContainerRegistry.getInstance().addContainer(empty_quality_changes_container) - -## Gives a fresh CuraContainerRegistry instance. -@pytest.fixture() -def container_registry(): - registry = CuraContainerRegistry() - UM.Settings.InstanceContainer.setContainerRegistry(registry) - UM.Settings.ContainerStack.setContainerRegistry(registry) - return registry - -## Gives an arbitrary definition container. -@pytest.fixture() -def definition_container(): - return DefinitionContainer(container_id = "Test Definition") def teardown(): #If the temporary file for the legacy file rename test still exists, remove it. @@ -64,44 +18,47 @@ def teardown(): os.remove(temporary_file) ## Tests whether addContainer properly converts to ExtruderStack. -def test_addContainerExtruderStack(container_registry, definition_container): - creteEmptyContainers() +def test_addContainerExtruderStack(container_registry, definition_container, definition_changes_container): container_registry.addContainer(definition_container) + container_registry.addContainer(definition_changes_container) - container_stack = UM.Settings.ContainerStack.ContainerStack(stack_id = "Test Container Stack") #A container we're going to convert. + container_stack = UM.Settings.ContainerStack.ContainerStack(stack_id = "Test Extruder Stack") #A container we're going to convert. container_stack.setMetaDataEntry("type", "extruder_train") #This is now an extruder train. container_stack.insertContainer(0, definition_container) #Add a definition to it so it doesn't complain. + container_stack.insertContainer(1, definition_changes_container) mock_super_add_container = unittest.mock.MagicMock() #Takes the role of the Uranium-ContainerRegistry where the resulting containers get registered. with unittest.mock.patch("UM.Settings.ContainerRegistry.ContainerRegistry.addContainer", mock_super_add_container): container_registry.addContainer(container_stack) - assert len(mock_super_add_container.call_args_list) == 2 #Called only once. - assert len(mock_super_add_container.call_args_list[1][0]) == 1 #Called with one parameter. - assert type(mock_super_add_container.call_args_list[1][0][0]) == ExtruderStack + assert len(mock_super_add_container.call_args_list) == 1 #Called only once. + assert len(mock_super_add_container.call_args_list[0][0]) == 1 #Called with one parameter. + assert type(mock_super_add_container.call_args_list[0][0][0]) == ExtruderStack ## Tests whether addContainer properly converts to GlobalStack. -def test_addContainerGlobalStack(container_registry, definition_container): +def test_addContainerGlobalStack(container_registry, definition_container, definition_changes_container): container_registry.addContainer(definition_container) + container_registry.addContainer(definition_changes_container) - container_stack = UM.Settings.ContainerStack.ContainerStack(stack_id = "Test Container Stack") #A container we're going to convert. + container_stack = UM.Settings.ContainerStack.ContainerStack(stack_id = "Test Global Stack") #A container we're going to convert. container_stack.setMetaDataEntry("type", "machine") #This is now a global stack. container_stack.insertContainer(0, definition_container) #Must have a definition. + container_stack.insertContainer(1, definition_changes_container) #Must have a definition changes. mock_super_add_container = unittest.mock.MagicMock() #Takes the role of the Uranium-ContainerRegistry where the resulting containers get registered. with unittest.mock.patch("UM.Settings.ContainerRegistry.ContainerRegistry.addContainer", mock_super_add_container): container_registry.addContainer(container_stack) - assert len(mock_super_add_container.call_args_list) == 2 #Called only once. - assert len(mock_super_add_container.call_args_list[1][0]) == 1 #Called with one parameter. - assert type(mock_super_add_container.call_args_list[1][0][0]) == GlobalStack + assert len(mock_super_add_container.call_args_list) == 1 #Called only once. + assert len(mock_super_add_container.call_args_list[0][0]) == 1 #Called with one parameter. + assert type(mock_super_add_container.call_args_list[0][0][0]) == GlobalStack def test_addContainerGoodSettingVersion(container_registry, definition_container): from cura.CuraApplication import CuraApplication definition_container.getMetaData()["setting_version"] = CuraApplication.SettingVersion container_registry.addContainer(definition_container) - instance = UM.Settings.InstanceContainer.InstanceContainer(container_id = "Test Instance") + instance = UM.Settings.InstanceContainer.InstanceContainer(container_id = "Test Instance Right Version") instance.setMetaDataEntry("setting_version", CuraApplication.SettingVersion) instance.setDefinition(definition_container.getId()) @@ -116,7 +73,7 @@ def test_addContainerNoSettingVersion(container_registry, definition_container): definition_container.getMetaData()["setting_version"] = CuraApplication.SettingVersion container_registry.addContainer(definition_container) - instance = UM.Settings.InstanceContainer.InstanceContainer(container_id = "Test Instance") + instance = UM.Settings.InstanceContainer.InstanceContainer(container_id = "Test Instance No Version") #Don't add setting_version metadata. instance.setDefinition(definition_container.getId()) @@ -131,7 +88,7 @@ def test_addContainerBadSettingVersion(container_registry, definition_container) definition_container.getMetaData()["setting_version"] = CuraApplication.SettingVersion container_registry.addContainer(definition_container) - instance = UM.Settings.InstanceContainer.InstanceContainer(container_id = "Test Instance") + instance = UM.Settings.InstanceContainer.InstanceContainer(container_id = "Test Instance Wrong Version") instance.setMetaDataEntry("setting_version", 9001) #Wrong version! instance.setDefinition(definition_container.getId()) @@ -140,38 +97,3 @@ def test_addContainerBadSettingVersion(container_registry, definition_container) container_registry.addContainer(instance) mock_super_add_container.assert_not_called() #Should not get passed on to UM.Settings.ContainerRegistry.addContainer, because the setting_version doesn't match its definition! - -## Tests whether loading gives objects of the correct type. -# @pytest.mark.parametrize("filename, output_class", [ -# ("ExtruderLegacy.stack.cfg", ExtruderStack), -# ("MachineLegacy.stack.cfg", GlobalStack), -# ("Left.extruder.cfg", ExtruderStack), -# ("Global.global.cfg", GlobalStack), -# ("Global.stack.cfg", GlobalStack) -# ]) -# def test_loadTypes(filename, output_class, container_registry): -# #Mock some dependencies. -# Resources.getAllResourcesOfType = unittest.mock.MagicMock(return_value = [os.path.join(os.path.dirname(os.path.abspath(__file__)), "stacks", filename)]) #Return just this tested file. -# -# def findContainers(container_type = 0, id = None): -# if id == "some_instance": -# return [UM.Settings.ContainerRegistry._EmptyInstanceContainer(id)] -# elif id == "some_definition": -# return [DefinitionContainer(container_id = id)] -# else: -# return [] -# -# container_registry.findContainers = findContainers -# -# with unittest.mock.patch("cura.Settings.GlobalStack.GlobalStack.findContainer"): -# with unittest.mock.patch("os.remove"): -# container_registry.load() -# -# #Check whether the resulting type was correct. -# stack_id = filename.split(".")[0] -# for container_id, container in container_registry._containers.items(): #Stupid ContainerRegistry class doesn't expose any way of getting at this except by prodding the privates. -# if container_id == stack_id: #This is the one we're testing. -# assert type(container) == output_class -# break -# else: -# assert False #Container stack with specified ID was not loaded. \ No newline at end of file diff --git a/tests/Settings/TestExtruderStack.py b/tests/Settings/TestExtruderStack.py index 7c463fb9be..df2e1075d1 100644 --- a/tests/Settings/TestExtruderStack.py +++ b/tests/Settings/TestExtruderStack.py @@ -1,43 +1,17 @@ -# Copyright (c) 2017 Ultimaker B.V. +# Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. import pytest #This module contains automated tests. import unittest.mock #For the mocking and monkeypatching functionality. -import copy -import cura.CuraApplication +import cura.Settings.CuraContainerStack #To get the list of container types. import UM.Settings.ContainerRegistry #To create empty instance containers. import UM.Settings.ContainerStack #To set the container registry the container stacks use. from UM.Settings.DefinitionContainer import DefinitionContainer #To check against the class of DefinitionContainer. from UM.Settings.InstanceContainer import InstanceContainer #To check against the class of InstanceContainer. -import cura.Settings.ExtruderStack #The module we're testing. from cura.Settings.Exceptions import InvalidContainerError, InvalidOperationError #To check whether the correct exceptions are raised. - from cura.Settings.ExtruderManager import ExtruderManager -from UM.Settings.ContainerRegistry import ContainerRegistry -from cura.Settings.GlobalStack import GlobalStack - -## Fake container registry that always provides all containers you ask of. -@pytest.yield_fixture() -def container_registry(): - registry = unittest.mock.MagicMock() - registry.return_value = unittest.mock.NonCallableMagicMock() - registry.findInstanceContainers = lambda *args, registry = registry, **kwargs: [registry.return_value] - registry.findDefinitionContainers = lambda *args, registry = registry, **kwargs: [registry.return_value] - - UM.Settings.ContainerRegistry.ContainerRegistry._ContainerRegistry__instance = registry - UM.Settings.ContainerStack._containerRegistry = registry - - yield registry - - UM.Settings.ContainerRegistry.ContainerRegistry._ContainerRegistry__instance = None - UM.Settings.ContainerStack._containerRegistry = None - -## An empty extruder stack to test with. -@pytest.fixture() -def extruder_stack() -> cura.Settings.ExtruderStack.ExtruderStack: - creteEmptyContainers() - return cura.Settings.ExtruderStack.ExtruderStack("TestStack") +from cura.Settings.cura_empty_instance_containers import empty_container ## Gets an instance container with a specified container type. # @@ -48,31 +22,6 @@ def getInstanceContainer(container_type) -> InstanceContainer: container.setMetaDataEntry("type", container_type) return container -def creteEmptyContainers(): - empty_container = ContainerRegistry.getInstance().getEmptyInstanceContainer() - empty_variant_container = copy.deepcopy(empty_container) - empty_variant_container.setMetaDataEntry("id", "empty_variant") - empty_variant_container.setMetaDataEntry("type", "variant") - ContainerRegistry.getInstance().addContainer(empty_variant_container) - - empty_material_container = copy.deepcopy(empty_container) - empty_material_container.setMetaDataEntry("id", "empty_material") - empty_material_container.setMetaDataEntry("type", "material") - ContainerRegistry.getInstance().addContainer(empty_material_container) - - empty_quality_container = copy.deepcopy(empty_container) - empty_quality_container.setMetaDataEntry("id", "empty_quality") - empty_quality_container.setName("Not Supported") - empty_quality_container.setMetaDataEntry("quality_type", "not_supported") - empty_quality_container.setMetaDataEntry("type", "quality") - empty_quality_container.setMetaDataEntry("supported", False) - ContainerRegistry.getInstance().addContainer(empty_quality_container) - - empty_quality_changes_container = copy.deepcopy(empty_container) - empty_quality_changes_container.setMetaDataEntry("id", "empty_quality_changes") - empty_quality_changes_container.setMetaDataEntry("type", "quality_changes") - ContainerRegistry.getInstance().addContainer(empty_quality_changes_container) - class DefinitionContainerSubClass(DefinitionContainer): def __init__(self): super().__init__(container_id = "SubDefinitionContainer") @@ -179,12 +128,30 @@ def test_constrainVariantInvalid(container, extruder_stack): def test_constrainVariantValid(container, extruder_stack): extruder_stack.variant = container #Should not give an error. +#Tests setting definition changes profiles to invalid containers. +@pytest.mark.parametrize("container", [ + getInstanceContainer(container_type = "wrong container type"), + getInstanceContainer(container_type = "material"), #Existing, but still wrong type. + DefinitionContainer(container_id = "wrong class") +]) +def test_constrainDefinitionChangesInvalid(container, global_stack): + with pytest.raises(InvalidContainerError): #Invalid container, should raise an error. + global_stack.definitionChanges = container + +#Test setting definition changes profiles. +@pytest.mark.parametrize("container", [ + getInstanceContainer(container_type = "definition_changes"), + InstanceContainerSubClass(container_type = "definition_changes") +]) +def test_constrainDefinitionChangesValid(container, global_stack): + global_stack.definitionChanges = container #Should not give an error. + #Tests setting definitions to invalid containers. @pytest.mark.parametrize("container", [ getInstanceContainer(container_type = "wrong class"), getInstanceContainer(container_type = "material"), #Existing, but still wrong class. ]) -def test_constrainVariantInvalid(container, extruder_stack): +def test_constrainDefinitionInvalid(container, extruder_stack): with pytest.raises(InvalidContainerError): #Invalid container, should raise an error. extruder_stack.definition = container @@ -196,23 +163,22 @@ def test_constrainVariantInvalid(container, extruder_stack): def test_constrainDefinitionValid(container, extruder_stack): extruder_stack.definition = container #Should not give an error. -## Tests whether deserialising completes the missing containers with empty -# ones. -@pytest.mark.skip #The test currently fails because the definition container doesn't have a category, which is wrong but we don't have time to refactor that right now. -def test_deserializeCompletesEmptyContainers(extruder_stack: cura.Settings.ExtruderStack): - extruder_stack._containers = [DefinitionContainer(container_id = "definition")] #Set the internal state of this stack manually. +## Tests whether deserialising completes the missing containers with empty ones. +def test_deserializeCompletesEmptyContainers(extruder_stack): + extruder_stack._containers = [DefinitionContainer(container_id = "definition"), extruder_stack.definitionChanges] #Set the internal state of this stack manually. with unittest.mock.patch("UM.Settings.ContainerStack.ContainerStack.deserialize", unittest.mock.MagicMock()): #Prevent calling super().deserialize. extruder_stack.deserialize("") assert len(extruder_stack.getContainers()) == len(cura.Settings.CuraContainerStack._ContainerIndexes.IndexTypeMap) #Needs a slot for every type. for container_type_index in cura.Settings.CuraContainerStack._ContainerIndexes.IndexTypeMap: - if container_type_index == cura.Settings.CuraContainerStack._ContainerIndexes.Definition: #We're not checking the definition. + if container_type_index in \ + (cura.Settings.CuraContainerStack._ContainerIndexes.Definition, + cura.Settings.CuraContainerStack._ContainerIndexes.DefinitionChanges): # We're not checking the definition or definition_changes continue - assert extruder_stack.getContainer(container_type_index).getId() == "empty" #All others need to be empty. + assert extruder_stack.getContainer(container_type_index) == empty_container #All others need to be empty. -## Tests whether an instance container with the wrong type gets removed when -# deserialising. +## Tests whether an instance container with the wrong type gets removed when deserialising. def test_deserializeRemovesWrongInstanceContainer(extruder_stack): extruder_stack._containers[cura.Settings.CuraContainerStack._ContainerIndexes.Quality] = getInstanceContainer(container_type = "wrong type") extruder_stack._containers[cura.Settings.CuraContainerStack._ContainerIndexes.Definition] = DefinitionContainer(container_id = "some definition") @@ -222,8 +188,7 @@ def test_deserializeRemovesWrongInstanceContainer(extruder_stack): assert extruder_stack.quality == extruder_stack._empty_instance_container #Replaced with empty. -## Tests whether a container with the wrong class gets removed when -# deserialising. +## Tests whether a container with the wrong class gets removed when deserialising. def test_deserializeRemovesWrongContainerClass(extruder_stack): extruder_stack._containers[cura.Settings.CuraContainerStack._ContainerIndexes.Quality] = DefinitionContainer(container_id = "wrong class") extruder_stack._containers[cura.Settings.CuraContainerStack._ContainerIndexes.Definition] = DefinitionContainer(container_id = "some definition") @@ -233,8 +198,7 @@ def test_deserializeRemovesWrongContainerClass(extruder_stack): assert extruder_stack.quality == extruder_stack._empty_instance_container #Replaced with empty. -## Tests whether an instance container in the definition spot results in an -# error. +## Tests whether an instance container in the definition spot results in an error. def test_deserializeWrongDefinitionClass(extruder_stack): extruder_stack._containers[cura.Settings.CuraContainerStack._ContainerIndexes.Definition] = getInstanceContainer(container_type = "definition") #Correct type but wrong class. @@ -242,8 +206,7 @@ def test_deserializeWrongDefinitionClass(extruder_stack): with pytest.raises(UM.Settings.ContainerStack.InvalidContainerStackError): #Must raise an error that there is no definition container. extruder_stack.deserialize("") -## Tests whether an instance container with the wrong type is moved into the -# correct slot by deserialising. +## Tests whether an instance container with the wrong type is moved into the correct slot by deserialising. def test_deserializeMoveInstanceContainer(extruder_stack): extruder_stack._containers[cura.Settings.CuraContainerStack._ContainerIndexes.Quality] = getInstanceContainer(container_type = "material") #Not in the correct spot. extruder_stack._containers[cura.Settings.CuraContainerStack._ContainerIndexes.Definition] = DefinitionContainer(container_id = "some definition") @@ -251,26 +214,21 @@ def test_deserializeMoveInstanceContainer(extruder_stack): with unittest.mock.patch("UM.Settings.ContainerStack.ContainerStack.deserialize", unittest.mock.MagicMock()): #Prevent calling super().deserialize. extruder_stack.deserialize("") - assert extruder_stack.quality.getId() == "empty" - assert extruder_stack.material.getId() != "empty" -from UM.Settings.Validator import Validator -## Tests whether a definition container in the wrong spot is moved into the -# correct spot by deserialising. -@pytest.mark.skip #The test currently fails because the definition container doesn't have a category, which is wrong but we don't have time to refactor that right now. + assert extruder_stack.quality == empty_container + assert extruder_stack.material != empty_container + +## Tests whether a definition container in the wrong spot is moved into the correct spot by deserialising. def test_deserializeMoveDefinitionContainer(extruder_stack): extruder_stack._containers[cura.Settings.CuraContainerStack._ContainerIndexes.Material] = DefinitionContainer(container_id = "some definition") #Not in the correct spot. with unittest.mock.patch("UM.Settings.ContainerStack.ContainerStack.deserialize", unittest.mock.MagicMock()): #Prevent calling super().deserialize. extruder_stack.deserialize("") - assert extruder_stack.material.getId() == "empty" - assert extruder_stack.definition.getId() != "empty" + assert extruder_stack.material == empty_container + assert extruder_stack.definition != empty_container - UM.Settings.ContainerStack._containerRegistry = None - -## Tests whether getProperty properly applies the stack-like behaviour on its -# containers. -def test_getPropertyFallThrough(extruder_stack): +## Tests whether getProperty properly applies the stack-like behaviour on its containers. +def test_getPropertyFallThrough(global_stack, extruder_stack): # ExtruderStack.setNextStack calls registerExtruder for backward compatibility, but we do not need a complete extruder manager ExtruderManager._ExtruderManager__instance = unittest.mock.MagicMock() @@ -300,8 +258,7 @@ def test_getPropertyFallThrough(extruder_stack): with unittest.mock.patch("cura.Settings.CuraContainerStack.DefinitionContainer", unittest.mock.MagicMock): #To guard against the type checking. extruder_stack.definition = mock_layer_heights[container_indices.Definition] #There's a layer height in here! - stack = GlobalStack("PyTest GlobalStack") - extruder_stack.setNextStack(stack) + extruder_stack.setNextStack(global_stack) assert extruder_stack.getProperty("layer_height", "value") == container_indices.Definition extruder_stack.variant = mock_layer_heights[container_indices.Variant] @@ -340,4 +297,4 @@ def test_setPropertyUser(key, property, value, extruder_stack): extruder_stack.setProperty(key, property, value) #The actual test. - extruder_stack.userChanges.setProperty.assert_called_once_with(key, property, value) #Make sure that the user container gets a setProperty call. \ No newline at end of file + extruder_stack.userChanges.setProperty.assert_called_once_with(key, property, value, None, False) #Make sure that the user container gets a setProperty call. \ No newline at end of file diff --git a/tests/Settings/TestGlobalStack.py b/tests/Settings/TestGlobalStack.py index 3e74e3e575..f8052aa4bb 100755 --- a/tests/Settings/TestGlobalStack.py +++ b/tests/Settings/TestGlobalStack.py @@ -1,43 +1,19 @@ -# Copyright (c) 2017 Ultimaker B.V. +# Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. import pytest #This module contains unit tests. import unittest.mock #To monkeypatch some mocks in place of dependencies. -import copy -import cura.CuraApplication -import cura.Settings.GlobalStack #The module we're testing. import cura.Settings.CuraContainerStack #To get the list of container types. -from cura.Settings.Exceptions import TooManyExtrudersError, InvalidContainerError, InvalidOperationError #To test raising these errors. +from cura.Settings.Exceptions import InvalidContainerError, InvalidOperationError #To test raising these errors. from UM.Settings.DefinitionContainer import DefinitionContainer #To test against the class DefinitionContainer. from UM.Settings.InstanceContainer import InstanceContainer #To test against the class InstanceContainer. from UM.Settings.SettingInstance import InstanceState import UM.Settings.ContainerRegistry import UM.Settings.ContainerStack import UM.Settings.SettingDefinition #To add settings to the definition. -from UM.Settings.ContainerRegistry import ContainerRegistry -## Fake container registry that always provides all containers you ask of. -@pytest.yield_fixture() -def container_registry(): - registry = unittest.mock.MagicMock() - registry.return_value = unittest.mock.NonCallableMagicMock() - registry.findInstanceContainers = lambda *args, registry = registry, **kwargs: [registry.return_value] - registry.findDefinitionContainers = lambda *args, registry = registry, **kwargs: [registry.return_value] - - UM.Settings.ContainerRegistry.ContainerRegistry._ContainerRegistry__instance = registry - UM.Settings.ContainerStack._containerRegistry = registry - - yield registry - - UM.Settings.ContainerRegistry.ContainerRegistry._ContainerRegistry__instance = None - UM.Settings.ContainerStack._containerRegistry = None - -#An empty global stack to test with. -@pytest.fixture() -def global_stack() -> cura.Settings.GlobalStack.GlobalStack: - creteEmptyContainers() - return cura.Settings.GlobalStack.GlobalStack("TestStack") +from cura.Settings.cura_empty_instance_containers import empty_container ## Gets an instance container with a specified container type. # @@ -48,31 +24,6 @@ def getInstanceContainer(container_type) -> InstanceContainer: container.setMetaDataEntry("type", container_type) return container -def creteEmptyContainers(): - empty_container = ContainerRegistry.getInstance().getEmptyInstanceContainer() - empty_variant_container = copy.deepcopy(empty_container) - empty_variant_container.setMetaDataEntry("id", "empty_variant") - empty_variant_container.setMetaDataEntry("type", "variant") - ContainerRegistry.getInstance().addContainer(empty_variant_container) - - empty_material_container = copy.deepcopy(empty_container) - empty_material_container.setMetaDataEntry("id", "empty_material") - empty_material_container.setMetaDataEntry("type", "material") - ContainerRegistry.getInstance().addContainer(empty_material_container) - - empty_quality_container = copy.deepcopy(empty_container) - empty_quality_container.setMetaDataEntry("id", "empty_quality") - empty_quality_container.setName("Not Supported") - empty_quality_container.setMetaDataEntry("quality_type", "not_supported") - empty_quality_container.setMetaDataEntry("type", "quality") - empty_quality_container.setMetaDataEntry("supported", False) - ContainerRegistry.getInstance().addContainer(empty_quality_container) - - empty_quality_changes_container = copy.deepcopy(empty_container) - empty_quality_changes_container.setMetaDataEntry("id", "empty_quality_changes") - empty_quality_changes_container.setMetaDataEntry("type", "quality_changes") - ContainerRegistry.getInstance().addContainer(empty_quality_changes_container) - class DefinitionContainerSubClass(DefinitionContainer): def __init__(self): super().__init__(container_id = "SubDefinitionContainer") @@ -229,7 +180,7 @@ def test_constrainDefinitionChangesValid(container, global_stack): getInstanceContainer(container_type = "wrong class"), getInstanceContainer(container_type = "material"), #Existing, but still wrong class. ]) -def test_constrainVariantInvalid(container, global_stack): +def test_constrainDefinitionInvalid(container, global_stack): with pytest.raises(InvalidContainerError): #Invalid container, should raise an error. global_stack.definition = container @@ -241,23 +192,22 @@ def test_constrainVariantInvalid(container, global_stack): def test_constrainDefinitionValid(container, global_stack): global_stack.definition = container #Should not give an error. -## Tests whether deserialising completes the missing containers with empty -# ones. -@pytest.mark.skip #The test currently fails because the definition container doesn't have a category, which is wrong but we don't have time to refactor that right now. -def test_deserializeCompletesEmptyContainers(global_stack: cura.Settings.GlobalStack): - global_stack._containers = [DefinitionContainer(container_id = "definition")] #Set the internal state of this stack manually. +## Tests whether deserialising completes the missing containers with empty ones. The initial containers are just the +# definition and the definition_changes (that cannot be empty after CURA-5281) +def test_deserializeCompletesEmptyContainers(global_stack): + global_stack._containers = [DefinitionContainer(container_id = "definition"), global_stack.definitionChanges] #Set the internal state of this stack manually. with unittest.mock.patch("UM.Settings.ContainerStack.ContainerStack.deserialize", unittest.mock.MagicMock()): #Prevent calling super().deserialize. global_stack.deserialize("") assert len(global_stack.getContainers()) == len(cura.Settings.CuraContainerStack._ContainerIndexes.IndexTypeMap) #Needs a slot for every type. for container_type_index in cura.Settings.CuraContainerStack._ContainerIndexes.IndexTypeMap: - if container_type_index == cura.Settings.CuraContainerStack._ContainerIndexes.Definition: #We're not checking the definition. + if container_type_index in \ + (cura.Settings.CuraContainerStack._ContainerIndexes.Definition, cura.Settings.CuraContainerStack._ContainerIndexes.DefinitionChanges): #We're not checking the definition or definition_changes continue - assert global_stack.getContainer(container_type_index).getId() == "empty" #All others need to be empty. + assert global_stack.getContainer(container_type_index) == empty_container #All others need to be empty. -## Tests whether an instance container with the wrong type gets removed when -# deserialising. +## Tests whether an instance container with the wrong type gets removed when deserialising. def test_deserializeRemovesWrongInstanceContainer(global_stack): global_stack._containers[cura.Settings.CuraContainerStack._ContainerIndexes.Quality] = getInstanceContainer(container_type = "wrong type") global_stack._containers[cura.Settings.CuraContainerStack._ContainerIndexes.Definition] = DefinitionContainer(container_id = "some definition") @@ -267,8 +217,7 @@ def test_deserializeRemovesWrongInstanceContainer(global_stack): assert global_stack.quality == global_stack._empty_instance_container #Replaced with empty. -## Tests whether a container with the wrong class gets removed when -# deserialising. +## Tests whether a container with the wrong class gets removed when deserialising. def test_deserializeRemovesWrongContainerClass(global_stack): global_stack._containers[cura.Settings.CuraContainerStack._ContainerIndexes.Quality] = DefinitionContainer(container_id = "wrong class") global_stack._containers[cura.Settings.CuraContainerStack._ContainerIndexes.Definition] = DefinitionContainer(container_id = "some definition") @@ -278,8 +227,7 @@ def test_deserializeRemovesWrongContainerClass(global_stack): assert global_stack.quality == global_stack._empty_instance_container #Replaced with empty. -## Tests whether an instance container in the definition spot results in an -# error. +## Tests whether an instance container in the definition spot results in an error. def test_deserializeWrongDefinitionClass(global_stack): global_stack._containers[cura.Settings.CuraContainerStack._ContainerIndexes.Definition] = getInstanceContainer(container_type = "definition") #Correct type but wrong class. @@ -287,8 +235,7 @@ def test_deserializeWrongDefinitionClass(global_stack): with pytest.raises(UM.Settings.ContainerStack.InvalidContainerStackError): #Must raise an error that there is no definition container. global_stack.deserialize("") -## Tests whether an instance container with the wrong type is moved into the -# correct slot by deserialising. +## Tests whether an instance container with the wrong type is moved into the correct slot by deserialising. def test_deserializeMoveInstanceContainer(global_stack): global_stack._containers[cura.Settings.CuraContainerStack._ContainerIndexes.Quality] = getInstanceContainer(container_type = "material") #Not in the correct spot. global_stack._containers[cura.Settings.CuraContainerStack._ContainerIndexes.Definition] = DefinitionContainer(container_id = "some definition") @@ -296,25 +243,20 @@ def test_deserializeMoveInstanceContainer(global_stack): with unittest.mock.patch("UM.Settings.ContainerStack.ContainerStack.deserialize", unittest.mock.MagicMock()): #Prevent calling super().deserialize. global_stack.deserialize("") - assert global_stack.quality.getId() == "empty" - assert global_stack.material.getId() != "empty" + assert global_stack.quality == empty_container + assert global_stack.material != empty_container -## Tests whether a definition container in the wrong spot is moved into the -# correct spot by deserialising. -@pytest.mark.skip #The test currently fails because the definition container doesn't have a category, which is wrong but we don't have time to refactor that right now. +## Tests whether a definition container in the wrong spot is moved into the correct spot by deserialising. def test_deserializeMoveDefinitionContainer(global_stack): global_stack._containers[cura.Settings.CuraContainerStack._ContainerIndexes.Material] = DefinitionContainer(container_id = "some definition") #Not in the correct spot. with unittest.mock.patch("UM.Settings.ContainerStack.ContainerStack.deserialize", unittest.mock.MagicMock()): #Prevent calling super().deserialize. global_stack.deserialize("") - assert global_stack.material.getId() == "empty" - assert global_stack.definition.getId() != "empty" + assert global_stack.material == empty_container + assert global_stack.definition != empty_container - UM.Settings.ContainerStack._containerRegistry = None - -## Tests whether getProperty properly applies the stack-like behaviour on its -# containers. +## Tests whether getProperty properly applies the stack-like behaviour on its containers. def test_getPropertyFallThrough(global_stack): #A few instance container mocks to put in the stack. mock_layer_heights = {} #For each container type, a mock container that defines layer height to something unique. @@ -365,8 +307,7 @@ def test_getPropertyNoResolveInDefinition(global_stack): global_stack.definition = value assert global_stack.getProperty("material_bed_temperature", "value") == 10 #No resolve, so fall through to value. -## In definitions, when the value is asked and there is a resolve function, it -# must get the resolve first. +## In definitions, when the value is asked and there is a resolve function, it must get the resolve first. def test_getPropertyResolveInDefinition(global_stack): resolve_and_value = unittest.mock.MagicMock() #Sets the resolve and value for bed temperature. resolve_and_value.getProperty = lambda key, property, context = None: (7.5 if property == "resolve" else 5) if (key == "material_bed_temperature" and property in ("resolve", "value")) else None #7.5 resolve, 5 value. @@ -375,8 +316,7 @@ def test_getPropertyResolveInDefinition(global_stack): global_stack.definition = resolve_and_value assert global_stack.getProperty("material_bed_temperature", "value") == 7.5 #Resolve wins in the definition. -## In instance containers, when the value is asked and there is a resolve -# function, it must get the value first. +## In instance containers, when the value is asked and there is a resolve function, it must get the value first. def test_getPropertyResolveInInstance(global_stack): container_indices = cura.Settings.CuraContainerStack._ContainerIndexes instance_containers = {} @@ -402,8 +342,7 @@ def test_getPropertyResolveInInstance(global_stack): global_stack.userChanges = instance_containers[container_indices.UserChanges] assert global_stack.getProperty("material_bed_temperature", "value") == 5 -## Tests whether the value in instances gets evaluated before the resolve in -# definitions. +## Tests whether the value in instances gets evaluated before the resolve in definitions. def test_getPropertyInstancesBeforeResolve(global_stack): value = unittest.mock.MagicMock() #Sets just the value. value.getProperty = lambda key, property, context = None: (10 if property == "value" else (InstanceState.User if property != "limit_to_extruder" else "-1")) if key == "material_bed_temperature" else None @@ -417,8 +356,7 @@ def test_getPropertyInstancesBeforeResolve(global_stack): assert global_stack.getProperty("material_bed_temperature", "value") == 10 -## Tests whether the hasUserValue returns true for settings that are changed in -# the user-changes container. +## Tests whether the hasUserValue returns true for settings that are changed in the user-changes container. def test_hasUserValueUserChanges(global_stack): container = unittest.mock.MagicMock() container.getMetaDataEntry = unittest.mock.MagicMock(return_value = "user") @@ -429,8 +367,7 @@ def test_hasUserValueUserChanges(global_stack): assert not global_stack.hasUserValue("infill_sparse_density") assert not global_stack.hasUserValue("") -## Tests whether the hasUserValue returns true for settings that are changed in -# the quality-changes container. +## Tests whether the hasUserValue returns true for settings that are changed in the quality-changes container. def test_hasUserValueQualityChanges(global_stack): container = unittest.mock.MagicMock() container.getMetaDataEntry = unittest.mock.MagicMock(return_value = "quality_changes") @@ -441,8 +378,7 @@ def test_hasUserValueQualityChanges(global_stack): assert not global_stack.hasUserValue("infill_sparse_density") assert not global_stack.hasUserValue("") -## Tests whether a container in some other place on the stack is correctly not -# recognised as user value. +## Tests whether a container in some other place on the stack is correctly not recognised as user value. def test_hasNoUserValue(global_stack): container = unittest.mock.MagicMock() container.getMetaDataEntry = unittest.mock.MagicMock(return_value = "quality") @@ -481,4 +417,4 @@ def test_setPropertyUser(key, property, value, global_stack): global_stack.setProperty(key, property, value) #The actual test. - global_stack.userChanges.setProperty.assert_called_once_with(key, property, value) #Make sure that the user container gets a setProperty call. \ No newline at end of file + global_stack.userChanges.setProperty.assert_called_once_with(key, property, value, None, False) #Make sure that the user container gets a setProperty call. \ No newline at end of file diff --git a/tests/Settings/conftest.py b/tests/Settings/conftest.py new file mode 100644 index 0000000000..c2d8854f05 --- /dev/null +++ b/tests/Settings/conftest.py @@ -0,0 +1,54 @@ +# Copyright (c) 2018 Ultimaker B.V. +# Uranium is released under the terms of the LGPLv3 or higher. + +# The purpose of this class is to create fixtures or methods that can be shared among all settings tests. + +import pytest + +from UM.Settings.ContainerRegistry import ContainerRegistry +from UM.Settings.ContainerStack import setContainerRegistry +from UM.Settings.DefinitionContainer import DefinitionContainer #To provide definition containers in the registry fixtures. +from UM.Settings.InstanceContainer import InstanceContainer +from cura.Settings.CuraContainerRegistry import CuraContainerRegistry +from cura.Settings.ExtruderStack import ExtruderStack +from cura.Settings.GlobalStack import GlobalStack +import cura.Settings.CuraContainerStack + +# Returns the CuraContainerRegistry instance with some empty containers. +@pytest.fixture() +def container_registry(application) -> CuraContainerRegistry: + ContainerRegistry._ContainerRegistry__instance= None # Need to reset since we only allow one instance + registry = CuraContainerRegistry(application) + setContainerRegistry(registry) + return registry + +# Gives an arbitrary definition container. +@pytest.fixture() +def definition_container() -> DefinitionContainer: + return DefinitionContainer(container_id = "Test Definition") + +# Gives an arbitrary definition changes container. +@pytest.fixture() +def definition_changes_container() -> InstanceContainer: + definition_changes_container = InstanceContainer(container_id = "Test Definition Changes") + definition_changes_container.setMetaDataEntry("type", "definition_changes") + # Add current setting version to the instance container + from cura.CuraApplication import CuraApplication + definition_changes_container.getMetaData()["setting_version"] = CuraApplication.SettingVersion + return definition_changes_container + +# An empty global stack to test with. +# There is a restriction here that the definition changes cannot be an empty container. Added in CURA-5281 +@pytest.fixture() +def global_stack(definition_changes_container) -> GlobalStack: + global_stack = GlobalStack("TestGlobalStack") + global_stack._containers[cura.Settings.CuraContainerStack._ContainerIndexes.DefinitionChanges] = definition_changes_container + return global_stack + +# An empty extruder stack to test with. +# There is a restriction here that the definition changes cannot be an empty container. Added in CURA-5281 +@pytest.fixture() +def extruder_stack(definition_changes_container) -> ExtruderStack: + extruder_stack= ExtruderStack("TestExtruderStack") + extruder_stack._containers[cura.Settings.CuraContainerStack._ContainerIndexes.DefinitionChanges] = definition_changes_container + return extruder_stack \ No newline at end of file diff --git a/tests/Settings/stacks/Complete.extruder.cfg b/tests/Settings/stacks/Complete.extruder.cfg deleted file mode 100644 index 789c0978f3..0000000000 --- a/tests/Settings/stacks/Complete.extruder.cfg +++ /dev/null @@ -1,12 +0,0 @@ -[general] -version = 3 -name = Complete -id = Complete - -[containers] -0 = some_user_changes -1 = some_quality_changes -2 = some_quality -3 = some_material -4 = some_variant -5 = some_definition diff --git a/tests/Settings/stacks/Complete.global.cfg b/tests/Settings/stacks/Complete.global.cfg deleted file mode 100644 index f7f613991a..0000000000 --- a/tests/Settings/stacks/Complete.global.cfg +++ /dev/null @@ -1,13 +0,0 @@ -[general] -version = 3 -name = Complete -id = Complete - -[containers] -0 = some_user_changes -1 = some_quality_changes -2 = some_quality -3 = some_material -4 = some_variant -5 = some_definition_changes -6 = some_definition diff --git a/tests/Settings/stacks/ExtruderLegacy.stack.cfg b/tests/Settings/stacks/ExtruderLegacy.stack.cfg deleted file mode 100644 index 4a6c419e40..0000000000 --- a/tests/Settings/stacks/ExtruderLegacy.stack.cfg +++ /dev/null @@ -1,11 +0,0 @@ -[general] -version = 3 -name = Legacy Extruder Stack -id = ExtruderLegacy - -[metadata] -type = extruder_train - -[containers] -3 = some_instance -5 = some_definition diff --git a/tests/Settings/stacks/Global.global.cfg b/tests/Settings/stacks/Global.global.cfg deleted file mode 100644 index 9034c1d0d0..0000000000 --- a/tests/Settings/stacks/Global.global.cfg +++ /dev/null @@ -1,8 +0,0 @@ -[general] -version = 3 -name = Global -id = Global - -[containers] -3 = some_instance -6 = some_definition diff --git a/tests/Settings/stacks/Global.stack.cfg b/tests/Settings/stacks/Global.stack.cfg deleted file mode 100644 index aa1693d878..0000000000 --- a/tests/Settings/stacks/Global.stack.cfg +++ /dev/null @@ -1,11 +0,0 @@ -[general] -version = 3 -name = Global -id = Global - -[metadata] -type = machine - -[containers] -3 = some_instance -6 = some_definition diff --git a/tests/Settings/stacks/Left.extruder.cfg b/tests/Settings/stacks/Left.extruder.cfg deleted file mode 100644 index 8ba45d6754..0000000000 --- a/tests/Settings/stacks/Left.extruder.cfg +++ /dev/null @@ -1,8 +0,0 @@ -[general] -version = 3 -name = Left -id = Left - -[containers] -3 = some_instance -5 = some_definition diff --git a/tests/Settings/stacks/MachineLegacy.stack.cfg b/tests/Settings/stacks/MachineLegacy.stack.cfg deleted file mode 100644 index 147d63c596..0000000000 --- a/tests/Settings/stacks/MachineLegacy.stack.cfg +++ /dev/null @@ -1,11 +0,0 @@ -[general] -version = 3 -name = Legacy Global Stack -id = MachineLegacy - -[metadata] -type = machine - -[containers] -3 = some_instance -6 = some_definition \ No newline at end of file diff --git a/tests/Settings/stacks/OnlyDefinition.extruder.cfg b/tests/Settings/stacks/OnlyDefinition.extruder.cfg deleted file mode 100644 index e58512b27f..0000000000 --- a/tests/Settings/stacks/OnlyDefinition.extruder.cfg +++ /dev/null @@ -1,7 +0,0 @@ -[general] -version = 3 -name = Only Definition -id = OnlyDefinition - -[containers] -5 = some_definition diff --git a/tests/Settings/stacks/OnlyDefinition.global.cfg b/tests/Settings/stacks/OnlyDefinition.global.cfg deleted file mode 100644 index 9534353ed5..0000000000 --- a/tests/Settings/stacks/OnlyDefinition.global.cfg +++ /dev/null @@ -1,7 +0,0 @@ -[general] -version = 3 -name = Only Definition -id = OnlyDefinition - -[containers] -6 = some_definition diff --git a/tests/Settings/stacks/OnlyDefinitionChanges.global.cfg b/tests/Settings/stacks/OnlyDefinitionChanges.global.cfg deleted file mode 100644 index 39e2105b7d..0000000000 --- a/tests/Settings/stacks/OnlyDefinitionChanges.global.cfg +++ /dev/null @@ -1,8 +0,0 @@ -[general] -version = 3 -name = Only Definition Changes -id = OnlyDefinitionChanges - -[containers] -5 = some_instance -6 = some_definition diff --git a/tests/Settings/stacks/OnlyMaterial.extruder.cfg b/tests/Settings/stacks/OnlyMaterial.extruder.cfg deleted file mode 100644 index 49a9d12389..0000000000 --- a/tests/Settings/stacks/OnlyMaterial.extruder.cfg +++ /dev/null @@ -1,8 +0,0 @@ -[general] -version = 3 -name = Only Material -id = OnlyMaterial - -[containers] -3 = some_instance -5 = some_definition diff --git a/tests/Settings/stacks/OnlyMaterial.global.cfg b/tests/Settings/stacks/OnlyMaterial.global.cfg deleted file mode 100644 index 715651a9b9..0000000000 --- a/tests/Settings/stacks/OnlyMaterial.global.cfg +++ /dev/null @@ -1,8 +0,0 @@ -[general] -version = 3 -name = Only Material -id = OnlyMaterial - -[containers] -3 = some_instance -6 = some_definition diff --git a/tests/Settings/stacks/OnlyQuality.extruder.cfg b/tests/Settings/stacks/OnlyQuality.extruder.cfg deleted file mode 100644 index aaf7fb30c5..0000000000 --- a/tests/Settings/stacks/OnlyQuality.extruder.cfg +++ /dev/null @@ -1,8 +0,0 @@ -[general] -version = 3 -name = Only Quality -id = OnlyQuality - -[containers] -2 = some_instance -5 = some_definition diff --git a/tests/Settings/stacks/OnlyQuality.global.cfg b/tests/Settings/stacks/OnlyQuality.global.cfg deleted file mode 100644 index f07a35666e..0000000000 --- a/tests/Settings/stacks/OnlyQuality.global.cfg +++ /dev/null @@ -1,8 +0,0 @@ -[general] -version = 3 -name = Only Quality -id = OnlyQuality - -[containers] -2 = some_instance -6 = some_definition diff --git a/tests/Settings/stacks/OnlyQualityChanges.extruder.cfg b/tests/Settings/stacks/OnlyQualityChanges.extruder.cfg deleted file mode 100644 index 653bad840c..0000000000 --- a/tests/Settings/stacks/OnlyQualityChanges.extruder.cfg +++ /dev/null @@ -1,8 +0,0 @@ -[general] -version = 3 -name = Only Quality Changes -id = OnlyQualityChanges - -[containers] -1 = some_instance -5 = some_definition diff --git a/tests/Settings/stacks/OnlyQualityChanges.global.cfg b/tests/Settings/stacks/OnlyQualityChanges.global.cfg deleted file mode 100644 index 17d279377a..0000000000 --- a/tests/Settings/stacks/OnlyQualityChanges.global.cfg +++ /dev/null @@ -1,8 +0,0 @@ -[general] -version = 3 -name = Only Quality Changes -id = OnlyQualityChanges - -[containers] -1 = some_instance -6 = some_definition diff --git a/tests/Settings/stacks/OnlyUser.extruder.cfg b/tests/Settings/stacks/OnlyUser.extruder.cfg deleted file mode 100644 index abf812a859..0000000000 --- a/tests/Settings/stacks/OnlyUser.extruder.cfg +++ /dev/null @@ -1,8 +0,0 @@ -[general] -version = 3 -name = Only User -id = OnlyUser - -[containers] -0 = some_instance -5 = some_definition diff --git a/tests/Settings/stacks/OnlyUser.global.cfg b/tests/Settings/stacks/OnlyUser.global.cfg deleted file mode 100644 index 31371d2c51..0000000000 --- a/tests/Settings/stacks/OnlyUser.global.cfg +++ /dev/null @@ -1,8 +0,0 @@ -[general] -version = 3 -name = Only User -id = OnlyUser - -[containers] -0 = some_instance -6 = some_definition diff --git a/tests/Settings/stacks/OnlyVariant.extruder.cfg b/tests/Settings/stacks/OnlyVariant.extruder.cfg deleted file mode 100644 index a31997a6fd..0000000000 --- a/tests/Settings/stacks/OnlyVariant.extruder.cfg +++ /dev/null @@ -1,8 +0,0 @@ -[general] -version = 3 -name = Only Variant -id = OnlyVariant - -[containers] -4 = some_instance -5 = some_definition diff --git a/tests/Settings/stacks/OnlyVariant.global.cfg b/tests/Settings/stacks/OnlyVariant.global.cfg deleted file mode 100644 index 158d533ac8..0000000000 --- a/tests/Settings/stacks/OnlyVariant.global.cfg +++ /dev/null @@ -1,8 +0,0 @@ -[general] -version = 3 -name = Only Variant -id = OnlyVariant - -[containers] -4 = some_instance -6 = some_definition diff --git a/tests/TestArrange.py b/tests/TestArrange.py index f383fc0cf3..7de3ec1d8d 100755 --- a/tests/TestArrange.py +++ b/tests/TestArrange.py @@ -1,9 +1,11 @@ +# Copyright (c) 2018 Ultimaker B.V. +# Cura is released under the terms of the LGPLv3 or higher. + import numpy from cura.Arranging.Arrange import Arrange from cura.Arranging.ShapeArray import ShapeArray - ## Triangle of area 12 def gimmeTriangle(): return numpy.array([[-3, 1], [3, 1], [0, -3]], dtype=numpy.int32) @@ -102,7 +104,7 @@ def test_centerFirst_rectangular(): ## Test centerFirst -def test_centerFirst_rectangular(): +def test_centerFirst_rectangular2(): ar = Arrange(10, 20, 5, 10, scale = 1) ar.centerFirst() print(ar._priority) diff --git a/tests/TestMachineAction.py b/tests/TestMachineAction.py index 0118874a0b..7121fcc218 100755 --- a/tests/TestMachineAction.py +++ b/tests/TestMachineAction.py @@ -1,11 +1,10 @@ -#Todo: Write tests +# Copyright (c) 2018 Ultimaker B.V. +# Cura is released under the terms of the LGPLv3 or higher. import pytest -# QtApplication needs to be imported first to prevent import errors. -from UM.Qt.QtApplication import QtApplication from cura.MachineAction import MachineAction -from cura.MachineActionManager import MachineActionManager, NotUniqueMachineActionError, UnknownMachineActionError +from cura.MachineActionManager import NotUniqueMachineActionError, UnknownMachineActionError class Machine: def __init__(self, key = ""): @@ -14,66 +13,64 @@ class Machine: def getKey(self): return self._key -def test_addMachineAction(): - - machine_manager = MachineActionManager() +def test_addMachineAction(machine_action_manager): test_action = MachineAction(key = "test_action") test_action_2 = MachineAction(key = "test_action_2") test_machine = Machine("test_machine") - machine_manager.addMachineAction(test_action) - machine_manager.addMachineAction(test_action_2) + machine_action_manager.addMachineAction(test_action) + machine_action_manager.addMachineAction(test_action_2) - assert machine_manager.getMachineAction("test_action") == test_action - assert machine_manager.getMachineAction("key_that_doesnt_exist") is None + assert machine_action_manager.getMachineAction("test_action") == test_action + assert machine_action_manager.getMachineAction("key_that_doesnt_exist") is None # Adding the same machine action is not allowed. with pytest.raises(NotUniqueMachineActionError): - machine_manager.addMachineAction(test_action) + machine_action_manager.addMachineAction(test_action) # Check that the machine has no supported actions yet. - assert machine_manager.getSupportedActions(test_machine) == list() + assert machine_action_manager.getSupportedActions(test_machine) == list() # Check if adding a supported action works. - machine_manager.addSupportedAction(test_machine, "test_action") - assert machine_manager.getSupportedActions(test_machine) == [test_action, ] + machine_action_manager.addSupportedAction(test_machine, "test_action") + assert machine_action_manager.getSupportedActions(test_machine) == [test_action, ] # Check that adding a unknown action doesn't change anything. - machine_manager.addSupportedAction(test_machine, "key_that_doesnt_exist") - assert machine_manager.getSupportedActions(test_machine) == [test_action, ] + machine_action_manager.addSupportedAction(test_machine, "key_that_doesnt_exist") + assert machine_action_manager.getSupportedActions(test_machine) == [test_action, ] # Check if adding multiple supported actions works. - machine_manager.addSupportedAction(test_machine, "test_action_2") - assert machine_manager.getSupportedActions(test_machine) == [test_action, test_action_2] + machine_action_manager.addSupportedAction(test_machine, "test_action_2") + assert machine_action_manager.getSupportedActions(test_machine) == [test_action, test_action_2] # Check that the machine has no required actions yet. - assert machine_manager.getRequiredActions(test_machine) == set() + assert machine_action_manager.getRequiredActions(test_machine) == set() ## Ensure that only known actions can be added. with pytest.raises(UnknownMachineActionError): - machine_manager.addRequiredAction(test_machine, "key_that_doesnt_exist") + machine_action_manager.addRequiredAction(test_machine, "key_that_doesnt_exist") ## Check if adding single required action works - machine_manager.addRequiredAction(test_machine, "test_action") - assert machine_manager.getRequiredActions(test_machine) == [test_action, ] + machine_action_manager.addRequiredAction(test_machine, "test_action") + assert machine_action_manager.getRequiredActions(test_machine) == [test_action, ] # Check if adding multiple required actions works. - machine_manager.addRequiredAction(test_machine, "test_action_2") - assert machine_manager.getRequiredActions(test_machine) == [test_action, test_action_2] + machine_action_manager.addRequiredAction(test_machine, "test_action_2") + assert machine_action_manager.getRequiredActions(test_machine) == [test_action, test_action_2] # Ensure that firstStart actions are empty by default. - assert machine_manager.getFirstStartActions(test_machine) == [] + assert machine_action_manager.getFirstStartActions(test_machine) == [] # Check if adding multiple (the same) actions to first start actions work. - machine_manager.addFirstStartAction(test_machine, "test_action") - machine_manager.addFirstStartAction(test_machine, "test_action") - assert machine_manager.getFirstStartActions(test_machine) == [test_action, test_action] + machine_action_manager.addFirstStartAction(test_machine, "test_action") + machine_action_manager.addFirstStartAction(test_machine, "test_action") + assert machine_action_manager.getFirstStartActions(test_machine) == [test_action, test_action] # Check if inserting an action works - machine_manager.addFirstStartAction(test_machine, "test_action_2", index = 1) - assert machine_manager.getFirstStartActions(test_machine) == [test_action, test_action_2, test_action] + machine_action_manager.addFirstStartAction(test_machine, "test_action_2", index = 1) + assert machine_action_manager.getFirstStartActions(test_machine) == [test_action, test_action_2, test_action] # Check that adding a unknown action doesn't change anything. - machine_manager.addFirstStartAction(test_machine, "key_that_doesnt_exist", index = 1) - assert machine_manager.getFirstStartActions(test_machine) == [test_action, test_action_2, test_action] + machine_action_manager.addFirstStartAction(test_machine, "key_that_doesnt_exist", index = 1) + assert machine_action_manager.getFirstStartActions(test_machine) == [test_action, test_action_2, test_action] diff --git a/tests/TestProfileRequirements.py b/tests/TestProfileRequirements.py index f75ca9da8d..97641fe753 100644 --- a/tests/TestProfileRequirements.py +++ b/tests/TestProfileRequirements.py @@ -1,3 +1,6 @@ +# Copyright (c) 2018 Ultimaker B.V. +# Cura is released under the terms of the LGPLv3 or higher. + import configparser #To read the profiles. import os #To join paths. import pytest @@ -11,6 +14,7 @@ import pytest # often that we updated the variants for the UM3 but forgot about the UM3E. @pytest.mark.parametrize("um3_file, um3e_file", [ #List the corresponding files below. + ("ultimaker3_aa0.25.inst.cfg", "ultimaker3_extended_aa0.25.inst.cfg"), ("ultimaker3_aa0.8.inst.cfg", "ultimaker3_extended_aa0.8.inst.cfg"), ("ultimaker3_aa04.inst.cfg", "ultimaker3_extended_aa04.inst.cfg"), ("ultimaker3_bb0.8.inst.cfg", "ultimaker3_extended_bb0.8.inst.cfg"), diff --git a/tests/conftest.py b/tests/conftest.py new file mode 100644 index 0000000000..f2c709d8d8 --- /dev/null +++ b/tests/conftest.py @@ -0,0 +1,23 @@ +# Copyright (c) 2018 Ultimaker B.V. +# Cura is released under the terms of the LGPLv3 or higher. + +# The purpose of this class is to create fixtures or methods that can be shared among all tests. + +import pytest +from UM.Qt.QtApplication import QtApplication #QtApplication import is required, even though it isn't used. +from cura.CuraApplication import CuraApplication +from cura.MachineActionManager import MachineActionManager + +# Create a CuraApplication object that will be shared among all tests. It needs to be initialized. +# Since we need to use it more that once, we create the application the first time and use its instance afterwards. +@pytest.fixture() +def application() -> CuraApplication: + application = CuraApplication.getInstance() + if application is None: + application = CuraApplication() + return application + +# Returns a MachineActionManager instance. +@pytest.fixture() +def machine_action_manager(application) -> MachineActionManager: + return MachineActionManager(application)