Repository: MyreMylar/pygame_gui
Pull request #280 (2022-07-18 19:45:28)

Fixes & tests to improve coverage & resolve bugs related to untested code
Testing coverage was dropping a bit over recent release so I thought I'd exert some effort to improve it as it usually turns up a few bugs.


Patch:
diff --git a/pygame_gui/elements/ui_vertical_scroll_bar.py b/pygame_gui/elements/ui_vertical_scroll_bar.py
index 1af8d04..cffcf30 100644
--- a/pygame_gui/elements/ui_vertical_scroll_bar.py
+++ b/pygame_gui/elements/ui_vertical_scroll_bar.py
@@ -346,24 +346,8 @@ class UIVerticalScrollBar(UIElement):
         y_pos = (self.scroll_position + self.arrow_button_height)
         self.sliding_rect_position = pygame.math.Vector2(x_pos, y_pos)
 
-        if self.sliding_button is None:
-            self.sliding_button = UIButton(pygame.Rect(int(x_pos),
-                                                       int(y_pos),
-                                                       self.background_rect.width,
-                                                       scroll_bar_height),
-                                           '', self.ui_manager,
-                                           container=self.button_container,
-                                           starting_height=1,
-                                           parent_element=self,
-                                           object_id="#sliding_button",
-                                           anchors={'left': 'left',
-                                                    'right': 'right',
-                                                    'top': 'top',
-                                                    'bottom': 'top'})
-            self.join_focus_sets(self.sliding_button)
-        else:
-            self.sliding_button.set_relative_position(self.sliding_rect_position)
-            self.sliding_button.set_dimensions((self.background_rect.width, scroll_bar_height))
+        self.sliding_button.set_relative_position(self.sliding_rect_position)
+        self.sliding_button.set_dimensions((self.background_rect.width, scroll_bar_height))
         self.sliding_button.set_hold_range((100, self.background_rect.height))
 
     def set_visible_percentage(self, percentage: float):
diff --git a/pygame_gui/windows/ui_colour_picker_dialog.py b/pygame_gui/windows/ui_colour_picker_dialog.py
index c1898be..dfeb504 100644
--- a/pygame_gui/windows/ui_colour_picker_dialog.py
+++ b/pygame_gui/windows/ui_colour_picker_dialog.py
@@ -153,13 +153,8 @@ class UIColourChannelEditor(UIElement):
                 self._set_value_from_entry(int_value)
 
         if event.type == UI_HORIZONTAL_SLIDER_MOVED and event.ui_element == self.slider:
-            int_value = self.current_value
-            try:
-                int_value = int(self.slider.get_current_value())
-            except ValueError:
-                int_value = 0
-            finally:
-                self._set_value_from_slider(int_value)
+            # slider get current value can only return an int or a float so safe to assume cast works
+            self._set_value_from_slider(int(self.slider.get_current_value()))
 
         return consumed_event
 
diff --git a/pygame_gui/windows/ui_file_dialog.py b/pygame_gui/windows/ui_file_dialog.py
index a519e67..88dfef5 100644
--- a/pygame_gui/windows/ui_file_dialog.py
+++ b/pygame_gui/windows/ui_file_dialog.py
@@ -76,6 +76,8 @@ class UIFileDialog(UIWindow):
                 self.current_directory_path = str(pathed_initial_file_path.parent.resolve())
                 self.current_file_path = (Path(initial_file_path).parent.resolve() /
                                           Path(initial_file_path).name)
+            else:
+                self.current_directory_path = str(Path('.').resolve())
         else:
             self.current_directory_path = str(Path('.').resolve())
 


Test patch:
diff --git a/tests/test_core/test_layered_gui_group.py b/tests/test_core/test_layered_gui_group.py
new file mode 100644
index 0000000..658196e
--- /dev/null
+++ b/tests/test_core/test_layered_gui_group.py
@@ -0,0 +1,91 @@
+import pytest
+import pygame
+
+from pygame_gui.core.layered_gui_group import GUISprite, LayeredGUIGroup
+
+
+class MyProperSprite(GUISprite):
+    def __init__(self, *groups):
+        super().__init__(*groups)
+        self.blendmode = 0
+        self.visible = 1
+
+    def update(self, time_delta: float):
+        pass
+
+
+class MyDodgySprite1(pygame.sprite.Sprite):
+    def __init__(self, *groups):
+        super().__init__(*groups)
+
+    def update(self, time_delta: float):
+        pass
+
+
+class MyDodgySprite2(pygame.sprite.Sprite):
+    def __init__(self, *groups):
+        super().__init__(*groups)
+        self.visible = 1
+
+    def update(self, time_delta: float):
+        pass
+
+
+class MyDodgySprite3(pygame.sprite.Sprite):
+    def __init__(self, *groups):
+        super().__init__(*groups)
+        self.blendmode = 0
+        self.visible = 1
+
+
+class TestUIElement:
+    def test_remove_sprite_from_group(self, _init_pygame, default_ui_manager):
+
+        group = LayeredGUIGroup()
+
+        proper_sprite = MyProperSprite(group)
+
+        proper_sprite.remove(group)
+
+        assert len(group.sprites()) == 0
+
+    def test_add_dodgy_sprites(self, _init_pygame, default_ui_manager):
+        group = LayeredGUIGroup()
+
+        with pytest.raises(AttributeError):
+            MyDodgySprite1(group)
+
+        with pytest.raises(AttributeError):
+            MyDodgySprite2(group)
+
+        with pytest.raises(AttributeError):
+            MyDodgySprite3(group)
+
+    def test_sprite_set_layer_before_add(self, _init_pygame, default_ui_manager):
+        group = LayeredGUIGroup()
+
+        sprite1 = MyProperSprite()
+        sprite1.layer = 2
+
+        sprite2 = MyProperSprite()
+        sprite2.layer = 0
+
+        sprite3 = MyProperSprite()
+        sprite3.layer = 1
+
+        sprite1.add(group)
+        sprite2.add(group)
+        sprite3.add(group)
+
+        assert len(group.layers()) == 3 and group.layers() == [0, 1, 2]
+
+    def test_print_sprite(self, _init_pygame, default_ui_manager):
+        group = LayeredGUIGroup()
+
+        sprite1 = MyProperSprite()
+
+        print(sprite1)
+
+
+if __name__ == '__main__':
+    pytest.console_main()
\ No newline at end of file
diff --git a/tests/test_elements/test_ui_drop_down_menu.py b/tests/test_elements/test_ui_drop_down_menu.py
index 24915d1..2f9eb79 100644
--- a/tests/test_elements/test_ui_drop_down_menu.py
+++ b/tests/test_elements/test_ui_drop_down_menu.py
@@ -10,16 +10,6 @@ from pygame_gui.elements.ui_drop_down_menu import UIDropDownMenu
 from pygame_gui.core.ui_container import UIContainer
 from pygame_gui import PackageResource
 
-try:
-    # mouse button constants not defined in pygame 1.9.3
-    pygame.BUTTON_LEFT
-    pygame.BUTTON_MIDDLE
-    pygame.BUTTON_RIGHT
-except AttributeError:
-    pygame.BUTTON_LEFT = 1
-    pygame.BUTTON_MIDDLE = 2
-    pygame.BUTTON_RIGHT = 3
-
 
 class TestUIDropDownMenu:
 
diff --git a/tests/test_elements/test_ui_image.py b/tests/test_elements/test_ui_image.py
index a51fb82..de6f1cb 100644
--- a/tests/test_elements/test_ui_image.py
+++ b/tests/test_elements/test_ui_image.py
@@ -6,6 +6,7 @@ from tests.shared_comparators import compare_surfaces
 
 from pygame_gui.ui_manager import UIManager
 from pygame_gui.elements.ui_image import UIImage
+from pygame_gui.elements.ui_scrolling_container import UIScrollingContainer
 
 
 class TestUIImage:
@@ -50,6 +51,24 @@ class TestUIImage:
 
         assert ui_image.image.get_size() == (200, 200) and ui_image.rect.size == (200, 200)
 
+        container = UIScrollingContainer(pygame.Rect(100, 100, 200, 200),
+                                         manager=default_ui_manager)
+
+        ui_image = UIImage(relative_rect=pygame.Rect(10, 10, 128, 128),
+                           image_surface=loaded_image,
+                           manager=default_ui_manager,
+                           container=container)
+
+        ui_image.set_dimensions((50, 50))
+        ui_image.set_dimensions((128, 128))
+
+        container.set_dimensions((50, 50))
+        ui_image.set_dimensions((35, 35))
+        container.set_dimensions((300, 300))
+        ui_image.set_dimensions((128, 128))
+
+        assert ui_image.image.get_size() == (128, 128) and ui_image.rect.size == (128, 128)
+
     def test_show(self, _init_pygame, default_ui_manager, _display_surface_return_none):
         loaded_image = pygame.image.load(os.path.join('tests', 'data', 'images', 'splat.png'))
         ui_image = UIImage(relative_rect=pygame.Rect(100, 100, 150, 30),
diff --git a/tests/test_elements/test_ui_panel.py b/tests/test_elements/test_ui_panel.py
index 72ec5b2..5922b95 100644
--- a/tests/test_elements/test_ui_panel.py
+++ b/tests/test_elements/test_ui_panel.py
@@ -10,16 +10,6 @@ from pygame_gui.elements.ui_panel import UIPanel
 from pygame_gui.elements.ui_button import UIButton
 from pygame_gui.ui_manager import UIManager
 
-try:
-    # mouse button constants not defined in pygame 1.9.3
-    pygame.BUTTON_LEFT
-    pygame.BUTTON_MIDDLE
-    pygame.BUTTON_RIGHT
-except AttributeError:
-    pygame.BUTTON_LEFT = 1
-    pygame.BUTTON_MIDDLE = 2
-    pygame.BUTTON_RIGHT = 3
-
 
 class TestUIPanel:
 
diff --git a/tests/test_elements/test_ui_scrolling_container.py b/tests/test_elements/test_ui_scrolling_container.py
index 77b0353..6c63f1e 100644
--- a/tests/test_elements/test_ui_scrolling_container.py
+++ b/tests/test_elements/test_ui_scrolling_container.py
@@ -75,6 +75,16 @@ class TestUIScrollingContainer:
 
         assert container.rect.size == (50, 50)
 
+        container.set_scrollable_area_dimensions((500, 600))
+
+        container.set_dimensions((400, 500))
+
+        assert container.rect.size == (400, 500)
+
+        container.set_dimensions((500, 600))
+
+        assert container.rect.size == (500, 600)
+
     def test_kill(self, _init_pygame, default_ui_manager,
                   _display_surface_return_none):
         container = UIScrollingContainer(pygame.Rect(100, 100, 200, 200),
@@ -119,6 +129,14 @@ class TestUIScrollingContainer:
 
         assert container.get_container().relative_rect.x == -18
 
+        container.vert_scroll_bar.scroll_wheel_moved = True
+        container.vert_scroll_bar.scroll_wheel_amount = -1.0
+        container.vert_scroll_bar.update(0.02)
+
+        container.update(0.02)
+
+        assert container.get_container().relative_rect.y == -67
+
     def test_disable(self, _init_pygame: None, default_ui_manager: UIManager,
                      _display_surface_return_none: None):
         container = UIScrollingContainer(pygame.Rect(100, 100, 200, 200),
diff --git a/tests/test_elements/test_ui_text_entry_line.py b/tests/test_elements/test_ui_text_entry_line.py
index d67e3de..3dd150b 100644
--- a/tests/test_elements/test_ui_text_entry_line.py
+++ b/tests/test_elements/test_ui_text_entry_line.py
@@ -10,16 +10,6 @@ from pygame_gui.core.ui_container import UIContainer
 
 from pygame_gui.core.utility import clipboard_paste, clipboard_copy
 
-try:
-    # mouse button constants not defined in pygame 1.9.3
-    pygame.BUTTON_LEFT
-    pygame.BUTTON_MIDDLE
-    pygame.BUTTON_RIGHT
-except AttributeError:
-    pygame.BUTTON_LEFT = 1
-    pygame.BUTTON_MIDDLE = 2
-    pygame.BUTTON_RIGHT = 3
-
 
 class TestUITextEntryLine:
 
diff --git a/tests/test_elements/test_ui_vertical_scroll_bar.py b/tests/test_elements/test_ui_vertical_scroll_bar.py
index 63382df..1828162 100644
--- a/tests/test_elements/test_ui_vertical_scroll_bar.py
+++ b/tests/test_elements/test_ui_vertical_scroll_bar.py
@@ -32,6 +32,11 @@ class TestUIVerticalScrollBar:
         scroll_bar.rebuild()
         assert scroll_bar.image is not None
 
+        scroll_bar.enable_arrow_buttons = False
+
+        scroll_bar.rebuild()
+        assert scroll_bar.image is not None
+
     def test_check_has_moved_recently(self, _init_pygame, default_ui_manager,
                                       _display_surface_return_none):
         scroll_bar = UIVerticalScrollBar(relative_rect=pygame.Rect(100, 100, 30, 150),
diff --git a/tests/test_elements/test_ui_window.py b/tests/test_elements/test_ui_window.py
index 7a716ed..c7dfe80 100644
--- a/tests/test_elements/test_ui_window.py
+++ b/tests/test_elements/test_ui_window.py
@@ -12,16 +12,6 @@ from pygame_gui import UIManager
 
 from pygame_gui.elements.ui_drop_down_menu import UIDropDownMenu
 
-try:
-    # mouse button constants not defined in pygame 1.9.3
-    pygame.BUTTON_LEFT
-    pygame.BUTTON_MIDDLE
-    pygame.BUTTON_RIGHT
-except AttributeError:
-    pygame.BUTTON_LEFT = 1
-    pygame.BUTTON_MIDDLE = 2
-    pygame.BUTTON_RIGHT = 3
-
 
 class TestUIWindow:
     def test_creation(self, _init_pygame, default_ui_manager,
diff --git a/tests/test_ui_manager.py b/tests/test_ui_manager.py
index df1ac93..038ef86 100644
--- a/tests/test_ui_manager.py
+++ b/tests/test_ui_manager.py
@@ -317,26 +317,15 @@ class TestUIManager:
         assert button1.hovered is True
         assert button2.hovered is False
 
-    def test_old_events_warn(self, _init_pygame, _display_surface_return_none):
+    def test_set_visual_debug(self, _init_pygame, _display_surface_return_none):
         manager = UIManager((800, 600))
-        button = UIButton(relative_rect=pygame.Rect(10, 10, 150, 30),
-                          text="Test Button",
-                          manager=manager,
-                          allow_double_clicks=True)
-
-        button.process_event(pygame.event.Event(pygame.MOUSEBUTTONDOWN,
-                                                                   {'button': pygame.BUTTON_LEFT,
-                                                                    'pos': button.rect.center}))
-
-        button.process_event(pygame.event.Event(pygame.MOUSEBUTTONUP,
-                                                                   {'button': pygame.BUTTON_LEFT,
-                                                                    'pos': button.rect.center}))
-
-        with pytest.warns(DeprecationWarning, match="Pygame GUI event types can now"):
-            for event in pygame.event.get():
-                if (event.type == pygame.USEREVENT and
-                        event.user_type == UI_BUTTON_PRESSED and event.ui_element == button):
-                    assert isinstance(event.user_type, OldType)
+        manager.set_visual_debug_mode(True)
+
+        assert manager.visual_debug_active is True
+
+        manager.set_visual_debug_mode(False)
+
+        assert manager.visual_debug_active is False
 
 
 if __name__ == '__main__':
diff --git a/tests/test_windows/test_ui_colour_picker_dialog.py b/tests/test_windows/test_ui_colour_picker_dialog.py
index 5057259..d277cb0 100644
--- a/tests/test_windows/test_ui_colour_picker_dialog.py
+++ b/tests/test_windows/test_ui_colour_picker_dialog.py
@@ -9,16 +9,6 @@ from pygame_gui.windows import UIColourPickerDialog
 from pygame_gui.windows.ui_colour_picker_dialog import UIColourChannelEditor
 from pygame_gui.core.utility import restore_premul_col
 
-try:
-    # mouse button constants not defined in pygame 1.9.3
-    pygame.BUTTON_LEFT
-    pygame.BUTTON_MIDDLE
-    pygame.BUTTON_RIGHT
-except AttributeError:
-    pygame.BUTTON_LEFT = 1
-    pygame.BUTTON_MIDDLE = 2
-    pygame.BUTTON_RIGHT = 3
-
 
 class TestUIColourChannelEditor:
     def test_creation(self, _init_pygame, default_ui_manager, _display_surface_return_none):
@@ -55,8 +45,26 @@ class TestUIColourChannelEditor:
         for event in pygame.event.get():
             default_ui_manager.process_events(event)
 
+        for event in pygame.event.get():
+            default_ui_manager.process_events(event)
+
         assert channel_editor.slider.current_value == 50
 
+        with pytest.warns(UserWarning, match="Tried to set text string with "
+                                             "invalid characters on text entry element"):
+            channel_editor.entry.set_text('dog')
+
+        channel_editor.entry.text = 'dog'
+        channel_editor.entry.is_focused = True
+        channel_editor.entry.text_entered = False
+
+        channel_editor.entry.process_event(pygame.event.Event(pygame.KEYDOWN, {'key': pygame.K_RETURN}))
+
+        for event in pygame.event.get():
+            default_ui_manager.process_events(event)
+
+        assert channel_editor.slider.current_value == 0
+
     def test_slider_moved_finished(self, _init_pygame, default_ui_manager,
                                    _display_surface_return_none):
         channel_editor = UIColourChannelEditor(relative_rect=pygame.Rect(0, 0, 150, 29),
diff --git a/tests/test_windows/test_ui_confirmation_dialog.py b/tests/test_windows/test_ui_confirmation_dialog.py
index 43d1020..514a28b 100644
--- a/tests/test_windows/test_ui_confirmation_dialog.py
+++ b/tests/test_windows/test_ui_confirmation_dialog.py
@@ -8,16 +8,6 @@ from tests.shared_comparators import compare_surfaces
 from pygame_gui.ui_manager import UIManager
 from pygame_gui.windows import UIConfirmationDialog
 
-try:
-    # mouse button constants not defined in pygame 1.9.3
-    pygame.BUTTON_LEFT
-    pygame.BUTTON_MIDDLE
-    pygame.BUTTON_RIGHT
-except AttributeError:
-    pygame.BUTTON_LEFT = 1
-    pygame.BUTTON_MIDDLE = 2
-    pygame.BUTTON_RIGHT = 3
-
 
 class TestUIConfirmationDialog:
 
diff --git a/tests/test_windows/test_ui_console_window.py b/tests/test_windows/test_ui_console_window.py
index 8d94e58..986d067 100644
--- a/tests/test_windows/test_ui_console_window.py
+++ b/tests/test_windows/test_ui_console_window.py
@@ -7,16 +7,6 @@ from tests.shared_comparators import compare_surfaces
 from pygame_gui.ui_manager import UIManager
 from pygame_gui.windows.ui_console_window import UIConsoleWindow
 
-try:
-    # mouse button constants not defined in pygame 1.9.3
-    pygame.BUTTON_LEFT
-    pygame.BUTTON_MIDDLE
-    pygame.BUTTON_RIGHT
-except AttributeError:
-    pygame.BUTTON_LEFT = 1
-    pygame.BUTTON_MIDDLE = 2
-    pygame.BUTTON_RIGHT = 3
-
 
 class TestUIConsoleWindow:
     def test_creation(self, _init_pygame, default_ui_manager,
diff --git a/tests/test_windows/test_ui_file_dialog.py b/tests/test_windows/test_ui_file_dialog.py
index 474f1af..e90305c 100644
--- a/tests/test_windows/test_ui_file_dialog.py
+++ b/tests/test_windows/test_ui_file_dialog.py
@@ -8,16 +8,6 @@ from tests.shared_comparators import compare_surfaces
 
 from pygame_gui.windows import UIFileDialog
 
-try:
-    # mouse button constants not defined in pygame 1.9.3
-    pygame.BUTTON_LEFT
-    pygame.BUTTON_MIDDLE
-    pygame.BUTTON_RIGHT
-except AttributeError:
-    pygame.BUTTON_LEFT = 1
-    pygame.BUTTON_MIDDLE = 2
-    pygame.BUTTON_RIGHT = 3
-
 
 class TestUIUIFileDialog:
 
@@ -32,6 +22,26 @@ class TestUIUIFileDialog:
             UIFileDialog(rect=pygame.Rect(100, 100, 50, 50),
                          manager=default_ui_manager)
 
+    def test_create_options(self, _init_pygame, default_ui_manager,
+                            _display_surface_return_none):
+        UIFileDialog(rect=pygame.Rect(100, 100, 440, 500),
+                     manager=default_ui_manager, allow_existing_files_only=True)
+
+        UIFileDialog(rect=pygame.Rect(100, 100, 440, 500),
+                     manager=default_ui_manager, allow_picking_directories=True)
+
+        UIFileDialog(rect=pygame.Rect(100, 100, 440, 500),
+                     manager=default_ui_manager, initial_file_path='tests/data/images')
+
+        UIFileDialog(rect=pygame.Rect(100, 100, 440, 500),
+                     manager=default_ui_manager, initial_file_path='tests/data/images/splat.png')
+
+        UIFileDialog(rect=pygame.Rect(100, 100, 440, 500),
+                     manager=default_ui_manager, initial_file_path='tests/data/images/splot.png')
+
+        UIFileDialog(rect=pygame.Rect(100, 100, 440, 500),
+                     manager=default_ui_manager, initial_file_path='nonsense/path/that/does/not/exist')
+
     def test_update_current_file_list(self, _init_pygame, default_ui_manager,
                                       _display_surface_return_none):
         file_dialog = UIFileDialog(rect=pygame.Rect(100, 100, 440, 500),
diff --git a/tests/test_windows/test_ui_message_window.py b/tests/test_windows/test_ui_message_window.py
index ef4e2aa..b19d55c 100644
--- a/tests/test_windows/test_ui_message_window.py
+++ b/tests/test_windows/test_ui_message_window.py
@@ -7,15 +7,6 @@ from tests.shared_comparators import compare_surfaces
 from pygame_gui.ui_manager import UIManager
 from pygame_gui.windows.ui_message_window import UIMessageWindow
 
-try:
-    # mouse button constants not defined in pygame 1.9.3
-    pygame.BUTTON_LEFT
-    pygame.BUTTON_MIDDLE
-    pygame.BUTTON_RIGHT
-except AttributeError:
-    pygame.BUTTON_LEFT = 1
-    pygame.BUTTON_MIDDLE = 2
-    pygame.BUTTON_RIGHT = 3
 
 
 class TestUIMessageWindow: