Skip to content

Commit e9d002a

Browse files
committed
Test screenshots are now generated automatically (those integrated in test launcher)
1 parent 3459107 commit e9d002a

48 files changed

Lines changed: 1289 additions & 1022 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
### Version 0.7.0 ###
55

6-
- Added new test launcher
6+
- Added new test launcher with screenshots (automatically generated)
77
- QwtPlot: added "flatStyle" option, a PythonQwt-exclusive feature improving
88
default plot style (without margin, more compact and flat look) -- option is
99
enabled by default

qwt/tests/__init__.py

Lines changed: 99 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,25 @@
1616
import sys
1717
import subprocess
1818
import platform
19-
from qwt.qt.QtGui import (QWidget, QMainWindow, QVBoxLayout, QFormLayout,
20-
QCheckBox, QGroupBox, QGridLayout, QToolButton,
21-
QStyle, QToolBar, QAction, QIcon, QMessageBox)
22-
from qwt.qt.QtCore import Qt, QSize
19+
from qwt.qt.QtGui import (
20+
QApplication,
21+
QWidget,
22+
QMainWindow,
23+
QVBoxLayout,
24+
QFormLayout,
25+
QCheckBox,
26+
QGroupBox,
27+
QGridLayout,
28+
QToolButton,
29+
QStyle,
30+
QToolBar,
31+
QAction,
32+
QIcon,
33+
QMessageBox,
34+
QPixmap,
35+
)
36+
from qwt.qt.QtCore import Qt, QSize, QTimer
37+
from qwt.qt import PYQT5
2338
from qwt import QwtPlot
2439

2540

@@ -28,8 +43,8 @@
2843

2944
def run_test(fname, wait=False):
3045
"""Run test"""
31-
os.environ['PYTHONPATH'] = os.pathsep.join(sys.path)
32-
args = " ".join([sys.executable, '"'+fname+'"'])
46+
os.environ["PYTHONPATH"] = os.pathsep.join(sys.path)
47+
args = " ".join([sys.executable, '"' + fname + '"'])
3348
if os.environ.get("TEST_UNATTENDED") is not None:
3449
print(args)
3550
if wait:
@@ -40,35 +55,43 @@ def run_test(fname, wait=False):
4055

4156
def get_tests(package):
4257
"""Return list of test filenames"""
43-
test_package_name = '%s.tests' % package.__name__
58+
test_package_name = "%s.tests" % package.__name__
4459
_temp = __import__(test_package_name)
4560
test_package = sys.modules[test_package_name]
4661
tests = []
4762
test_path = osp.dirname(osp.realpath(test_package.__file__))
48-
for fname in sorted([name for name in os.listdir(test_path)
49-
if name.endswith(('.py', '.pyw')) and\
50-
not name.startswith('_')]):
63+
for fname in sorted(
64+
[
65+
name
66+
for name in os.listdir(test_path)
67+
if name.endswith((".py", ".pyw")) and not name.startswith("_")
68+
]
69+
):
5170
module_name = osp.splitext(fname)[0]
5271
_temp = __import__(test_package.__name__, fromlist=[module_name])
5372
module = getattr(_temp, module_name)
54-
if hasattr(module, 'SHOW') and module.SHOW:
73+
if hasattr(module, "SHOW") and module.SHOW:
5574
tests.append(osp.abspath(osp.join(test_path, fname)))
5675
return tests
5776

5877

5978
def run_all_tests(wait):
6079
"""Run all PythonQwt tests"""
6180
import qwt
81+
6282
for fname in get_tests(qwt):
6383
run_test(fname, wait=wait)
6484

6585

6686
class TestLauncher(QMainWindow):
6787
"""PythonQwt Test Launcher main window"""
88+
6889
ROWS = 5
90+
6991
def __init__(self, parent=None):
7092
super(TestLauncher, self).__init__(parent)
7193
from qwt import __version__
94+
7295
self.setWindowIcon(self.get_std_icon("FileDialogListView"))
7396
self.setWindowTitle("PythonQwt %s - Test Launcher" % __version__)
7497
self.setCentralWidget(QWidget())
@@ -86,6 +109,7 @@ def get_std_icon(self, name):
86109
def fill_layout(self):
87110
"""Fill grid layout"""
88111
import qwt
112+
89113
for fname in get_tests(qwt):
90114
self.add_test(fname)
91115
toolbar = QToolBar(self)
@@ -112,8 +136,8 @@ def add_test(self, fname):
112136
if self.test_nb is None:
113137
self.test_nb = 0
114138
self.test_nb += 1
115-
row = (self.test_nb-1) % self.ROWS
116-
column = (self.test_nb-1) // self.ROWS
139+
row = (self.test_nb - 1) % self.ROWS
140+
column = (self.test_nb - 1) // self.ROWS
117141
bname = osp.basename(fname)
118142
button = QToolButton(self)
119143
button.setToolButtonStyle(Qt.ToolButtonTextUnderIcon)
@@ -127,22 +151,31 @@ def add_test(self, fname):
127151
button.setIconSize(QSize(130, 80))
128152
button.clicked.connect(lambda checked, fname=fname: run_test(fname))
129153
self.grid_layout.addWidget(button, row, column)
130-
154+
131155
def about(self):
132156
"""About test launcher"""
133157
from qwt.qt.QtCore import __version__ as qt_version
134-
QMessageBox.about( self, "About "+self.windowTitle(),
135-
"""<b>%s</b><p>Developped by Pierre Raybaut
158+
159+
QMessageBox.about(
160+
self,
161+
"About " + self.windowTitle(),
162+
"""<b>%s</b><p>Developped by Pierre Raybaut
136163
<br>Copyright &copy; 2020 Pierre Raybaut
137-
<p>Python %s, Qt %s on %s""" % \
138-
(self.windowTitle(), platform.python_version(),
139-
qt_version, platform.system()) )
164+
<p>Python %s, Qt %s on %s"""
165+
% (
166+
self.windowTitle(),
167+
platform.python_version(),
168+
qt_version,
169+
platform.system(),
170+
),
171+
)
140172

141173

142174
def run(wait=True):
143175
"""Run PythonQwt tests or test launcher (requires `guidata`)"""
144176
if os.environ.get("TEST_UNATTENDED") is None:
145177
from qwt.qt.QtGui import QApplication
178+
146179
app = QApplication([])
147180
launcher = TestLauncher()
148181
launcher.show()
@@ -153,6 +186,7 @@ def run(wait=True):
153186

154187
class TestOptions(QGroupBox):
155188
"""Test options groupbox"""
189+
156190
def __init__(self, parent=None):
157191
super(TestOptions, self).__init__("Test options", parent)
158192
self.setLayout(QFormLayout())
@@ -169,68 +203,85 @@ def add_checkbox(self, title, label, slot):
169203

170204
class TestCentralWidget(QWidget):
171205
"""Test central widget"""
172-
def __init__(self, parent=None):
206+
207+
def __init__(self, widget_name, parent=None):
173208
super(TestCentralWidget, self).__init__(parent)
209+
self.widget_name = widget_name
210+
self.plots = None
174211
self.setLayout(QVBoxLayout())
175212
self.options = TestOptions(self)
176213
self.add_widget(self.options)
177214

215+
@property
216+
def widget_of_interest(self):
217+
"""Return widget of interest (screenshot)"""
218+
if len(self.plots) == 1:
219+
return self.plots[0]
220+
else:
221+
return self.parent()
222+
178223
def add_widget(self, widget):
179224
"""Add new sub-widget"""
180225
self.layout().addWidget(widget)
181226
if isinstance(widget, QwtPlot):
182-
plots = [widget]
227+
self.plots = [widget]
183228
else:
184-
plots = widget.findChildren(QwtPlot)
185-
for index, plot in enumerate(plots):
229+
self.plots = widget.findChildren(QwtPlot)
230+
for index, plot in enumerate(self.plots):
186231
plot_name = plot.objectName()
187232
if not plot_name:
188233
plot_name = "Plot #%d" % (index + 1)
189-
widget = self.options.add_checkbox(plot_name,
190-
"Enable new flat style option", plot.setFlatStyle)
234+
widget = self.options.add_checkbox(
235+
plot_name, "Enable new flat style option", plot.setFlatStyle
236+
)
191237
widget.setChecked(plot.flatStyle())
192238

193239

194-
class TestWindow(QMainWindow):
195-
"""Test main window"""
196-
def __init__(self):
197-
super(TestWindow, self).__init__()
198-
self.setCentralWidget(TestCentralWidget())
199-
200-
def add_widget(self, widget):
201-
"""Add new sub-widget to central widget"""
202-
self.centralWidget().add_widget(widget)
240+
def take_screenshot(widget):
241+
"""Take screenshot and save it to the data folder"""
242+
if PYQT5:
243+
pixmap = widget.grab()
244+
else:
245+
pixmap = QPixmap.grabWidget(widget)
246+
bname = (widget.objectName().lower() + ".png").replace("window", "")
247+
bname = bname.replace("plot", "").replace("widget", "")
248+
pixmap.save(osp.join(TEST_PATH, "data", bname))
249+
QTimer.singleShot(0, QApplication.instance().quit)
203250

204251

205-
def test_widget(widget_class, size=None, title=None, options=True):
252+
def test_widget(widget_class, size=None, title=None, options=True, timeout=1000):
206253
"""Test widget"""
207-
from qwt.qt.QtGui import QApplication
254+
widget_name = widget_class.__name__
208255
app = QApplication([])
209256
window = widget = widget_class()
210257
if options:
211258
if isinstance(widget, QMainWindow):
212-
original_central_widget = window.centralWidget()
213-
original_central_widget.setParent(None)
214-
new_central_widget = TestCentralWidget()
215-
window.setCentralWidget(new_central_widget)
216-
new_central_widget.add_widget(original_central_widget)
259+
widget = window.centralWidget()
260+
widget.setParent(None)
217261
else:
218-
window = TestWindow()
219-
window.add_widget(widget)
262+
window = QMainWindow()
263+
central_widget = TestCentralWidget(widget_name)
264+
central_widget.add_widget(widget)
265+
window.setCentralWidget(central_widget)
266+
widget_of_interest = central_widget.widget_of_interest
267+
else:
268+
widget_of_interest = window
269+
widget_of_interest.setObjectName(widget_name)
220270
if title is None:
221271
from qwt import __version__
222-
title = 'Test "%s" - PythonQwt %s' % (widget_class.__name__,
223-
__version__)
272+
273+
title = 'Test "%s" - PythonQwt %s' % (widget_name, __version__)
224274
window.setWindowTitle(title)
225275
if size is not None:
226276
width, height = size
227277
window.resize(width, height)
228278

229279
window.show()
230-
if os.environ.get("TEST_UNATTENDED") is None:
231-
app.exec_()
280+
if os.environ.get("TEST_UNATTENDED") is not None:
281+
QTimer.singleShot(timeout, lambda: take_screenshot(widget_of_interest))
282+
app.exec_()
232283
return app
233284

234285

235-
if __name__ == '__main__':
286+
if __name__ == "__main__":
236287
run()

0 commit comments

Comments
 (0)