TestLegacyProfileReader.py 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. # Copyright (c) 2018 Ultimaker B.V.
  2. # Cura is released under the terms of the LGPLv3 or higher.
  3. import configparser # An input for some functions we're testing.
  4. import os.path # To find the integration test .ini files.
  5. import pytest # To register tests with.
  6. import unittest.mock # To mock the application, plug-in and container registry out.
  7. import sys
  8. sys.path.append(os.path.join(os.path.dirname(os.path.abspath(__file__)), ".."))
  9. import UM.Application # To mock the application out.
  10. import UM.PluginRegistry # To mock the plug-in registry out.
  11. import UM.Settings.ContainerRegistry # To mock the container registry out.
  12. import UM.Settings.InstanceContainer # To intercept the serialised data from the read() function.
  13. import LegacyProfileReader as LegacyProfileReaderModule # To get the directory of the module.
  14. @pytest.fixture
  15. def legacy_profile_reader():
  16. try:
  17. return LegacyProfileReaderModule.LegacyProfileReader()
  18. except TypeError:
  19. return LegacyProfileReaderModule.LegacyProfileReader.LegacyProfileReader()
  20. test_prepareDefaultsData = [
  21. {
  22. "defaults":
  23. {
  24. "foo": "bar"
  25. },
  26. "cheese": "delicious"
  27. },
  28. {
  29. "cat": "fluffy",
  30. "dog": "floofy"
  31. }
  32. ]
  33. @pytest.mark.parametrize("input", test_prepareDefaultsData)
  34. def test_prepareDefaults(legacy_profile_reader, input):
  35. output = legacy_profile_reader.prepareDefaults(input)
  36. if "defaults" in input:
  37. assert input["defaults"] == output
  38. else:
  39. assert output == {}
  40. test_prepareLocalsData = [
  41. ( # Ordinary case.
  42. { # Parser data.
  43. "profile":
  44. {
  45. "layer_height": "0.2",
  46. "infill_density": "30"
  47. }
  48. },
  49. { # Defaults.
  50. "layer_height": "0.1",
  51. "infill_density": "20",
  52. "line_width": "0.4"
  53. }
  54. ),
  55. ( # Empty data.
  56. { # Parser data.
  57. "profile":
  58. {
  59. }
  60. },
  61. { # Defaults.
  62. }
  63. ),
  64. ( # All defaults.
  65. { # Parser data.
  66. "profile":
  67. {
  68. }
  69. },
  70. { # Defaults.
  71. "foo": "bar",
  72. "boo": "far"
  73. }
  74. ),
  75. ( # Multiple config sections.
  76. { # Parser data.
  77. "some_other_name":
  78. {
  79. "foo": "bar"
  80. },
  81. "profile":
  82. {
  83. "foo": "baz" #Not the same as in some_other_name
  84. }
  85. },
  86. { # Defaults.
  87. "foo": "bla"
  88. }
  89. )
  90. ]
  91. @pytest.mark.parametrize("parser_data, defaults", test_prepareLocalsData)
  92. def test_prepareLocals(legacy_profile_reader, parser_data, defaults):
  93. parser = configparser.ConfigParser()
  94. parser.read_dict(parser_data)
  95. output = legacy_profile_reader.prepareLocals(parser, "profile", defaults)
  96. assert set(defaults.keys()) <= set(output.keys()) # All defaults must be in there.
  97. assert set(parser_data["profile"]) <= set(output.keys()) # All overwritten values must be in there.
  98. for key in output:
  99. if key in parser_data["profile"]:
  100. assert output[key] == parser_data["profile"][key] # If overwritten, must be the overwritten value.
  101. else:
  102. assert output[key] == defaults[key] # Otherwise must be equal to the default.
  103. test_prepareLocalsNoSectionErrorData = [
  104. ( # Section does not exist.
  105. { # Parser data.
  106. "some_other_name":
  107. {
  108. "foo": "bar"
  109. },
  110. },
  111. { # Defaults.
  112. "foo": "baz"
  113. }
  114. )
  115. ]
  116. ## Test cases where a key error is expected.
  117. @pytest.mark.parametrize("parser_data, defaults", test_prepareLocalsNoSectionErrorData)
  118. def test_prepareLocalsNoSectionError(legacy_profile_reader, parser_data, defaults):
  119. parser = configparser.ConfigParser()
  120. parser.read_dict(parser_data)
  121. with pytest.raises(configparser.NoSectionError):
  122. legacy_profile_reader.prepareLocals(parser, "profile", defaults)
  123. intercepted_data = ""
  124. @pytest.mark.parametrize("file_name", ["normal_case.ini"])
  125. def test_read(legacy_profile_reader, file_name):
  126. # Mock out all dependencies. Quite a lot!
  127. global_stack = unittest.mock.MagicMock()
  128. global_stack.getProperty = unittest.mock.MagicMock(return_value = 1) # For machine_extruder_count setting.
  129. def getMetaDataEntry(key, default_value = ""):
  130. if key == "quality_definition":
  131. return "mocked_quality_definition"
  132. if key == "has_machine_quality":
  133. return "True"
  134. global_stack.definition.getMetaDataEntry = getMetaDataEntry
  135. global_stack.definition.getId = unittest.mock.MagicMock(return_value = "mocked_global_definition")
  136. application = unittest.mock.MagicMock()
  137. application.getGlobalContainerStack = unittest.mock.MagicMock(return_value = global_stack)
  138. application_getInstance = unittest.mock.MagicMock(return_value = application)
  139. container_registry = unittest.mock.MagicMock()
  140. container_registry_getInstance = unittest.mock.MagicMock(return_value = container_registry)
  141. container_registry.uniqueName = unittest.mock.MagicMock(return_value = "Imported Legacy Profile")
  142. container_registry.findDefinitionContainers = unittest.mock.MagicMock(return_value = [global_stack.definition])
  143. UM.Settings.InstanceContainer.setContainerRegistry(container_registry)
  144. plugin_registry = unittest.mock.MagicMock()
  145. plugin_registry_getInstance = unittest.mock.MagicMock(return_value = plugin_registry)
  146. plugin_registry.getPluginPath = unittest.mock.MagicMock(return_value = os.path.dirname(LegacyProfileReaderModule.__file__))
  147. # Mock out the resulting InstanceContainer so that we can intercept the data before it's passed through the version upgrader.
  148. def deserialize(self, data, filename): # Intercepts the serialised data that we'd perform the version upgrade from when deserializing.
  149. global intercepted_data
  150. intercepted_data = data
  151. parser = configparser.ConfigParser()
  152. parser.read_string(data)
  153. self._metadata["position"] = parser["metadata"]["position"]
  154. def duplicate(self, new_id, new_name):
  155. self._metadata["id"] = new_id
  156. self._metadata["name"] = new_name
  157. return self
  158. with unittest.mock.patch.object(UM.Application.Application, "getInstance", application_getInstance):
  159. with unittest.mock.patch.object(UM.Settings.ContainerRegistry.ContainerRegistry, "getInstance", container_registry_getInstance):
  160. with unittest.mock.patch.object(UM.PluginRegistry.PluginRegistry, "getInstance", plugin_registry_getInstance):
  161. with unittest.mock.patch.object(UM.Settings.InstanceContainer.InstanceContainer, "deserialize", deserialize):
  162. with unittest.mock.patch.object(UM.Settings.InstanceContainer.InstanceContainer, "duplicate", duplicate):
  163. result = legacy_profile_reader.read(os.path.join(os.path.dirname(__file__), file_name))
  164. assert len(result) == 1
  165. # Let's see what's inside the actual output file that we generated.
  166. parser = configparser.ConfigParser()
  167. parser.read_string(intercepted_data)
  168. assert parser["general"]["definition"] == "mocked_quality_definition"
  169. assert parser["general"]["version"] == "4" # Yes, before we upgraded.
  170. assert parser["general"]["name"] == "Imported Legacy Profile" # Because we overwrote uniqueName.
  171. assert parser["metadata"]["type"] == "quality_changes"
  172. assert parser["metadata"]["quality_type"] == "normal"
  173. assert parser["metadata"]["position"] == "0"
  174. assert parser["metadata"]["setting_version"] == "5" # Yes, before we upgraded.