diff --git a/test/test_soi.py b/test/test_soi.py index 29f73a85c083e0b003005f7ec4f66d68da12b13a..89fb7c9d3d6d377d963d143a38df52fd69850085 100644 --- a/test/test_soi.py +++ b/test/test_soi.py @@ -3,6 +3,7 @@ To view the SOI during manual testing the following snippet is useful: ```python +from soitool.inline_editable_soi_view import InlineEditableSOIView self.soi.reorganize() view = InlineEditableSOIView(self.soi) view.show() @@ -91,11 +92,16 @@ class TestSOI(unittest.TestCase): """TestCase for the SOI class.""" def setUp(self): - """Prepare SOI to test on.""" + """Prepare SOI to test on. + + Note that the SOI can be modified by individual tests before use, this + simply sets the default. + """ self.soi = SOI( - modules=TEST_MODULES, - attachments=TEST_MODULES, + modules=list(TEST_MODULES), + attachments=list(TEST_MODULES), algorithm_sort="none", + placement_strategy="auto", ) def sort_modules_and_assert_order(self, sorting_algorithm, expected_order): @@ -165,15 +171,15 @@ class TestSOI(unittest.TestCase): module_too_wide = { "widget": TestModule("red", maximum_width + 1, 100), - "meta": {"x": 0, "y": 0, "page": 1, "name": "tall_module"}, + "meta": {"x": 0, "y": 0, "page": 1, "name": "too_wide"}, } module_too_tall = { "widget": TestModule("red", 100, maximum_height + 1), - "meta": {"x": 0, "y": 0, "page": 1, "name": "tall_module"}, + "meta": {"x": 0, "y": 0, "page": 1, "name": "too_tall"}, } module_maximum_size = { "widget": TestModule("red", maximum_width, maximum_height), - "meta": {"x": 0, "y": 0, "page": 1, "name": "tall_module"}, + "meta": {"x": 0, "y": 0, "page": 1, "name": "maximum_size"}, } # too wide module should raise exception @@ -197,3 +203,89 @@ class TestSOI(unittest.TestCase): "ModuleLargerThanBinError was raised even though module was " "not too large" ) + + def test_packing(self): + """Test that 4 test modules are packed as we expect them to be. + + Only the algorithms "MaxRectsBl" and "GuillotineBssfSas" are tested. + This is becaues if these two work, we can assume other choices of + algorithm will work as well. The modules in the SOI have been chosen + such that these two algorithms should yield different packings. + + This test was constructed by first running the algorithms on our + modules and inspecting the resulting packing, and then this packing is + used for testing. This way if reorganize gives a different packing in + the future this test should break. It is required that reorganize + yields the same packing given the same input. + + Note that this test does not check the actual module widget positions, + only the meta positions. + """ + # append module of maximum size + maximum_width = self.soi.CONTENT_WIDTH + maximum_height = self.soi.CONTENT_HEIGHT - self.soi.HEADER_HEIGHT + module_maximum_size = { + "widget": TestModule("red", maximum_width, maximum_height), + "meta": {"x": 0, "y": 0, "page": 1, "name": "maximum_size"}, + } + self.soi.modules.append(module_maximum_size) + + # store modules so we can use the exact same input for both algorithms + input_modules = self.soi.modules + + # test packing with Guillotine algorithm + expected_module_packing_metadata_guillotinebssfsas = [ + {"x": 0, "y": 0, "page": 1, "name": "tall_module"}, + {"x": 100, "y": 0, "page": 1, "name": "wide_module"}, + {"x": 100, "y": 100, "page": 1, "name": "big_module"}, + {"x": 0, "y": 0, "page": 2, "name": "maximum_size"}, + ] + self.soi.algorithm_pack = "GuillotineBssfSas" + self.soi.reorganize() + self.assertEqual( + expected_module_packing_metadata_guillotinebssfsas, + [module["meta"] for module in self.soi.modules], + ) + + # restore modules and test packing with MaxRects + self.soi.modules = input_modules + expected_module_packing_metadata_maxrectsbl = [ + {"x": 0, "y": 0, "page": 1, "name": "tall_module"}, + {"x": 100, "y": 0, "page": 1, "name": "wide_module"}, + {"x": 500, "y": 0, "page": 1, "name": "big_module"}, + {"x": 0, "y": 0, "page": 2, "name": "maximum_size"}, + ] + self.soi.algorithm_pack = "MaxRectsBl" + self.soi.reorganize() + self.assertEqual( + expected_module_packing_metadata_maxrectsbl, + [module["meta"] for module in self.soi.modules], + ) + + def test_module_widget_update_position(self): + """Test update of real widget position to match meta position.""" + page_2_module = { + "widget": TestModule("red", 100, 100), + "meta": {"x": 100, "y": 100, "page": 2, "name": "maximum_size"}, + } + + self.soi.modules = [page_2_module] + + # using [0] below because we're guaranteed there is only one + # module, and it's the one we want to test + + self.soi.update_module_widget_position(self.soi.modules[0]) + + # calculate expected widget positions + expected_x = page_2_module["meta"]["x"] + self.soi.PADDING + expected_y = ( + page_2_module["meta"]["y"] + self.soi.PADDING * 3 + self.soi.HEIGHT + ) + + self.assertEqual( + expected_x, self.soi.modules[0]["widget"].pos().x(), + ) + + self.assertEqual( + expected_y, self.soi.modules[0]["widget"].pos().y(), + )