12 import time |
12 import time |
13 import re |
13 import re |
14 import os |
14 import os |
15 import contextlib |
15 import contextlib |
16 |
16 |
17 from PyQt6.QtCore import pyqtSignal, QEvent, Qt, pyqtSlot |
17 from PyQt6.QtCore import pyqtSignal, pyqtSlot, Qt, QEvent, QFileInfo |
18 from PyQt6.QtGui import QColor |
18 from PyQt6.QtGui import QColor |
19 from PyQt6.QtWidgets import ( |
19 from PyQt6.QtWidgets import ( |
20 QWidget, QDialog, QApplication, QDialogButtonBox, QListWidgetItem, |
20 QWidget, QDialog, QApplication, QDialogButtonBox, QListWidgetItem, |
21 QComboBox, QTreeWidgetItem |
21 QComboBox, QTreeWidgetItem |
22 ) |
22 ) |
75 super().__init__(parent) |
80 super().__init__(parent) |
76 if name: |
81 if name: |
77 self.setObjectName(name) |
82 self.setObjectName(name) |
78 self.setupUi(self) |
83 self.setupUi(self) |
79 |
84 |
|
85 self.clearHistoriesButton.setIcon( |
|
86 UI.PixmapCache.getIcon("clearPrivateData")) |
|
87 |
80 self.testsuitePicker.setMode(EricPathPickerModes.OPEN_FILE_MODE) |
88 self.testsuitePicker.setMode(EricPathPickerModes.OPEN_FILE_MODE) |
81 self.testsuitePicker.setInsertPolicy( |
89 self.testsuitePicker.setInsertPolicy( |
82 QComboBox.InsertPolicy.InsertAtTop) |
90 QComboBox.InsertPolicy.InsertAtTop) |
83 self.testsuitePicker.setSizeAdjustPolicy( |
91 self.testsuitePicker.setSizeAdjustPolicy( |
84 QComboBox.SizeAdjustPolicy.AdjustToMinimumContentsLengthWithIcon) |
92 QComboBox.SizeAdjustPolicy.AdjustToMinimumContentsLengthWithIcon) |
86 self.discoveryPicker.setMode(EricPathPickerModes.DIRECTORY_MODE) |
94 self.discoveryPicker.setMode(EricPathPickerModes.DIRECTORY_MODE) |
87 self.discoveryPicker.setInsertPolicy( |
95 self.discoveryPicker.setInsertPolicy( |
88 QComboBox.InsertPolicy.InsertAtTop) |
96 QComboBox.InsertPolicy.InsertAtTop) |
89 self.discoveryPicker.setSizeAdjustPolicy( |
97 self.discoveryPicker.setSizeAdjustPolicy( |
90 QComboBox.SizeAdjustPolicy.AdjustToMinimumContentsLengthWithIcon) |
98 QComboBox.SizeAdjustPolicy.AdjustToMinimumContentsLengthWithIcon) |
|
99 |
|
100 self.testComboBox.lineEdit().setClearButtonEnabled(True) |
91 |
101 |
92 self.discoverButton = self.buttonBox.addButton( |
102 self.discoverButton = self.buttonBox.addButton( |
93 self.tr("Discover"), QDialogButtonBox.ButtonRole.ActionRole) |
103 self.tr("Discover"), QDialogButtonBox.ButtonRole.ActionRole) |
94 self.discoverButton.setToolTip(self.tr( |
104 self.discoverButton.setToolTip(self.tr( |
95 "Discover tests")) |
105 "Discover tests")) |
96 self.discoverButton.setWhatsThis(self.tr( |
106 self.discoverButton.setWhatsThis(self.tr( |
97 """<b>Discover</b>""" |
107 """<b>Discover</b>""" |
98 """<p>This button starts a discovery of available tests.</p>""")) |
108 """<p>This button starts a discovery of available tests.</p>""")) |
99 self.startButton = self.buttonBox.addButton( |
109 self.startButton = self.buttonBox.addButton( |
100 self.tr("Start"), QDialogButtonBox.ButtonRole.ActionRole) |
110 self.tr("Start"), QDialogButtonBox.ButtonRole.ActionRole) |
|
111 |
101 self.startButton.setToolTip(self.tr( |
112 self.startButton.setToolTip(self.tr( |
102 "Start the selected testsuite")) |
113 "Start the selected testsuite")) |
103 self.startButton.setWhatsThis(self.tr( |
114 self.startButton.setWhatsThis(self.tr( |
104 """<b>Start Test</b>""" |
115 """<b>Start Test</b>""" |
105 """<p>This button starts the selected testsuite.</p>""")) |
116 """<p>This button starts the selected testsuite.</p>""")) |
|
117 |
106 self.startFailedButton = self.buttonBox.addButton( |
118 self.startFailedButton = self.buttonBox.addButton( |
107 self.tr("Rerun Failed"), QDialogButtonBox.ButtonRole.ActionRole) |
119 self.tr("Rerun Failed"), QDialogButtonBox.ButtonRole.ActionRole) |
108 self.startFailedButton.setToolTip( |
120 self.startFailedButton.setToolTip( |
109 self.tr("Reruns failed tests of the selected testsuite")) |
121 self.tr("Reruns failed tests of the selected testsuite")) |
110 self.startFailedButton.setWhatsThis(self.tr( |
122 self.startFailedButton.setWhatsThis(self.tr( |
111 """<b>Rerun Failed</b>""" |
123 """<b>Rerun Failed</b>""" |
112 """<p>This button reruns all failed tests of the selected""" |
124 """<p>This button reruns all failed tests of the selected""" |
113 """ testsuite.</p>""")) |
125 """ testsuite.</p>""")) |
|
126 |
114 self.stopButton = self.buttonBox.addButton( |
127 self.stopButton = self.buttonBox.addButton( |
115 self.tr("Stop"), QDialogButtonBox.ButtonRole.ActionRole) |
128 self.tr("Stop"), QDialogButtonBox.ButtonRole.ActionRole) |
116 self.stopButton.setToolTip(self.tr("Stop the running unittest")) |
129 self.stopButton.setToolTip(self.tr("Stop the running unittest")) |
117 self.stopButton.setWhatsThis(self.tr( |
130 self.stopButton.setWhatsThis(self.tr( |
118 """<b>Stop Test</b>""" |
131 """<b>Stop Test</b>""" |
119 """<p>This button stops a running unittest.</p>""")) |
132 """<p>This button stops a running unittest.</p>""")) |
|
133 |
120 self.discoverButton.setEnabled(False) |
134 self.discoverButton.setEnabled(False) |
121 self.stopButton.setEnabled(False) |
135 self.stopButton.setEnabled(False) |
122 self.startButton.setDefault(True) |
136 self.startButton.setDefault(True) |
123 self.startFailedButton.setEnabled(False) |
137 self.startFailedButton.setEnabled(False) |
124 |
138 |
249 discoveryPicker object. |
268 discoveryPicker object. |
250 |
269 |
251 @param start start directory name to be inserted |
270 @param start start directory name to be inserted |
252 @type str |
271 @type str |
253 """ |
272 """ |
|
273 current = self.discoveryPicker.currentText() |
|
274 |
254 # prepend the given directory to the discovery picker |
275 # prepend the given directory to the discovery picker |
255 if start is None: |
276 if start is None: |
256 start = "" |
277 start = "" |
257 if start in self.discoverHistory: |
278 if start in self.discoverHistory: |
258 self.discoverHistory.remove(start) |
279 self.discoverHistory.remove(start) |
259 self.discoverHistory.insert(0, start) |
280 self.discoverHistory.insert(0, start) |
260 self.discoveryPicker.clear() |
281 self.discoveryPicker.clear() |
261 self.discoveryPicker.addItems(self.discoverHistory) |
282 self.discoveryPicker.addItems(self.discoverHistory) |
|
283 |
|
284 if current: |
|
285 self.discoveryPicker.setText(current) |
262 |
286 |
263 def insertProg(self, prog): |
287 def insertProg(self, prog): |
264 """ |
288 """ |
265 Public slot to insert the filename prog into the testsuitePicker |
289 Public slot to insert the filename prog into the testsuitePicker |
266 object. |
290 object. |
267 |
291 |
268 @param prog filename to be inserted (string) |
292 @param prog filename to be inserted (string) |
269 """ |
293 """ |
|
294 current = self.testsuitePicker.currentText() |
|
295 |
270 # prepend the selected file to the testsuite picker |
296 # prepend the selected file to the testsuite picker |
271 if prog is None: |
297 if prog is None: |
272 prog = "" |
298 prog = "" |
273 if prog in self.fileHistory: |
299 if prog in self.fileHistory: |
274 self.fileHistory.remove(prog) |
300 self.fileHistory.remove(prog) |
275 self.fileHistory.insert(0, prog) |
301 self.fileHistory.insert(0, prog) |
276 self.testsuitePicker.clear() |
302 self.testsuitePicker.clear() |
277 self.testsuitePicker.addItems(self.fileHistory) |
303 self.testsuitePicker.addItems(self.fileHistory) |
|
304 |
|
305 if current: |
|
306 self.testsuitePicker.setText(current) |
278 |
307 |
279 def insertTestName(self, testName): |
308 def insertTestName(self, testName): |
280 """ |
309 """ |
281 Public slot to insert a test name into the testComboBox object. |
310 Public slot to insert a test name into the testComboBox object. |
282 |
311 |
283 @param testName name of the test to be inserted (string) |
312 @param testName name of the test to be inserted (string) |
284 """ |
313 """ |
|
314 current = self.testComboBox.currentText() |
|
315 |
285 # prepend the selected file to the testsuite combobox |
316 # prepend the selected file to the testsuite combobox |
286 if testName is None: |
317 if testName is None: |
287 testName = "" |
318 testName = "" |
288 if testName in self.testNameHistory: |
319 if testName in self.testNameHistory: |
289 self.testNameHistory.remove(testName) |
320 self.testNameHistory.remove(testName) |
290 self.testNameHistory.insert(0, testName) |
321 self.testNameHistory.insert(0, testName) |
291 self.testComboBox.clear() |
322 self.testComboBox.clear() |
292 self.testComboBox.addItems(self.testNameHistory) |
323 self.testComboBox.addItems(self.testNameHistory) |
|
324 |
|
325 if current: |
|
326 self.testComboBox.setCurrentText(current) |
293 |
327 |
294 @pyqtSlot() |
328 @pyqtSlot() |
295 def on_testsuitePicker_aboutToShowPathPickerDialog(self): |
329 def on_testsuitePicker_aboutToShowPathPickerDialog(self): |
296 """ |
330 """ |
297 Private slot called before the test suite selection dialog is shown. |
331 Private slot called before the test suite selection dialog is shown. |
363 |
397 |
364 @param button button that was clicked (QAbstractButton) |
398 @param button button that was clicked (QAbstractButton) |
365 """ |
399 """ |
366 if button == self.discoverButton: |
400 if button == self.discoverButton: |
367 self.__discover() |
401 self.__discover() |
|
402 self.__saveRecent() |
368 elif button == self.startButton: |
403 elif button == self.startButton: |
369 self.startTests() |
404 self.startTests() |
|
405 self.__saveRecent() |
370 elif button == self.stopButton: |
406 elif button == self.stopButton: |
371 self.__stopTests() |
407 self.__stopTests() |
372 elif button == self.startFailedButton: |
408 elif button == self.startFailedButton: |
373 self.startTests(failedOnly=True) |
409 self.startTests(failedOnly=True) |
374 |
410 |
|
411 def __loadRecent(self): |
|
412 """ |
|
413 Private method to load the most recently used lists. |
|
414 """ |
|
415 Preferences.Prefs.rsettings.sync() |
|
416 |
|
417 # 1. discovery history |
|
418 self.discoverHistory = [] |
|
419 rs = Preferences.Prefs.rsettings.value( |
|
420 recentNameUnittestDiscoverHistory) |
|
421 if rs is not None: |
|
422 recent = [f |
|
423 for f in Preferences.toList(rs) |
|
424 if QFileInfo(f).exists()] |
|
425 self.discoverHistory = recent[ |
|
426 :Preferences.getDebugger("RecentNumber")] |
|
427 |
|
428 # 2. test file history |
|
429 self.fileHistory = [] |
|
430 rs = Preferences.Prefs.rsettings.value( |
|
431 recentNameUnittestFileHistory) |
|
432 if rs is not None: |
|
433 recent = [f |
|
434 for f in Preferences.toList(rs) |
|
435 if QFileInfo(f).exists()] |
|
436 self.fileHistory = recent[ |
|
437 :Preferences.getDebugger("RecentNumber")] |
|
438 |
|
439 # 3. test name history |
|
440 self.testNameHistory = [] |
|
441 rs = Preferences.Prefs.rsettings.value( |
|
442 recentNameUnittestTestnameHistory) |
|
443 if rs is not None: |
|
444 recent = [n for n in Preferences.toList(rs) if n] |
|
445 self.testNameHistory = recent[ |
|
446 :Preferences.getDebugger("RecentNumber")] |
|
447 |
|
448 def __saveRecent(self): |
|
449 """ |
|
450 Private method to save the most recently used lists. |
|
451 """ |
|
452 Preferences.Prefs.rsettings.setValue( |
|
453 recentNameUnittestDiscoverHistory, self.discoverHistory) |
|
454 Preferences.Prefs.rsettings.setValue( |
|
455 recentNameUnittestFileHistory, self.fileHistory) |
|
456 Preferences.Prefs.rsettings.setValue( |
|
457 recentNameUnittestTestnameHistory, self.testNameHistory) |
|
458 |
|
459 Preferences.Prefs.rsettings.sync() |
|
460 |
|
461 @pyqtSlot() |
|
462 def clearRecent(self): |
|
463 """ |
|
464 Public slot to clear the recently used lists. |
|
465 """ |
|
466 # clear histories |
|
467 self.discoverHistory = [] |
|
468 self.fileHistory = [] |
|
469 self.testNameHistory = [] |
|
470 |
|
471 # clear widgets with histories |
|
472 self.discoveryPicker.clear() |
|
473 self.testsuitePicker.clear() |
|
474 self.testComboBox.clear() |
|
475 |
|
476 # sync histories |
|
477 self.__saveRecent() |
|
478 |
375 @pyqtSlot() |
479 @pyqtSlot() |
376 def __discover(self): |
480 def __discover(self): |
377 """ |
481 """ |
378 Private slot to discover unit test but don't run them. |
482 Private slot to discover unit test but don't run them. |
379 """ |
483 """ |