Fix merge conflicts with master

This commit is contained in:
Lipu Fei 2019-03-21 14:59:53 +01:00
commit 4e5d08f320
153 changed files with 5127 additions and 3586 deletions

View file

@ -0,0 +1,76 @@
from unittest import TestCase
from unittest.mock import MagicMock
from PyQt5.QtCore import QUrl
from UM.MimeTypeDatabase import MimeTypeDatabase
from cura.Settings.ContainerManager import ContainerManager
import tempfile
import os
class TestContainerManager(TestCase):
def setUp(self):
self._application = MagicMock()
self._container_registry = MagicMock()
self._machine_manager = MagicMock()
self._mocked_mime = MagicMock()
self._mocked_mime.preferredSuffix = "omg"
self._mocked_mime.suffixes = ["omg"]
self._mocked_mime.comment = "UnitTest!"
self._mocked_container = MagicMock()
self._mocked_container_data = "SOME DATA :D"
self._mocked_container.serialize = MagicMock(return_value = self._mocked_container_data)
self._containers_meta_data = [{"id": "test", "test_data": "omg"}]
self._container_registry.findContainersMetadata = MagicMock(return_value = self._containers_meta_data)
self._container_registry.getMimeTypeForContainer = MagicMock(return_value = self._mocked_mime)
self._container_registry.findContainers = MagicMock(return_value = [self._mocked_container])
self._application.getContainerRegistry = MagicMock(return_value = self._container_registry)
self._application.getMachineManager = MagicMock(return_value = self._machine_manager)
# Destroy the previous instance of the container manager
if ContainerManager.getInstance() is not None:
ContainerManager._ContainerManager__instance = None
self._container_manager = ContainerManager(self._application)
MimeTypeDatabase.addMimeType(self._mocked_mime)
def tearDown(self):
MimeTypeDatabase.removeMimeType(self._mocked_mime)
def test_getContainerMetaDataEntry(self):
assert self._container_manager.getContainerMetaDataEntry("test", "test_data") == "omg"
assert self._container_manager.getContainerMetaDataEntry("test", "entry_that_is_not_defined") == ""
def test_clearUserContainer(self):
self._container_manager.clearUserContainers()
assert self._machine_manager.activeMachine.userChanges.clear.call_count == 1
def test_getContainerNameFilters(self):
# If nothing is added, we still expect to get the all files filter
assert self._container_manager.getContainerNameFilters("") == ['All Files (*)']
# Pretend that a new type was added.
self._container_registry.getContainerTypes = MagicMock(return_value=[("None", None)])
assert self._container_manager.getContainerNameFilters("") == ['UnitTest! (*.omg)', 'All Files (*)']
def test_exportContainerUnknownFileType(self):
# The filetype is not known, so this should cause an error!
assert self._container_manager.exportContainer("test", "zomg", "whatever")["status"] == "error"
def test_exportContainerInvalidPath(self):
assert self._container_manager.exportContainer("test", "zomg", "")["status"] == "error"
assert self._container_manager.exportContainer("test", "zomg", QUrl())["status"] == "error"
def test_exportContainerInvalidId(self):
assert self._container_manager.exportContainer("", "whatever", "whatever")["status"] == "error"
def test_exportContainer(self):
with tempfile.TemporaryDirectory() as tmpdirname:
result = self._container_manager.exportContainer("test", "whatever", os.path.join(tmpdirname, "whatever.omg"))
assert(os.path.exists(result["path"]))
with open(result["path"], "r", encoding="utf-8") as f:
assert f.read() == self._mocked_container_data

View file

@ -1,7 +1,8 @@
# Copyright (c) 2018 Ultimaker B.V.
# Copyright (c) 2019 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 #To parameterize tests.
import unittest.mock #To mock and monkeypatch stuff.
from UM.Settings.DefinitionContainer import DefinitionContainer
@ -119,3 +120,62 @@ 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!
test_loadMetaDataValidation_data = [
{
"id": "valid_container",
"is_valid": True,
"metadata": {
"id": "valid_container",
"setting_version": None, #The tests sets this to the current version so it's always correct.
"foo": "bar"
}
},
{
"id": "wrong_setting_version",
"is_valid": False,
"metadata": {
"id": "wrong_setting_version",
"setting_version": "5",
"foo": "bar"
}
},
{
"id": "missing_setting_version",
"is_valid": False,
"metadata": {
"id": "missing_setting_version",
"foo": "bar"
}
},
{
"id": "unparsable_setting_version",
"is_valid": False,
"metadata": {
"id": "unparsable_setting_version",
"setting_version": "Not an integer!",
"foo": "bar"
}
}
]
@pytest.mark.parametrize("parameters", test_loadMetaDataValidation_data)
def test_loadMetadataValidation(container_registry, definition_container, parameters):
from cura.CuraApplication import CuraApplication
definition_container.getMetaData()["setting_version"] = CuraApplication.SettingVersion
container_registry.addContainer(definition_container)
if "setting_version" in parameters["metadata"] and parameters["metadata"]["setting_version"] is None: #Signal that the setting_version must be set to the currently correct version.
parameters["metadata"]["setting_version"] = CuraApplication.SettingVersion
mock_provider = unittest.mock.MagicMock()
mock_provider.getAllIds = unittest.mock.MagicMock(return_value = [parameters["id"]])
mock_provider.loadMetadata = unittest.mock.MagicMock(return_value = parameters["metadata"])
container_registry._providers = [mock_provider]
container_registry.loadAllMetadata() #Run the test.
if parameters["is_valid"]:
assert parameters["id"] in container_registry.metadata
assert container_registry.metadata[parameters["id"]] == parameters["metadata"]
else:
assert parameters["id"] not in container_registry.metadata

View file

@ -82,7 +82,7 @@ def test_validateQualityProfiles(file_name):
except Exception as e:
# File can't be read, header sections missing, whatever the case, this shouldn't happen!
print("Go an Exception while reading he file [%s]: %s" % (file_name, e))
print("Got an Exception while reading he file [%s]: %s" % (file_name, e))
assert False
@ -110,5 +110,5 @@ def test_validateVariantProfiles(file_name):
assert False
except Exception as e:
# File can't be read, header sections missing, whatever the case, this shouldn't happen!
print("Go an Exception while reading he file [%s]: %s" % (file_name, e))
print("Got an Exception while reading he file [%s]: %s" % (file_name, e))
assert False

View file

@ -1,5 +1,5 @@
# Copyright (c) 2018 Ultimaker B.V.
# Uranium is released under the terms of the LGPLv3 or higher.
# Copyright (c) 2019 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 settings tests.
@ -49,6 +49,6 @@ def global_stack(definition_changes_container) -> GlobalStack:
# 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 = ExtruderStack("TestExtruderStack")
extruder_stack._containers[cura.Settings.CuraContainerStack._ContainerIndexes.DefinitionChanges] = definition_changes_container
return extruder_stack

View file

@ -1,4 +1,4 @@
# Copyright (c) 2018 Ultimaker B.V.
# Copyright (c) 2019 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher.
import numpy
@ -10,35 +10,29 @@ from cura.Arranging.ShapeArray import ShapeArray
def gimmeTriangle():
return numpy.array([[-3, 1], [3, 1], [0, -3]], dtype=numpy.int32)
## Boring square
def gimmeSquare():
return numpy.array([[-2, -2], [2, -2], [2, 2], [-2, 2]], dtype=numpy.int32)
## Triangle of area 12
def gimmeShapeArray(scale = 1.0):
vertices = gimmeTriangle()
shape_arr = ShapeArray.fromPolygon(vertices, scale = scale)
return shape_arr
## Boring square
def gimmeShapeArraySquare(scale = 1.0):
vertices = gimmeSquare()
shape_arr = ShapeArray.fromPolygon(vertices, scale = scale)
return shape_arr
## Smoke test for Arrange
def test_smoke_arrange():
ar = Arrange.create(fixed_nodes = [])
Arrange.create(fixed_nodes = [])
## Smoke test for ShapeArray
def test_smoke_ShapeArray():
shape_arr = gimmeShapeArray()
gimmeShapeArray()
## Test ShapeArray
def test_ShapeArray():
@ -47,12 +41,9 @@ def test_ShapeArray():
ar.centerFirst()
shape_arr = gimmeShapeArray(scale)
print(shape_arr.arr)
count = len(numpy.where(shape_arr.arr == 1)[0])
print(count)
assert count >= 10 # should approach 12
## Test ShapeArray with scaling
def test_ShapeArray_scaling():
scale = 2
@ -60,12 +51,9 @@ def test_ShapeArray_scaling():
ar.centerFirst()
shape_arr = gimmeShapeArray(scale)
print(shape_arr.arr)
count = len(numpy.where(shape_arr.arr == 1)[0])
print(count)
assert count >= 40 # should approach 2*2*12 = 48
## Test ShapeArray with scaling
def test_ShapeArray_scaling2():
scale = 0.5
@ -73,12 +61,9 @@ def test_ShapeArray_scaling2():
ar.centerFirst()
shape_arr = gimmeShapeArray(scale)
print(shape_arr.arr)
count = len(numpy.where(shape_arr.arr == 1)[0])
print(count)
assert count >= 1 # should approach 3, but it can be inaccurate due to pixel rounding
## Test centerFirst
def test_centerFirst():
ar = Arrange(300, 300, 150, 150, scale = 1)
@ -90,7 +75,6 @@ def test_centerFirst():
assert ar._priority[150][150] < ar._priority[150][130]
assert ar._priority[150][150] < ar._priority[130][130]
## Test centerFirst
def test_centerFirst_rectangular():
ar = Arrange(400, 300, 200, 150, scale = 1)
@ -102,12 +86,10 @@ def test_centerFirst_rectangular():
assert ar._priority[150][200] < ar._priority[130][200]
assert ar._priority[150][200] < ar._priority[130][180]
## Test centerFirst
def test_centerFirst_rectangular2():
ar = Arrange(10, 20, 5, 10, scale = 1)
ar.centerFirst()
print(ar._priority)
assert ar._priority[10][5] < ar._priority[10][7]
@ -120,7 +102,6 @@ def test_backFirst():
assert ar._priority[150][150] > ar._priority[130][150]
assert ar._priority[150][150] > ar._priority[130][130]
## See if the result of bestSpot has the correct form
def test_smoke_bestSpot():
ar = Arrange(30, 30, 15, 15, scale = 1)
@ -133,7 +114,6 @@ def test_smoke_bestSpot():
assert hasattr(best_spot, "penalty_points")
assert hasattr(best_spot, "priority")
## Real life test
def test_bestSpot():
ar = Arrange(16, 16, 8, 8, scale = 1)
@ -151,9 +131,6 @@ def test_bestSpot():
assert best_spot.x != 0 or best_spot.y != 0 # it can't be on the same location
ar.place(best_spot.x, best_spot.y, shape_arr)
print(ar._occupied) # For debugging
## Real life test rectangular build plate
def test_bestSpot_rectangular_build_plate():
ar = Arrange(16, 40, 8, 20, scale = 1)
@ -187,9 +164,6 @@ def test_bestSpot_rectangular_build_plate():
best_spot_x = ar.bestSpot(shape_arr)
ar.place(best_spot_x.x, best_spot_x.y, shape_arr)
print(ar._occupied) # For debugging
## Real life test
def test_bestSpot_scale():
scale = 0.5
@ -202,17 +176,12 @@ def test_bestSpot_scale():
assert best_spot.y == 0
ar.place(best_spot.x, best_spot.y, shape_arr)
print(ar._occupied)
# Place object a second time
best_spot = ar.bestSpot(shape_arr)
assert best_spot.x is not None # we found a location
assert best_spot.x != 0 or best_spot.y != 0 # it can't be on the same location
ar.place(best_spot.x, best_spot.y, shape_arr)
print(ar._occupied) # For debugging
## Real life test
def test_bestSpot_scale_rectangular():
scale = 0.5
@ -227,8 +196,6 @@ def test_bestSpot_scale_rectangular():
assert best_spot.y == 0
ar.place(best_spot.x, best_spot.y, shape_arr_square)
print(ar._occupied)
# Place object a second time
best_spot = ar.bestSpot(shape_arr)
assert best_spot.x is not None # we found a location
@ -238,9 +205,6 @@ def test_bestSpot_scale_rectangular():
best_spot = ar.bestSpot(shape_arr_square)
ar.place(best_spot.x, best_spot.y, shape_arr_square)
print(ar._occupied) # For debugging
## Try to place an object and see if something explodes
def test_smoke_place():
ar = Arrange(30, 30, 15, 15)
@ -252,7 +216,6 @@ def test_smoke_place():
ar.place(0, 0, shape_arr)
assert numpy.any(ar._occupied)
## See of our center has less penalty points than out of the center
def test_checkShape():
ar = Arrange(30, 30, 15, 15)
@ -265,12 +228,10 @@ def test_checkShape():
assert points2 > points
assert points3 > points
## See of our center has less penalty points than out of the center
def test_checkShape_rectangular():
ar = Arrange(20, 30, 10, 15)
ar.centerFirst()
print(ar._priority)
shape_arr = gimmeShapeArray()
points = ar.checkShape(0, 0, shape_arr)
@ -279,20 +240,18 @@ def test_checkShape_rectangular():
assert points2 > points
assert points3 > points
## Check that placing an object on occupied place returns None.
def test_checkShape_place():
ar = Arrange(30, 30, 15, 15)
ar.centerFirst()
shape_arr = gimmeShapeArray()
points = ar.checkShape(3, 6, shape_arr)
ar.checkShape(3, 6, shape_arr)
ar.place(3, 6, shape_arr)
points2 = ar.checkShape(3, 6, shape_arr)
assert points2 is None
## Test the whole sequence
def test_smoke_place_objects():
ar = Arrange(20, 20, 10, 10, scale = 1)
@ -303,35 +262,30 @@ def test_smoke_place_objects():
best_spot_x, best_spot_y, score, prio = ar.bestSpot(shape_arr)
ar.place(best_spot_x, best_spot_y, shape_arr)
# Test some internals
def test_compare_occupied_and_priority_tables():
ar = Arrange(10, 15, 5, 7)
ar.centerFirst()
assert ar._priority.shape == ar._occupied.shape
## Polygon -> array
def test_arrayFromPolygon():
vertices = numpy.array([[-3, 1], [3, 1], [0, -3]])
array = ShapeArray.arrayFromPolygon([5, 5], vertices)
assert numpy.any(array)
## Polygon -> array
def test_arrayFromPolygon2():
vertices = numpy.array([[-3, 1], [3, 1], [2, -3]])
array = ShapeArray.arrayFromPolygon([5, 5], vertices)
assert numpy.any(array)
## Polygon -> array
def test_fromPolygon():
vertices = numpy.array([[0, 0.5], [0, 0], [0.5, 0]])
array = ShapeArray.fromPolygon(vertices, scale=0.5)
assert numpy.any(array.arr)
## Line definition -> array with true/false
def test_check():
base_array = numpy.zeros([5, 5], dtype=float)
@ -342,7 +296,6 @@ def test_check():
assert check_array[3][0]
assert not check_array[0][3]
## Line definition -> array with true/false
def test_check2():
base_array = numpy.zeros([5, 5], dtype=float)
@ -353,22 +306,17 @@ def test_check2():
assert not check_array[3][0]
assert check_array[3][4]
## Just adding some stuff to ensure fromNode works as expected. Some parts should actually be in UM
def test_parts_of_fromNode():
from UM.Math.Polygon import Polygon
p = Polygon(numpy.array([[-2, -2], [2, -2], [2, 2], [-2, 2]], dtype=numpy.int32))
offset = 1
print(p._points)
p_offset = p.getMinkowskiHull(Polygon.approximatedCircle(offset))
print("--------------")
print(p_offset._points)
assert len(numpy.where(p_offset._points[:, 0] >= 2.9)) > 0
assert len(numpy.where(p_offset._points[:, 0] <= -2.9)) > 0
assert len(numpy.where(p_offset._points[:, 1] >= 2.9)) > 0
assert len(numpy.where(p_offset._points[:, 1] <= -2.9)) > 0
def test_parts_of_fromNode2():
from UM.Math.Polygon import Polygon
p = Polygon(numpy.array([[-2, -2], [2, -2], [2, 2], [-2, 2]], dtype=numpy.int32) * 2) # 4x4
@ -378,4 +326,4 @@ def test_parts_of_fromNode2():
shape_arr1 = ShapeArray.fromPolygon(p._points, scale = scale)
shape_arr2 = ShapeArray.fromPolygon(p_offset._points, scale = scale)
assert shape_arr1.arr.shape[0] >= (4 * scale) - 1 # -1 is to account for rounding errors
assert shape_arr2.arr.shape[0] >= (2 * offset + 4) * scale - 1
assert shape_arr2.arr.shape[0] >= (2 * offset + 4) * scale - 1

View file

@ -0,0 +1,43 @@
from unittest.mock import MagicMock, patch
from cura.Machines.MaterialManager import MaterialManager
mocked_registry = MagicMock()
material_1 = {"id": "test", "GUID":"TEST!", "base_file": "base_material", "definition": "fdmmachine", "approximate_diameter": 3, "brand": "generic"}
material_2 = {"id": "base_material", "GUID": "TEST2!", "base_file": "test", "definition": "fdmmachine", "approximate_diameter": 3}
mocked_registry.findContainersMetadata = MagicMock(return_value = [material_1, material_2])
mocked_definition = MagicMock()
mocked_definition.getId = MagicMock(return_value = "fdmmachine")
mocked_definition.getMetaDataEntry = MagicMock(return_value = [])
def test_initialize(application):
# Just test if the simple loading works
with patch("UM.Application.Application.getInstance", MagicMock(return_value=application)):
manager = MaterialManager(mocked_registry)
manager.initialize()
# Double check that we actually got some material nodes
assert manager.getMaterialGroup("base_material").name == "base_material"
assert manager.getMaterialGroup("test").name == "test"
def test_getAvailableMaterials(application):
with patch("UM.Application.Application.getInstance", MagicMock(return_value=application)):
manager = MaterialManager(mocked_registry)
manager.initialize()
available_materials = manager.getAvailableMaterials(mocked_definition, None, None, 3)
assert "base_material" in available_materials
assert "test" in available_materials
def test_getMaterialNode(application):
with patch("UM.Application.Application.getInstance", MagicMock(return_value=application)):
manager = MaterialManager(mocked_registry)
manager.initialize()
assert manager.getMaterialNode("fdmmachine", None, None, 3, "base_material").getMetaDataEntry("id") == "test"

View file

@ -77,8 +77,6 @@ def test_duration():
# Fake a print duration message
print_information._onPrintDurationMessage(0, {"travel": 20}, [10])
# Some debugging code, since this test sometimes fails on the CI server.
print("Testing debug;", print_information.getFeaturePrintTimes(), print_information.currentPrintTime)
# We only set a single time, so the total time must be of the same value.
assert int(print_information.currentPrintTime) == 20

View file

@ -0,0 +1,60 @@
from unittest.mock import MagicMock
import pytest
from cura.Machines.QualityManager import QualityManager
mocked_stack = MagicMock()
mocked_extruder = MagicMock()
mocked_material = MagicMock()
mocked_material.getMetaDataEntry = MagicMock(return_value = "base_material")
mocked_extruder.material = mocked_material
mocked_stack.extruders = {"0": mocked_extruder}
@pytest.fixture()
def material_manager():
result = MagicMock()
result.getRootMaterialIDWithoutDiameter = MagicMock(return_value = "base_material")
return result
@pytest.fixture()
def container_registry():
result = MagicMock()
mocked_metadata = [{"id": "test", "definition": "fdmprinter", "quality_type": "normal", "name": "test_name", "global_quality": True, "type": "quality"},
{"id": "test_material", "definition": "fdmprinter", "quality_type": "normal", "name": "test_name_material", "material": "base_material", "type": "quality"},
{"id": "quality_changes_id", "definition": "fdmprinter", "type": "quality_changes", "quality_type": "amazing!", "name": "herp"}]
result.findContainersMetadata = MagicMock(return_value = mocked_metadata)
return result
@pytest.fixture()
def quality_mocked_application(material_manager, container_registry):
result = MagicMock()
result.getMaterialManager = MagicMock(return_value=material_manager)
result.getContainerRegistry = MagicMock(return_value=container_registry)
return result
def test_getQualityGroups(quality_mocked_application):
manager = QualityManager(quality_mocked_application)
manager.initialize()
assert "normal" in manager.getQualityGroups(mocked_stack)
def test_getQualityGroupsForMachineDefinition(quality_mocked_application):
manager = QualityManager(quality_mocked_application)
manager.initialize()
assert "normal" in manager.getQualityGroupsForMachineDefinition(mocked_stack)
def test_getQualityChangesGroup(quality_mocked_application):
manager = QualityManager(quality_mocked_application)
manager.initialize()
assert "herp" in manager.getQualityChangesGroups(mocked_stack)