diff -r d72fedf5310d -r a56b500d7d2d PyUnit/UnittestDialog.py --- a/PyUnit/UnittestDialog.py Sat Mar 30 14:16:34 2019 +0100 +++ b/PyUnit/UnittestDialog.py Sat Mar 30 14:20:29 2019 +0100 @@ -37,13 +37,18 @@ """ Class implementing the UI to the pyunit package. - @signal unittestFile(str, int, int) emitted to show the source of a + @signal unittestFile(str, int, bool) emitted to show the source of a unittest file @signal unittestStopped() emitted after a unit test was run """ - unittestFile = pyqtSignal(str, int, int) + unittestFile = pyqtSignal(str, int, bool) unittestStopped = pyqtSignal() + TestCaseNameRole = Qt.UserRole + TestCaseFileRole = Qt.UserRole + 1 + + ErrorsInfoRole = Qt.UserRole + def __init__(self, prog=None, dbs=None, ui=None, parent=None, name=None): """ Constructor @@ -449,7 +454,8 @@ ) self.sbLabel.clear() else: - testsList = self.__assembleTestCasesList(test) + testsList = self.__assembleTestCasesList( + test, discoveryStart) self.__populateDiscoveryResults(testsList) self.sbLabel.setText( self.tr("Discovered %n Test(s)", "", @@ -470,27 +476,34 @@ sys.path = self.savedSysPath - def __assembleTestCasesList(self, suite): + def __assembleTestCasesList(self, suite, start): """ Private method to assemble a list of test cases included in a test suite. @param suite test suite to be inspected @type unittest.TestSuite - @return list of tuples containing the test case ID and short - description - @rtype list of tuples of (str, str) + @param start name of directory discovery was started at + @type str + @return list of tuples containing the test case ID, a short description + and the path of the test file name + @rtype list of tuples of (str, str, str) """ testCases = [] for test in suite: if isinstance(test, unittest.TestSuite): - testCases.extend(self.__assembleTestCasesList(test)) + testCases.extend(self.__assembleTestCasesList(test, start)) else: testId = test.id() if "ModuleImportFailure" not in testId and \ "LoadTestsFailure" not in testId and \ "_FailedTest" not in testId: - testCases.append((test.id(), test.shortDescription())) + filename = os.path.join( + start, + test.__module__.replace(".", os.sep) + ".py") + testCases.append( + (test.id(), test.shortDescription(), filename) + ) return testCases def __findDiscoveryItem(self, modulePath): @@ -504,7 +517,7 @@ """ itm = self.discoveryList.topLevelItem(0) while itm is not None: - if itm.data(0, Qt.UserRole) == modulePath: + if itm.data(0, UnittestDialog.TestCaseNameRole) == modulePath: return itm itm = self.discoveryList.itemBelow(itm) @@ -515,9 +528,9 @@ Private method to populate the test discovery results list. @param tests list of tuples containing the discovery results - @type list of tuples of (str, str) + @type list of tuples of (str, str, str) """ - for test, _testDescription in tests: + for test, _testDescription, filename in tests: testPath = test.split(".") pitm = None for index in range(1, len(testPath) + 1): @@ -535,7 +548,15 @@ pitm.setExpanded(True) itm.setFlags(Qt.ItemIsUserCheckable | Qt.ItemIsEnabled) itm.setCheckState(0, Qt.Unchecked) - itm.setData(0, Qt.UserRole, modulePath) + itm.setData(0, UnittestDialog.TestCaseNameRole, modulePath) + if os.path.splitext(os.path.basename(filename))[0] == \ + itm.text(0): + itm.setData(0, UnittestDialog.TestCaseFileRole, + filename) + elif pitm: + fn = pitm.data(0, UnittestDialog.TestCaseFileRole) + if fn: + itm.setData(0, UnittestDialog.TestCaseFileRole, fn) pitm = itm def __selectedTestCases(self, parent=None): @@ -553,7 +574,8 @@ for index in range(self.discoveryList.topLevelItemCount()): itm = self.discoveryList.topLevelItem(index) if itm.checkState(0) == Qt.Checked: - selectedTests.append(itm.data(0, Qt.UserRole)) + selectedTests.append( + itm.data(0, UnittestDialog.TestCaseNameRole)) # ignore children because they are included implicitly elif itm.childCount(): # recursively check children @@ -564,7 +586,8 @@ for index in range(parent.childCount()): itm = parent.child(index) if itm.checkState(0) == Qt.Checked: - selectedTests.append(itm.data(0, Qt.UserRole)) + selectedTests.append( + itm.data(0, UnittestDialog.TestCaseNameRole)) # ignore children because they are included implicitly elif itm.childCount(): # recursively check children @@ -601,6 +624,25 @@ .format(exc_type, exc_value.replace("\n", "<br/>")) ) + @pyqtSlot(QTreeWidgetItem, int) + def on_discoveryList_itemDoubleClicked(self, item, column): + """ + Private slot handling the user double clicking an item. + + @param item reference to the item + @type QTreeWidgetItem + @param column column of the double click + @type int + """ + if item: + filename = item.data(0, UnittestDialog.TestCaseFileRole) + if filename: + if self.__dbs: + # running as part of eric IDE + self.unittestFile.emit(filename, 1, False) + else: + self.__openEditor(filename, 1) + @pyqtSlot() def startTests(self, failedOnly=False): """ @@ -655,6 +697,15 @@ else: testCases = self.__selectedTestCases() + if not testCases and self.discoveryList.topLevelItemCount(): + ok = E5MessageBox.yesNo( + self, + self.tr("Unittest"), + self.tr("""No test case has been selected. Shall all""" + """ test cases be run?""")) + if not ok: + return + if self.__dbs: venvName = self.venvComboBox.currentText() @@ -968,7 +1019,7 @@ self.failCount += 1 self.progressCounterFailureCount.setText(str(self.failCount)) itm = QListWidgetItem(self.tr("Failure: {0}").format(test)) - itm.setData(Qt.UserRole, (test, exc)) + itm.setData(UnittestDialog.ErrorsInfoRole, (test, exc)) self.errorsListWidget.insertItem(0, itm) self.__failedTests.append(testId) @@ -983,7 +1034,7 @@ self.errorCount += 1 self.progressCounterErrorCount.setText(str(self.errorCount)) itm = QListWidgetItem(self.tr("Error: {0}").format(test)) - itm.setData(Qt.UserRole, (test, exc)) + itm.setData(UnittestDialog.ErrorsInfoRole, (test, exc)) self.errorsListWidget.insertItem(0, itm) self.__failedTests.append(testId) @@ -1078,7 +1129,7 @@ self.on_errorsListWidget_currentTextChanged(text) # get the error info - test, tracebackText = lbitem.data(Qt.UserRole) + test, tracebackText = lbitem.data(UnittestDialog.ErrorsInfoRole) # now build the dialog from .Ui_UnittestStacktraceDialog import Ui_UnittestStacktraceDialog @@ -1117,7 +1168,7 @@ fn, ln = fmatch.group(1, 2) if self.__dbs: # running as part of eric IDE - self.unittestFile.emit(fn, int(ln), 1) + self.unittestFile.emit(fn, int(ln), True) else: self.__openEditor(fn, int(ln))