Просмотр исходного кода

Fix global stack tests.

Contributes to CURA-5628.
Diego Prado Gesto 6 лет назад
Родитель
Сommit
1364370ede
3 измененных файлов с 50 добавлено и 111 удалено
  1. 26 91
      tests/Settings/TestGlobalStack.py
  2. 23 4
      tests/Settings/conftest.py
  3. 1 16
      tests/conftest.py

+ 26 - 91
tests/Settings/TestGlobalStack.py

@@ -3,41 +3,16 @@
 
 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
+from UM.Settings.EmptyInstanceContainer import empty_container
 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")
 
 ##  Gets an instance container with a specified container type.
 #
@@ -48,31 +23,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")
@@ -241,23 +191,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 +216,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 +226,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 +234,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 +242,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"
-
-    UM.Settings.ContainerStack._containerRegistry = None
+    assert global_stack.material == empty_container
+    assert global_stack.definition != empty_container
 
-##  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 +306,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 +315,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 +341,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 +355,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 +366,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 +377,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 +416,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.
+    global_stack.userChanges.setProperty.assert_called_once_with(key, property, value, None, False) #Make sure that the user container gets a setProperty call.

+ 23 - 4
tests/Settings/conftest.py

@@ -4,16 +4,35 @@
 # The purpose of this class is to create fixtures or methods that can be shared among all settings tests.
 
 import pytest
-import copy
 
 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):
+def container_registry(application) -> CuraContainerRegistry:
     return application.getContainerRegistry()
 
 # Gives an arbitrary definition container.
 @pytest.fixture()
-def definition_container():
-    return DefinitionContainer(container_id = "Test Definition")
+def definition_container() -> DefinitionContainer:
+    return DefinitionContainer(container_id = "Test Definition")
+
+#An empty global stack to test with.
+@pytest.fixture()
+def global_stack() -> GlobalStack:
+    global_stack = GlobalStack("TestGlobalStack")
+    # There is a restriction here that the definition changes cannot be an empty container. Added in CURA-5281
+    definition_changes_container = InstanceContainer(container_id = "InstanceContainer")
+    definition_changes_container.setMetaDataEntry("type", "definition_changes")
+    global_stack._containers[cura.Settings.CuraContainerStack._ContainerIndexes.DefinitionChanges] = definition_changes_container
+    return global_stack
+
+##  An empty extruder stack to test with.
+@pytest.fixture()
+def extruder_stack() -> ExtruderStack:
+    return ExtruderStack("TestExtruderStack")

+ 1 - 16
tests/conftest.py

@@ -4,7 +4,7 @@
 # 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 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
 
@@ -15,24 +15,9 @@ def application() -> CuraApplication:
     application = CuraApplication.getInstance()
     if application is None:
         application = CuraApplication()
-        application.initialize()
     return application
 
 # Returns a MachineActionManager instance.
 @pytest.fixture()
 def machine_action_manager(application) -> MachineActionManager:
     return application.getMachineActionManager()
-
-# @pytest.fixture()
-# def plugin_registry(application):
-#     PluginRegistry._PluginRegistry__instance = None
-#     plugin_registry = PluginRegistry(application)
-#     plugin_registry._plugin_locations = [] # Clear pre-defined plugin locations
-#     return plugin_registry
-#
-# @pytest.fixture()
-# def upgrade_manager(application):
-#     VersionUpgradeManager._VersionUpgradeManager__instance = None
-#     upgrade_manager = VersionUpgradeManager(application)
-#     return upgrade_manager
-