TestGlobalStack.py 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601
  1. # Copyright (c) 2017 Ultimaker B.V.
  2. # Cura is released under the terms of the AGPLv3 or higher.
  3. import os.path #To find the test files.
  4. import pytest #This module contains unit tests.
  5. import unittest.mock #To monkeypatch some mocks in place of dependencies.
  6. import copy
  7. import functools
  8. import cura.Settings.GlobalStack #The module we're testing.
  9. from cura.Settings.Exceptions import TooManyExtrudersError, InvalidContainerError, InvalidOperationError #To test raising these errors.
  10. from UM.Settings.DefinitionContainer import DefinitionContainer #To test against the class DefinitionContainer.
  11. from UM.Settings.InstanceContainer import InstanceContainer #To test against the class InstanceContainer.
  12. import UM.Settings.ContainerRegistry
  13. import UM.Settings.ContainerStack
  14. class MockContainer:
  15. def __init__(self, container_id, type = "mock"):
  16. self._id = container_id
  17. self._type = type
  18. self._property_map = {}
  19. def getId(self):
  20. return self._id
  21. def getMetaDataEntry(self, entry, default = None):
  22. if entry == "type":
  23. return self._type
  24. return default
  25. def getProperty(self, key, property_name):
  26. if key not in self._property_map:
  27. return None
  28. if property_name not in self._property_map[key]:
  29. return None
  30. return self._property_map[key][property_name]
  31. def setProperty(self, key, property_name, value):
  32. if key not in self._property_map:
  33. self._property_map[key] = {}
  34. self._property_map[key][property_name] = value
  35. propertyChanged = unittest.mock.MagicMock()
  36. ## Fake container registry that always provides all containers you ask of.
  37. @pytest.fixture()
  38. def container_registry():
  39. registry = unittest.mock.MagicMock()
  40. registry.typeMetaData = "registry_mock"
  41. def findInstanceContainers(registry, **kwargs):
  42. if "id" not in kwargs:
  43. return [MockContainer("test_container", registry.typeMetaData)]
  44. else:
  45. return [MockContainer(id, registry.typeMetaData)]
  46. registry.findInstanceContainers = functools.partial(findInstanceContainers, registry)
  47. def findContainers(registry, container_type = None, id = None):
  48. if not id:
  49. return [MockContainer("test_container", registry.typeMetaData)]
  50. else:
  51. return [MockContainer(id, registry.typeMetaData)]
  52. registry.findContainers = functools.partial(findContainers, registry)
  53. UM.Settings.ContainerRegistry.ContainerRegistry._ContainerRegistry__instance = registry
  54. UM.Settings.ContainerStack._containerRegistry = registry
  55. yield registry
  56. UM.Settings.ContainerRegistry.ContainerRegistry._ContainerRegistry__instance = None
  57. UM.Settings.ContainerStack._containerRegistry = None
  58. #An empty global stack to test with.
  59. @pytest.fixture()
  60. def global_stack() -> cura.Settings.GlobalStack.GlobalStack:
  61. return cura.Settings.GlobalStack.GlobalStack("TestStack")
  62. ## Place-in function for findContainer that finds only containers that start
  63. # with "some_".
  64. def findSomeContainers(container_id = "*", container_type = None, type = None, category = "*"):
  65. if container_id.startswith("some_"):
  66. return UM.Settings.ContainerRegistry._EmptyInstanceContainer(container_id)
  67. if container_type == DefinitionContainer:
  68. definition_mock = unittest.mock.MagicMock()
  69. definition_mock.getId = unittest.mock.MagicMock(return_value = "some_definition") #getId returns some_definition.
  70. return definition_mock
  71. ## Helper function to read the contents of a container stack in the test
  72. # stack folder.
  73. #
  74. # \param filename The name of the file in the "stacks" folder to read from.
  75. # \return The contents of that file.
  76. def readStack(filename):
  77. with open(os.path.join(os.path.dirname(os.path.abspath(__file__)), "stacks", filename)) as file_handle:
  78. serialized = file_handle.read()
  79. return serialized
  80. class DefinitionContainerSubClass(DefinitionContainer):
  81. def __init__(self):
  82. super().__init__(container_id = "SubDefinitionContainer")
  83. class InstanceContainerSubClass(InstanceContainer):
  84. def __init__(self):
  85. super().__init__(container_id = "SubInstanceContainer")
  86. #############################START OF TEST CASES################################
  87. ## Tests whether adding a container is properly forbidden.
  88. def test_addContainer(global_stack):
  89. with pytest.raises(InvalidOperationError):
  90. global_stack.addContainer(unittest.mock.MagicMock())
  91. ## Tests adding extruders to the global stack.
  92. def test_addExtruder(global_stack):
  93. mock_definition = unittest.mock.MagicMock()
  94. mock_definition.getProperty = lambda key, property: 2 if key == "machine_extruder_count" and property == "value" else None
  95. global_stack.definition = mock_definition
  96. assert len(global_stack.extruders) == 0
  97. first_extruder = unittest.mock.MagicMock()
  98. global_stack.addExtruder(first_extruder)
  99. assert len(global_stack.extruders) == 1
  100. assert global_stack.extruders[0] == first_extruder
  101. second_extruder = unittest.mock.MagicMock()
  102. global_stack.addExtruder(second_extruder)
  103. assert len(global_stack.extruders) == 2
  104. assert global_stack.extruders[1] == second_extruder
  105. with pytest.raises(TooManyExtrudersError): #Should be limited to 2 extruders because of machine_extruder_count.
  106. global_stack.addExtruder(unittest.mock.MagicMock())
  107. assert len(global_stack.extruders) == 2 #Didn't add the faulty extruder.
  108. ## Tests whether the container types are properly enforced on the stack.
  109. #
  110. # When setting a field to have a different type of stack than intended, we
  111. # should get an exception.
  112. @pytest.mark.parametrize("definition_container, instance_container", [
  113. (DefinitionContainer(container_id = "TestDefinitionContainer"), InstanceContainer(container_id = "TestInstanceContainer")),
  114. (DefinitionContainerSubClass(), InstanceContainerSubClass())
  115. ])
  116. def test_constrainContainerTypes(definition_container, instance_container, global_stack):
  117. instance_container.addMetaDataEntry("type", "")
  118. with pytest.raises(InvalidContainerError): # Putting a definition container in the user changes is not allowed.
  119. global_stack.userChanges = definition_container
  120. with pytest.raises(InvalidContainerError):
  121. global_stack.userChanges = instance_container # Putting a random instance container in the user changes is not allowed.
  122. instance_container.setMetaDataEntry("type", "user") # After setting the metadata type entry correctly, we are allowed to set the container
  123. global_stack.userChanges = instance_container
  124. with pytest.raises(InvalidContainerError):
  125. global_stack.qualityChanges = definition_container
  126. with pytest.raises(InvalidContainerError):
  127. global_stack.qualityChanges = instance_container
  128. instance_container.setMetaDataEntry("type", "quality_changes")
  129. global_stack.qualityChanges = instance_container
  130. with pytest.raises(InvalidContainerError):
  131. global_stack.quality = definition_container
  132. with pytest.raises(InvalidContainerError):
  133. global_stack.quality = instance_container
  134. instance_container.setMetaDataEntry("type", "quality")
  135. global_stack.quality = instance_container
  136. with pytest.raises(InvalidContainerError):
  137. global_stack.material = definition_container
  138. with pytest.raises(InvalidContainerError):
  139. global_stack.material = instance_container
  140. instance_container.setMetaDataEntry("type", "material")
  141. global_stack.material = instance_container
  142. with pytest.raises(InvalidContainerError):
  143. global_stack.variant = definition_container
  144. with pytest.raises(InvalidContainerError):
  145. global_stack.variant = instance_container
  146. instance_container.setMetaDataEntry("type", "variant")
  147. global_stack.variant = instance_container
  148. with pytest.raises(InvalidContainerError):
  149. global_stack.definitionChanges = definition_container
  150. with pytest.raises(InvalidContainerError):
  151. global_stack.definitionChanges = instance_container
  152. instance_container.setMetaDataEntry("type", "definition_changes")
  153. global_stack.definitionChanges = instance_container
  154. with pytest.raises(InvalidContainerError): #Putting an instance container in the definition is not allowed.
  155. global_stack.definition = instance_container
  156. global_stack.definition = definition_container #Putting a definition container in the definition is allowed.
  157. ## Tests whether the user changes are being read properly from a global stack.
  158. @pytest.mark.parametrize("filename, user_changes_id", [
  159. ("Global.global.cfg", "empty"),
  160. ("Global.stack.cfg", "empty"),
  161. ("MachineLegacy.stack.cfg", "empty"),
  162. ("OnlyUser.global.cfg", "some_instance"), #This one does have a user profile.
  163. ("Complete.global.cfg", "some_user_changes")
  164. ])
  165. def test_deserializeUserChanges(filename, user_changes_id, container_registry, global_stack):
  166. serialized = readStack(filename)
  167. #Mock the loading of the instance containers.
  168. global_stack.findContainer = findSomeContainers
  169. original_container_registry = UM.Settings.ContainerStack._containerRegistry
  170. UM.Settings.ContainerStack._containerRegistry = container_registry #Always has all profiles you ask of.
  171. global_stack.deserialize(serialized)
  172. assert global_stack.userChanges.getId() == user_changes_id
  173. #Restore.
  174. UM.Settings.ContainerStack._containerRegistry = original_container_registry
  175. ## Tests whether the quality changes are being read properly from a global
  176. # stack.
  177. @pytest.mark.parametrize("filename, quality_changes_id", [
  178. ("Global.global.cfg", "empty"),
  179. ("Global.stack.cfg", "empty"),
  180. ("MachineLegacy.stack.cfg", "empty"),
  181. ("OnlyQualityChanges.global.cfg", "some_instance"),
  182. ("Complete.global.cfg", "some_quality_changes")
  183. ])
  184. def test_deserializeQualityChanges(filename, quality_changes_id, container_registry, global_stack):
  185. serialized = readStack(filename)
  186. #Mock the loading of the instance containers.
  187. global_stack.findContainer = findSomeContainers
  188. original_container_registry = UM.Settings.ContainerStack._containerRegistry
  189. UM.Settings.ContainerStack._containerRegistry = container_registry #Always has all the profiles you ask of.
  190. global_stack.deserialize(serialized)
  191. assert global_stack.qualityChanges.getId() == quality_changes_id
  192. #Restore.
  193. UM.Settings.ContainerStack._containerRegistry = original_container_registry
  194. ## Tests whether the quality profile is being read properly from a global
  195. # stack.
  196. @pytest.mark.parametrize("filename, quality_id", [
  197. ("Global.global.cfg", "empty"),
  198. ("Global.stack.cfg", "empty"),
  199. ("MachineLegacy.stack.cfg", "empty"),
  200. ("OnlyQuality.global.cfg", "some_instance"),
  201. ("Complete.global.cfg", "some_quality")
  202. ])
  203. def test_deserializeQuality(filename, quality_id, container_registry, global_stack):
  204. serialized = readStack(filename)
  205. #Mock the loading of the instance containers.
  206. global_stack.findContainer = findSomeContainers
  207. original_container_registry = UM.Settings.ContainerStack._containerRegistry
  208. UM.Settings.ContainerStack._containerRegistry = container_registry #Always has all the profiles you ask of.
  209. global_stack.deserialize(serialized)
  210. assert global_stack.quality.getId() == quality_id
  211. #Restore.
  212. UM.Settings.ContainerStack._containerRegistry = original_container_registry
  213. ## Tests whether the material profile is being read properly from a global
  214. # stack.
  215. @pytest.mark.parametrize("filename, material_id", [
  216. ("Global.global.cfg", "some_instance"),
  217. ("Global.stack.cfg", "some_instance"),
  218. ("MachineLegacy.stack.cfg", "some_instance"),
  219. ("OnlyDefinition.global.cfg", "empty"),
  220. ("OnlyMaterial.global.cfg", "some_instance"),
  221. ("Complete.global.cfg", "some_material")
  222. ])
  223. def test_deserializeMaterial(filename, material_id, container_registry, global_stack):
  224. serialized = readStack(filename)
  225. #Mock the loading of the instance containers.
  226. global_stack.findContainer = findSomeContainers
  227. original_container_registry = UM.Settings.ContainerStack._containerRegistry
  228. UM.Settings.ContainerStack._containerRegistry = container_registry #Always has all the profiles you ask of.
  229. global_stack.deserialize(serialized)
  230. assert global_stack.material.getId() == material_id
  231. #Restore.
  232. UM.Settings.ContainerStack._containerRegistry = original_container_registry
  233. ## Tests whether the variant profile is being read properly from a global
  234. # stack.
  235. @pytest.mark.parametrize("filename, variant_id", [
  236. ("Global.global.cfg", "empty"),
  237. ("Global.stack.cfg", "empty"),
  238. ("MachineLegacy.stack.cfg", "empty"),
  239. ("OnlyVariant.global.cfg", "some_instance"),
  240. ("Complete.global.cfg", "some_variant")
  241. ])
  242. def test_deserializeVariant(filename, variant_id, container_registry, global_stack):
  243. serialized = readStack(filename)
  244. #Mock the loading of the instance containers.
  245. global_stack.findContainer = findSomeContainers
  246. original_container_registry = UM.Settings.ContainerStack._containerRegistry
  247. UM.Settings.ContainerStack._containerRegistry = container_registry #Always has all the profiles you ask of.
  248. global_stack.deserialize(serialized)
  249. assert global_stack.variant.getId() == variant_id
  250. #Restore.
  251. UM.Settings.ContainerStack._containerRegistry = original_container_registry
  252. ## Tests whether the definition changes profile is being read properly from a
  253. # global stack.
  254. @pytest.mark.parametrize("filename, definition_changes_id", [
  255. ("Global.global.cfg", "empty"),
  256. ("Global.stack.cfg", "empty"),
  257. ("MachineLegacy.stack.cfg", "empty"),
  258. ("OnlyDefinitionChanges.global.cfg", "some_instance"),
  259. ("Complete.global.cfg", "some_material")
  260. ])
  261. def test_deserializeDefinitionChanges(filename, definition_changes_id, container_registry, global_stack):
  262. serialized = readStack(filename)
  263. global_stack = cura.Settings.GlobalStack.GlobalStack("TestStack")
  264. #Mock the loading of the instance containers.
  265. global_stack.findContainer = findSomeContainers
  266. original_container_registry = UM.Settings.ContainerStack._containerRegistry
  267. UM.Settings.ContainerStack._containerRegistry = container_registry #Always has all the profiles you ask of.
  268. global_stack.deserialize(serialized)
  269. assert global_stack.definitionChanges.getId() == definition_changes_id
  270. #Restore.
  271. UM.Settings.ContainerStack._containerRegistry = original_container_registry
  272. ## Tests whether the definition is being read properly from a global stack.
  273. @pytest.mark.parametrize("filename, definition_id", [
  274. ("Global.global.cfg", "some_definition"),
  275. ("Global.stack.cfg", "some_definition"),
  276. ("MachineLegacy.stack.cfg", "some_definition"),
  277. ("OnlyDefinition.global.cfg", "some_definition"),
  278. ("Complete.global.cfg", "some_definition")
  279. ])
  280. def test_deserializeDefinition(filename, definition_id, container_registry, global_stack):
  281. serialized = readStack(filename)
  282. #Mock the loading of the instance containers.
  283. global_stack.findContainer = findSomeContainers
  284. original_container_registry = UM.Settings.ContainerStack._containerRegistry
  285. UM.Settings.ContainerStack._containerRegistry = container_registry #Always has all the profiles you ask of.
  286. global_stack.deserialize(serialized)
  287. assert global_stack.definition.getId() == definition_id
  288. #Restore.
  289. UM.Settings.ContainerStack._containerRegistry = original_container_registry
  290. ## Tests that when a global stack is loaded with an unknown instance, it raises
  291. # an exception.
  292. def test_deserializeMissingContainer(global_stack):
  293. serialized = readStack("Global.global.cfg")
  294. with pytest.raises(Exception):
  295. global_stack.deserialize(serialized)
  296. try:
  297. global_stack.deserialize(serialized)
  298. except Exception as e:
  299. #Must be exactly Exception, not one of its subclasses, since that is what gets raised when a stack has an unknown container.
  300. #That's why we can't use pytest.raises.
  301. assert type(e) == Exception
  302. ## Tests whether getProperty properly applies the stack-like behaviour on its
  303. # containers.
  304. def test_getPropertyFallThrough(global_stack):
  305. #A few instance container mocks to put in the stack.
  306. layer_height_5 = unittest.mock.MagicMock() #Sets layer height to 5.
  307. layer_height_5.getProperty = lambda key, property: 5 if (key == "layer_height" and property == "value") else None
  308. layer_height_5.hasProperty = lambda key: key == "layer_height"
  309. layer_height_10 = unittest.mock.MagicMock() #Sets layer height to 10.
  310. layer_height_10.getProperty = lambda key, property: 10 if (key == "layer_height" and property == "value") else None
  311. layer_height_10.hasProperty = lambda key: key == "layer_height"
  312. no_layer_height = unittest.mock.MagicMock() #No settings at all.
  313. no_layer_height.getProperty = lambda key, property: None
  314. no_layer_height.hasProperty = lambda key: False
  315. global_stack.userChanges = no_layer_height
  316. global_stack.qualityChanges = no_layer_height
  317. global_stack.quality = no_layer_height
  318. global_stack.material = no_layer_height
  319. global_stack.variant = no_layer_height
  320. global_stack.definitionChanges = no_layer_height
  321. global_stack.definition = layer_height_5 #Here it is!
  322. assert global_stack.getProperty("layer_height", "value") == 5
  323. global_stack.definitionChanges = layer_height_10
  324. assert global_stack.getProperty("layer_height", "value") == 10
  325. global_stack.variant = layer_height_5
  326. assert global_stack.getProperty("layer_height", "value") == 5
  327. global_stack.material = layer_height_10
  328. assert global_stack.getProperty("layer_height", "value") == 10
  329. global_stack.quality = layer_height_5
  330. assert global_stack.getProperty("layer_height", "value") == 5
  331. global_stack.qualityChanges = layer_height_10
  332. assert global_stack.getProperty("layer_height", "value") == 10
  333. global_stack.userChanges = layer_height_5
  334. assert global_stack.getProperty("layer_height", "value") == 5
  335. def test_getPropertyWithResolve(global_stack):
  336. #Define some containers for the stack.
  337. resolve = unittest.mock.MagicMock() #Sets just the resolve for bed temperature.
  338. resolve.getProperty = lambda key, property: 15 if (key == "material_bed_temperature" and property == "resolve") else None
  339. resolve_and_value = unittest.mock.MagicMock() #Sets the resolve and value for bed temperature.
  340. resolve_and_value.getProperty = lambda key, property: (7.5 if property == "resolve" else 5) if (key == "material_bed_temperature") else None #7.5 resolve, 5 value.
  341. value = unittest.mock.MagicMock() #Sets just the value for bed temperature.
  342. value.getProperty = lambda key, property: 10 if (key == "material_bed_temperature" and property == "value") else None
  343. empty = unittest.mock.MagicMock() #Sets no value or resolve.
  344. empty.getProperty = unittest.mock.MagicMock(return_value = None)
  345. global_stack.definition = resolve_and_value
  346. assert global_stack.getProperty("material_bed_temperature", "value") == 7.5 #Resolve wins in the definition.
  347. global_stack.userChanges = resolve_and_value
  348. assert global_stack.getProperty("material_bed_temperature", "value") == 5 #Value wins in other places.
  349. global_stack.userChanges = value
  350. assert global_stack.getProperty("material_bed_temperature", "value") == 10 #Resolve in the definition doesn't influence the value in the user changes.
  351. global_stack.userChanges = resolve
  352. assert global_stack.getProperty("material_bed_temperature", "value") == 15 #Falls through to definition for lack of values, but then asks the start of the stack for the resolve.
  353. global_stack.userChanges = empty
  354. global_stack.qualityChanges = resolve_and_value
  355. assert global_stack.getProperty("material_bed_temperature", "value") == 5 #Value still wins in lower places, except definition.
  356. global_stack.qualityChanges = empty
  357. global_stack.quality = resolve_and_value
  358. assert global_stack.getProperty("material_bed_temperature", "value") == 5
  359. global_stack.quality = empty
  360. global_stack.material = resolve_and_value
  361. assert global_stack.getProperty("material_bed_temperature", "value") == 5
  362. global_stack.material = empty
  363. global_stack.variant = resolve_and_value
  364. assert global_stack.getProperty("material_bed_temperature", "value") == 5
  365. global_stack.variant = empty
  366. global_stack.definitionChanges = resolve_and_value
  367. assert global_stack.getProperty("material_bed_temperature", "value") == 5
  368. ## Tests whether the hasUserValue returns true for settings that are changed in
  369. # the user-changes container.
  370. def test_hasUserValueUserChanges(global_stack):
  371. user_changes = unittest.mock.MagicMock()
  372. def hasProperty(key, property):
  373. return key == "layer_height" and property == "value" #Only have the layer_height property set.
  374. user_changes.hasProperty = hasProperty
  375. global_stack.userChanges = user_changes
  376. assert not global_stack.hasUserValue("infill_sparse_density")
  377. assert global_stack.hasUserValue("layer_height")
  378. assert not global_stack.hasUserValue("")
  379. ## Tests whether the hasUserValue returns true for settings that are changed in
  380. # the quality-changes container.
  381. def test_hasUserValueQualityChanges(global_stack):
  382. quality_changes = unittest.mock.MagicMock()
  383. def hasProperty(key, property):
  384. return key == "layer_height" and property == "value" #Only have the layer_height property set.
  385. quality_changes.hasProperty = hasProperty
  386. global_stack.qualityChanges = quality_changes
  387. assert not global_stack.hasUserValue("infill_sparse_density")
  388. assert global_stack.hasUserValue("layer_height")
  389. assert not global_stack.hasUserValue("")
  390. ## Tests whether inserting a container is properly forbidden.
  391. def test_insertContainer(global_stack):
  392. with pytest.raises(InvalidOperationError):
  393. global_stack.insertContainer(0, unittest.mock.MagicMock())
  394. ## Tests whether removing a container is properly forbidden.
  395. def test_removeContainer(global_stack):
  396. with pytest.raises(InvalidOperationError):
  397. global_stack.removeContainer(unittest.mock.MagicMock())
  398. ## Tests setting definitions by specifying an ID of a definition that exists.
  399. def test_setDefinitionByIdExists(global_stack, container_registry):
  400. global_stack.setDefinitionById("some_definition") #The container registry always has a container with the ID.
  401. ## Tests setting definitions by specifying an ID of a definition that doesn't
  402. # exist.
  403. def test_setDefinitionByIdDoesntExist(global_stack):
  404. with pytest.raises(InvalidContainerError):
  405. global_stack.setDefinitionById("some_definition") #Container registry is empty now.
  406. ## Tests setting definition changes by specifying an ID of a container that
  407. # exists.
  408. def test_setDefinitionChangesByIdExists(global_stack, container_registry):
  409. container_registry.typeMetaData = "definition_changes"
  410. global_stack.setDefinitionChangesById("some_definition_changes") #The container registry always has a container with the ID.
  411. ## Tests setting definition changes by specifying an ID of a container that
  412. # doesn't exist.
  413. def test_setDefinitionChangesByIdDoesntExist(global_stack):
  414. with pytest.raises(InvalidContainerError):
  415. global_stack.setDefinitionChangesById("some_definition_changes") #Container registry is empty now.
  416. ## Tests setting materials by specifying an ID of a material that exists.
  417. def test_setMaterialByIdExists(global_stack, container_registry):
  418. container_registry.typeMetaData = "material"
  419. global_stack.setMaterialById("some_material") #The container registry always has a container with the ID.
  420. ## Tests setting materials by specifying an ID of a material that doesn't
  421. # exist.
  422. def test_setMaterialByIdDoesntExist(global_stack):
  423. with pytest.raises(InvalidContainerError):
  424. global_stack.setMaterialById("some_material") #Container registry is empty now.
  425. ## Tests whether changing the next stack is properly forbidden.
  426. def test_setNextStack(global_stack):
  427. with pytest.raises(InvalidOperationError):
  428. global_stack.setNextStack(unittest.mock.MagicMock())
  429. ## Tests setting properties directly on the global stack.
  430. @pytest.mark.parametrize("key, property, value, output_value", [
  431. ("layer_height", "value", "0.1337", 0.1337),
  432. ("foo", "value", "100", 100),
  433. ("support_enabled", "value", "True", True),
  434. ("layer_height", "default_value", 0.1337, 0.1337),
  435. ("layer_height", "is_bright_pink", "of course", "of course")
  436. ])
  437. def test_setPropertyUser(key, property, value, output_value, global_stack):
  438. global_stack.setUserChanges(MockContainer(global_stack.id + "_user", "user"))
  439. global_stack.setProperty(key, value, property)
  440. assert global_stack.userChanges.getProperty(key, property) == output_value
  441. ## Tests setting properties on specific containers on the global stack.
  442. @pytest.mark.parametrize("target_container", [
  443. "user",
  444. "quality_changes",
  445. "quality",
  446. "material",
  447. "variant",
  448. "definition_changes",
  449. ])
  450. def test_setPropertyOtherContainers(target_container, global_stack):
  451. #Other parameters that don't need to be varied.
  452. key = "layer_height"
  453. property = "value",
  454. value = "0.1337",
  455. output_value = 0.1337
  456. global_stack.setProperty(key, value, property, target_container = target_container)
  457. containers = {
  458. "user": global_stack.userChanges,
  459. "quality_changes": global_stack.qualityChanges,
  460. "quality": global_stack.quality,
  461. "material": global_stack.material,
  462. "variant": global_stack.variant,
  463. "definition_changes": global_stack.definitionChanges,
  464. "definition": global_stack.definition
  465. }
  466. assert containers[target_container].getProperty(key, property) == output_value
  467. ## Tests setting qualities by specifying an ID of a quality that exists.
  468. def test_setQualityByIdExists(global_stack, container_registry):
  469. container_registry.typeMetaData = "quality"
  470. global_stack.setQualityById("some_quality") #The container registry always has a container with the ID.
  471. ## Tests setting qualities by specifying an ID of a quality that doesn't exist.
  472. def test_setQualityByIdDoesntExist(global_stack):
  473. with pytest.raises(InvalidContainerError):
  474. global_stack.setQualityById("some_quality") #Container registry is empty now.
  475. ## Tests setting quality changes by specifying an ID of a quality change that
  476. # exists.
  477. def test_setQualityChangesByIdExists(global_stack, container_registry):
  478. container_registry.typeMetaData = "quality_changes"
  479. global_stack.setQualityChangesById("some_quality_changes") #The container registry always has a container with the ID.
  480. ## Tests setting quality changes by specifying an ID of a quality change that
  481. # doesn't exist.
  482. def test_setQualityChangesByIdDoesntExist(global_stack):
  483. with pytest.raises(InvalidContainerError):
  484. global_stack.setQualityChangesById("some_quality_changes") #Container registry is empty now.
  485. ## Tests setting variants by specifying an ID of a variant that exists.
  486. def test_setVariantByIdExists(global_stack, container_registry):
  487. container_registry.typeMetaData = "variant"
  488. global_stack.setVariantById("some_variant") #The container registry always has a container with the ID.
  489. ## Tests setting variants by specifying an ID of a variant that doesn't exist.
  490. def test_setVariantByIdDoesntExist(global_stack):
  491. with pytest.raises(InvalidContainerError):
  492. global_stack.setVariantById("some_variant") #Container registry is empty now.