--- a/eric7/Unittest/UTTestResultsTree.py Fri May 13 17:23:21 2022 +0200 +++ b/eric7/Unittest/UTTestResultsTree.py Sat May 14 18:56:52 2022 +0200 @@ -11,6 +11,8 @@ import contextlib import copy import locale + +from collections import Counter from operator import attrgetter from PyQt6.QtCore import ( @@ -31,7 +33,12 @@ class TestResultsModel(QAbstractItemModel): """ Class implementing the item model containing the test data. + + @signal summary(str) emitted whenever the model data changes. The element + is a summary of the test results of the model. """ + summary = pyqtSignal(str) + Headers = [ QCoreApplication.translate("TestResultsModel", "Status"), QCoreApplication.translate("TestResultsModel", "Name"), @@ -129,7 +136,7 @@ elif column == TestResultsModel.DurationColumn: duration = self.__testResults[row].duration return ( - '' + "" if duration is None else locale.format_string("%.2f", duration, grouping=True) ) @@ -289,6 +296,8 @@ self.beginResetModel() self.__testResults = copy.deepcopy(testResults) self.endResetModel() + + self.summary.emit(self.__summary()) def addTestResults(self, testResults): """ @@ -303,6 +312,8 @@ self.beginInsertRows(QModelIndex(), firstRow, lastRow) self.__testResults.extend(testResults) self.endInsertRows() + + self.summary.emit(self.__summary()) def updateTestResults(self, testResults): """ @@ -314,6 +325,8 @@ minIndex = None maxIndex = None + testResultsToBeAdded = [] + for testResult in testResults: for (index, currentResult) in enumerate(self.__testResults): if currentResult.id == testResult.id: @@ -324,12 +337,52 @@ else: minIndex = min(minIndex, index) maxIndex = max(maxIndex, index) + + break + else: + # Test result with given id was not found. + # Just add it to the list (could be a sub test) + testResultsToBeAdded.append(testResult) if minIndex is not None: self.dataChanged.emit( self.index(minIndex, 0), self.index(maxIndex, len(TestResultsModel.Headers) - 1) ) + + self.summary.emit(self.__summary()) + + if testResultsToBeAdded: + self.addTestResults(testResultsToBeAdded) + + def __summary(self): + """ + Private method to generate a test results summary text. + + @return test results summary text + @rtype str + """ + if len(self.__testResults) == 0: + return self.tr("No results to show") + + counts = Counter(res.category for res in self.__testResults) + if all( + counts[category] == 0 + for category in (ResultCategory.FAIL, ResultCategory.OK, + ResultCategory.SKIP) + ): + return self.tr("Collected %n test(s)", "", len(self.__testResults)) + + return self.tr( + "%n test(s)/subtest(s) total, {0} failed, {1} passed," + " {2} skipped, {3} pending", + "", len(self.__testResults) + ).format( + counts[ResultCategory.FAIL], + counts[ResultCategory.OK], + counts[ResultCategory.SKIP], + counts[ResultCategory.PENDING] + ) class TestResultsTreeView(QTreeView):