Skip to content

Commit e19d8f5

Browse files
committed
Add a CI run for Qt5 and cleanup CI runs
1 parent 675d8c8 commit e19d8f5

File tree

9 files changed

+124
-80
lines changed

9 files changed

+124
-80
lines changed

.github/workflows/qt5-tests.yml

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
name: Run Qt5 tests
2+
3+
on:
4+
push:
5+
branches: [main]
6+
pull_request:
7+
branches: [main]
8+
9+
jobs:
10+
test:
11+
runs-on: ubuntu-22.04
12+
13+
steps:
14+
- name: Checkout repo
15+
uses: actions/checkout@v3
16+
17+
- name: Install dependencies
18+
run: |
19+
sudo apt-get update
20+
sudo apt-get install -y \
21+
qtbase5-dev \
22+
qtbase5-dev-tools \
23+
python3-pyside2.* \
24+
libegl1 \
25+
libglib2.0-0 \
26+
libx11-xcb1 \
27+
libxrender1 \
28+
libxkbcommon-x11-0 \
29+
libxcb-icccm4 \
30+
libxcb-image0 \
31+
libxcb-keysyms1 \
32+
libxcb-randr0 \
33+
libxcb-render-util0 \
34+
libxcb-xinerama0 \
35+
libxcb-xkb1 \
36+
xvfb
37+
38+
- name: Install Python dependencies
39+
run: |
40+
python -m pip install --upgrade pip
41+
pip install vermin || true
42+
43+
- name: Run App tests
44+
run: |
45+
python AddonManagerTest/run_app_tests.py
46+
47+
- name: Run GUI tests
48+
run: |
49+
xvfb-run -s "-screen 0 1920x1080x24" python3 AddonManagerTest/run_gui_tests.py

.github/workflows/app-tests.yml renamed to .github/workflows/qt6-tests.yml

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
name: Run app tests
1+
name: Run Qt6 tests
22

33
on:
44
push:
@@ -23,7 +23,7 @@ jobs:
2323
with:
2424
python-version: ${{ matrix.python-version }}
2525

26-
- name: Install Qt dependencies
26+
- name: Install dependencies
2727
run: |
2828
sudo apt-get update
2929
sudo apt-get install -y \
@@ -32,16 +32,30 @@ jobs:
3232
libx11-xcb1 \
3333
libxrender1 \
3434
libxkbcommon-x11-0 \
35+
libxcb-cursor0 \
3536
libxcb-icccm4 \
3637
libxcb-image0 \
3738
libxcb-keysyms1 \
3839
libxcb-randr0 \
3940
libxcb-render-util0 \
41+
libxcb-shape0 \
4042
libxcb-xinerama0 \
4143
libxcb-xkb1 \
42-
libopengl0
44+
libopengl0 \
45+
libxcomposite1 \
46+
libxdamage1 \
47+
libxi6 \
48+
libxtst6 \
49+
libnss3 \
50+
libxss1 \
51+
libdbus-1-3 \
52+
libatk1.0-0 \
53+
libatk-bridge2.0-0 \
54+
libxrandr2 \
55+
libgtk-3-0 \
56+
xvfb
4357
44-
- name: Install dependencies
58+
- name: Install Python dependencies
4559
run: |
4660
python -m pip install --upgrade pip
4761
pip install -r requirements.txt || true
@@ -51,5 +65,8 @@ jobs:
5165
python AddonManagerTest/run_app_tests.py
5266
5367
- name: Run GUI tests
68+
env:
69+
QT_QPA_PLATFORM: xcb
70+
QT_DEBUG_PLUGINS: 1
5471
run: |
55-
python AddonManagerTest/run_gui_tests.py
72+
xvfb-run -s "-screen 0 1920x1080x24" python3 AddonManagerTest/run_gui_tests.py

AddonManagerTest/gui/test_gui.py

Lines changed: 0 additions & 33 deletions
This file was deleted.

AddonManagerTest/gui/test_python_deps_gui.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ def test_call_pip(self, mock_run_subprocess: MagicMock):
5656
args = mock_run_subprocess.call_args[0][0]
5757
self.assertTrue("pip" in args)
5858

59-
@patch("addonmanager_python_deps_gui.get_python_exe")
59+
@patch("addonmanager_python_deps_gui.utils.fci.get_python_exe")
6060
def test_call_pip_no_python(self, mock_get_python_exe: MagicMock):
6161
mock_get_python_exe.return_value = None
6262
with self.assertRaises(PipFailed):

AddonManagerTest/gui/test_toolbar_adapter.py

Lines changed: 35 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -12,83 +12,83 @@ def test_toolbar_adapter_outside_freecad(self):
1212
with self.assertRaises(RuntimeError):
1313
ToolbarAdapter()
1414

15-
@patch("addonmanager_toolbar_adapter.fci.ParamGet")
15+
@patch("addonmanager_toolbar_adapter.fci.FreeCAD")
1616
def test_toolbar_adapter_inside_freecad(self, _):
1717
"""When run inside FreeCAD, this class should instantiate correctly"""
1818
ToolbarAdapter()
1919

20-
@patch("addonmanager_toolbar_adapter.fci.ParamGet")
21-
def test_get_toolbars(self, mock_param_get):
20+
@patch("addonmanager_toolbar_adapter.fci.FreeCAD")
21+
def test_get_toolbars(self, mock_freecad: MagicMock):
2222
"""Get a list of toolbars out of the FreeCAD preferences system"""
23-
mock_param_get().GetGroups = Mock(return_value=["A", "B", "C"])
24-
mock_param_get().GetGroup = Mock(
23+
mock_freecad.ParamGet().GetGroups = Mock(return_value=["A", "B", "C"])
24+
mock_freecad.ParamGet().GetGroup = Mock(
2525
side_effect=["Toolbar1", "Toolbar2", "Toolbar3", "Toolbar4"]
2626
)
2727
toolbars = ToolbarAdapter().get_toolbars()
2828
self.assertEqual(["Toolbar1", "Toolbar2", "Toolbar3"], toolbars)
2929

30-
@patch("addonmanager_toolbar_adapter.fci.ParamGet")
31-
def test_get_toolbar_with_name_good(self, mock_param_get):
30+
@patch("addonmanager_toolbar_adapter.fci.FreeCAD")
31+
def test_get_toolbar_with_name_good(self, mock_freecad: MagicMock):
3232
"""Find a specific toolbar with a given name"""
33-
mock_param_get().GetGroups = Mock(return_value=["A", "B", "C"])
34-
mock_param_get().GetGroup = MagicMock()
35-
mock_param_get().GetGroup().GetString = MagicMock(
33+
mock_freecad.ParamGet().GetGroups = Mock(return_value=["A", "B", "C"])
34+
mock_freecad.ParamGet().GetGroup = MagicMock()
35+
mock_freecad.ParamGet().GetGroup().GetString = MagicMock(
3636
side_effect=["Toolbar1", "Toolbar2", "Toolbar3"]
3737
)
3838
toolbars = ToolbarAdapter().get_toolbar_with_name("Toolbar2")
3939
self.assertIsNotNone(toolbars)
4040

41-
@patch("addonmanager_toolbar_adapter.fci.ParamGet")
42-
def test_get_toolbar_with_name_no_match(self, mock_param_get):
41+
@patch("addonmanager_toolbar_adapter.fci.FreeCAD")
42+
def test_get_toolbar_with_name_no_match(self, mock_freecad: MagicMock):
4343
"""Don't find a toolbar that doesn't match the name"""
44-
mock_param_get().GetGroups = Mock(return_value=["A", "B", "C"])
45-
mock_param_get().GetGroup = MagicMock()
46-
mock_param_get().GetGroup().GetString = MagicMock(
44+
mock_freecad.ParamGet().GetGroups = Mock(return_value=["A", "B", "C"])
45+
mock_freecad.ParamGet().GetGroup = MagicMock()
46+
mock_freecad.ParamGet().GetGroup().GetString = MagicMock(
4747
side_effect=["Toolbar1", "Toolbar2", "Toolbar3"]
4848
)
4949
toolbars = ToolbarAdapter().get_toolbar_with_name("Toolbar4")
5050
self.assertIsNone(toolbars)
5151

52-
@patch("addonmanager_toolbar_adapter.fci.ParamGet")
53-
def test_check_for_toolbar_with_match(self, mock_param_get):
54-
mock_param_get().GetGroups = Mock(return_value=["A", "B", "C"])
55-
mock_param_get().GetGroup = MagicMock()
56-
mock_param_get().GetGroup().GetString = MagicMock(
52+
@patch("addonmanager_toolbar_adapter.fci.FreeCAD")
53+
def test_check_for_toolbar_with_match(self, mock_freecad: MagicMock):
54+
mock_freecad.ParamGet().GetGroups = Mock(return_value=["A", "B", "C"])
55+
mock_freecad.ParamGet().GetGroup = MagicMock()
56+
mock_freecad.ParamGet().GetGroup().GetString = MagicMock(
5757
side_effect=["Toolbar1", "Toolbar2", "Toolbar3"]
5858
)
5959
self.assertTrue(ToolbarAdapter().check_for_toolbar("Toolbar2"))
6060

61-
@patch("addonmanager_toolbar_adapter.fci.ParamGet")
62-
def test_check_for_toolbar_without_match(self, mock_param_get):
63-
mock_param_get().GetGroups = Mock(return_value=["A", "B", "C"])
64-
mock_param_get().GetGroup = MagicMock()
65-
mock_param_get().GetGroup().GetString = MagicMock(
61+
@patch("addonmanager_toolbar_adapter.fci.FreeCAD")
62+
def test_check_for_toolbar_without_match(self, mock_freecad: MagicMock):
63+
mock_freecad.ParamGet().GetGroups = Mock(return_value=["A", "B", "C"])
64+
mock_freecad.ParamGet().GetGroup = MagicMock()
65+
mock_freecad.ParamGet().GetGroup().GetString = MagicMock(
6666
side_effect=["Toolbar1", "Toolbar2", "Toolbar3"]
6767
)
6868
self.assertFalse(ToolbarAdapter().check_for_toolbar("Toolbar4"))
6969

70-
@patch("addonmanager_toolbar_adapter.fci.ParamGet")
71-
def test_create_new_custom_toolbar_basic_name(self, mock_param_get):
70+
@patch("addonmanager_toolbar_adapter.fci.FreeCAD")
71+
def test_create_new_custom_toolbar_basic_name(self, mock_freecad: MagicMock):
7272
"""If no custom toolbar exists yet, then the new toolbar uses the most basic name form"""
7373
toolbar = ToolbarAdapter().create_new_custom_toolbar()
7474
toolbar.SetString.assert_called_with("Name", "Auto-Created Macro Toolbar")
75-
mock_param_get().GetGroup.assert_called_with("Custom_1")
75+
mock_freecad.ParamGet().GetGroup.assert_called_with("Custom_1")
7676

77-
@patch("addonmanager_toolbar_adapter.fci.ParamGet")
78-
def test_create_new_custom_toolbar_name_taken(self, mock_param_get):
77+
@patch("addonmanager_toolbar_adapter.fci.FreeCAD")
78+
def test_create_new_custom_toolbar_name_taken(self, mock_freecad: MagicMock):
7979
"""If no custom toolbar exists yet, then the new toolbar uses the most basic name form"""
8080
with patch(
8181
"addonmanager_toolbar_adapter.ToolbarAdapter.check_for_toolbar"
8282
) as mock_check_for_toolbar:
8383
mock_check_for_toolbar.side_effect = [True, True, False]
8484
toolbar = ToolbarAdapter().create_new_custom_toolbar()
8585
toolbar.SetString.assert_called_with("Name", "Auto-Created Macro Toolbar (3)")
86-
mock_param_get().GetGroup.assert_called_with("Custom_1")
86+
mock_freecad.ParamGet().GetGroup.assert_called_with("Custom_1")
8787

88-
@patch("addonmanager_toolbar_adapter.fci.ParamGet")
89-
def test_create_new_custom_toolbar_group_name_taken(self, mock_param_get):
88+
@patch("addonmanager_toolbar_adapter.fci.FreeCAD")
89+
def test_create_new_custom_toolbar_group_name_taken(self, mock_freecad: MagicMock):
9090
"""If no custom toolbar exists yet, then the new toolbar uses the most basic name form"""
91-
mock_param_get().GetGroups = Mock(return_value=["Custom_1", "Custom_2", "Custom_3"])
91+
mock_freecad.ParamGet().GetGroups = Mock(return_value=["Custom_1", "Custom_2", "Custom_3"])
9292
toolbar = ToolbarAdapter().create_new_custom_toolbar()
9393
toolbar.SetString.assert_called_with("Name", "Auto-Created Macro Toolbar")
94-
mock_param_get().GetGroup.assert_called_with("Custom_4")
94+
mock_freecad.ParamGet().GetGroup.assert_called_with("Custom_4")

AddonManagerTest/run_gui_tests.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,14 @@
1212
try:
1313
from PySide6 import QtCore, QtWidgets
1414
from PySide6.QtWidgets import QApplication, QWidget
15+
16+
pyside_version = 6
1517
except ImportError:
1618
from PySide2 import QtCore, QtWidgets
1719
from PySide2.QtWidgets import QApplication
1820

21+
pyside_version = 2
22+
1923
app = None
2024
if QApplication:
2125
# Ensure there is only one QApplication instance
@@ -49,5 +53,8 @@ def run_suite(runner: unittest.TextTestRunner, suite: unittest.TestSuite):
4953
s = loader.discover(start_dir="gui", pattern="test_*.py")
5054
r = unittest.TextTestRunner(verbosity=2)
5155
QtCore.QTimer.singleShot(0, lambda: run_suite(r, s))
52-
app.exec()
56+
if pyside_version == 6:
57+
app.exec()
58+
else:
59+
app.exec_()
5360
sys.exit(not suite_result)

CMakeLists.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,6 @@ SET(AddonManagerTestsApp_SRCS
189189
SET(AddonManagerTestsGui_SRCS
190190
AddonManagerTest/gui/__init__.py
191191
AddonManagerTest/gui/gui_mocks.py
192-
AddonManagerTest/gui/test_gui.py
193192
AddonManagerTest/gui/test_installer_gui.py
194193
AddonManagerTest/gui/test_python_deps_gui.py
195194
AddonManagerTest/gui/test_toolbar_adapter.py

TestAddonManagerGui.py

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,6 @@
2323

2424
import addonmanager_freecad_interface as fci
2525

26-
# Unit test for the Addon Manager module GUI
27-
from AddonManagerTest.gui.test_gui import TestGui as AddonManagerTestGui
28-
2926
from AddonManagerTest.gui.test_workers_utility import (
3027
TestWorkersUtility as AddonManagerTestWorkersUtility,
3128
)

main.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,18 @@
2525

2626
# Check if PySide6 is used
2727
QApplication = None
28+
pyside_version = 0
2829
try:
2930
from PySide6 import QtCore, QtWidgets
3031
from PySide6.QtWidgets import QApplication, QWidget
32+
33+
pyside_version = 6
3134
except ImportError:
3235
from PySide2 import QtCore, QtWidgets
3336
from PySide2.QtWidgets import QApplication, QWidget
3437

38+
pyside_version = 2
39+
3540
app = None
3641
if QApplication:
3742
# Ensure there is only one QApplication instance
@@ -64,4 +69,7 @@ def run_addon_manager():
6469
QtCore.QTimer.singleShot(0, run_addon_manager)
6570
app.setQuitOnLastWindowClosed(False)
6671
setup_translations()
67-
app.exec()
72+
if pyside_version == 6:
73+
app.exec()
74+
else:
75+
app.exec_()

0 commit comments

Comments
 (0)