--- a/eric7/UI/UserInterface.py Mon May 02 15:53:05 2022 +0200 +++ b/eric7/UI/UserInterface.py Wed Jun 01 13:48:49 2022 +0200 @@ -341,7 +341,7 @@ # set a few dialog members for non-modal dialogs created on demand self.programsDialog = None self.shortcutsDialog = None - self.unittestDialog = None + self.__testingWidget = None self.findFileNameDialog = None self.diffDlg = None self.compareDlg = None @@ -372,8 +372,8 @@ self.viewmanager.openSourceFile) self.projectBrowser.psBrowser.closeSourceWindow.connect( self.viewmanager.closeWindow) - self.projectBrowser.psBrowser.unittestOpen.connect( - self.__unittestScript) + self.projectBrowser.psBrowser.testFile.connect( + self.__startTestScript) self.projectBrowser.pfBrowser.designerFile.connect(self.__designer) self.projectBrowser.pfBrowser.sourceFile.connect( @@ -531,7 +531,7 @@ self.browser.svgFile.connect(self.__showSvg) self.browser.umlFile.connect(self.__showUml) self.browser.binaryFile.connect(self.__openHexEditor) - self.browser.unittestOpen.connect(self.__unittestScript) + self.browser.testFile.connect(self.__startTestScript) self.browser.trpreview.connect(self.__TRPreviewer) self.debuggerUI.debuggingStarted.connect( @@ -606,6 +606,7 @@ self.__initExternalToolsActions() # redirect handling of http and https URLs to ourselves + QDesktopServices.setUrlHandler("file", self.handleUrl) QDesktopServices.setUrlHandler("http", self.handleUrl) QDesktopServices.setUrlHandler("https", self.handleUrl) @@ -661,8 +662,8 @@ # Initialize the instance variables. self.currentProg = None self.isProg = False - self.utEditorOpen = False - self.utProjectOpen = False + self.__testingEditorOpen = False + self.__testingProjectOpen = False self.inDragDrop = False self.setAcceptDrops(True) @@ -2510,81 +2511,81 @@ self.requestFeatureAct.triggered.connect(self.__requestFeature) self.actions.append(self.requestFeatureAct) - self.utActGrp = createActionGroup(self) - - self.utDialogAct = EricAction( - self.tr('Unittest'), + self.testingActGrp = createActionGroup(self) + + self.testingDialogAct = EricAction( + self.tr('Testing'), UI.PixmapCache.getIcon("unittest"), - self.tr('&Unittest...'), - 0, 0, self.utActGrp, 'unittest') - self.utDialogAct.setStatusTip(self.tr('Start unittest dialog')) - self.utDialogAct.setWhatsThis(self.tr( - """<b>Unittest</b>""" - """<p>Perform unit tests. The dialog gives you the""" - """ ability to select and run a unittest suite.</p>""" + self.tr('&Testing...'), + 0, 0, self.testingActGrp, 'unittest') + self.testingDialogAct.setStatusTip(self.tr('Start the testing dialog')) + self.testingDialogAct.setWhatsThis(self.tr( + """<b>Testing</b>""" + """<p>Perform test runs. The dialog gives the""" + """ ability to select and run a test suite or""" + """ auto discover them.</p>""" )) - self.utDialogAct.triggered.connect(self.__unittest) - self.actions.append(self.utDialogAct) + self.testingDialogAct.triggered.connect(self.__startTesting) + self.actions.append(self.testingDialogAct) - self.utRestartAct = EricAction( - self.tr('Unittest Restart'), + self.restartTestAct = EricAction( + self.tr('Restart Last Test'), UI.PixmapCache.getIcon("unittestRestart"), - self.tr('&Restart Unittest...'), - 0, 0, self.utActGrp, 'unittest_restart') - self.utRestartAct.setStatusTip(self.tr('Restart last unittest')) - self.utRestartAct.setWhatsThis(self.tr( - """<b>Restart Unittest</b>""" - """<p>Restart the unittest performed last.</p>""" + self.tr('&Restart Last Test...'), + 0, 0, self.testingActGrp, 'unittest_restart') + self.restartTestAct.setStatusTip(self.tr('Restarts the last test')) + self.restartTestAct.setWhatsThis(self.tr( + """<b>Restart Last Test</b>""" + """<p>Restarts the test performed last.</p>""" )) - self.utRestartAct.triggered.connect(self.__unittestRestart) - self.utRestartAct.setEnabled(False) - self.actions.append(self.utRestartAct) - - self.utRerunFailedAct = EricAction( - self.tr('Unittest Rerun Failed'), + self.restartTestAct.triggered.connect(self.__restartTest) + self.restartTestAct.setEnabled(False) + self.actions.append(self.restartTestAct) + + self.rerunFailedTestsAct = EricAction( + self.tr('Rerun Failed Tests'), UI.PixmapCache.getIcon("unittestRerunFailed"), self.tr('Rerun Failed Tests...'), - 0, 0, self.utActGrp, 'unittest_rerun_failed') - self.utRerunFailedAct.setStatusTip(self.tr( + 0, 0, self.testingActGrp, 'unittest_rerun_failed') + self.rerunFailedTestsAct.setStatusTip(self.tr( 'Rerun failed tests of the last run')) - self.utRerunFailedAct.setWhatsThis(self.tr( + self.rerunFailedTestsAct.setWhatsThis(self.tr( """<b>Rerun Failed Tests</b>""" - """<p>Rerun all tests that failed during the last unittest""" - """ run.</p>""" + """<p>Rerun all tests that failed during the last test run.</p>""" )) - self.utRerunFailedAct.triggered.connect(self.__unittestRerunFailed) - self.utRerunFailedAct.setEnabled(False) - self.actions.append(self.utRerunFailedAct) - - self.utScriptAct = EricAction( - self.tr('Unittest Script'), + self.rerunFailedTestsAct.triggered.connect(self.__rerunFailedTests) + self.rerunFailedTestsAct.setEnabled(False) + self.actions.append(self.rerunFailedTestsAct) + + self.testScriptAct = EricAction( + self.tr('Test Script'), UI.PixmapCache.getIcon("unittestScript"), - self.tr('Unittest &Script...'), - 0, 0, self.utActGrp, 'unittest_script') - self.utScriptAct.setStatusTip(self.tr( - 'Run unittest with current script')) - self.utScriptAct.setWhatsThis(self.tr( - """<b>Unittest Script</b>""" - """<p>Run unittest with current script.</p>""" + self.tr('Test &Script...'), + 0, 0, self.testingActGrp, 'unittest_script') + self.testScriptAct.setStatusTip(self.tr( + 'Run tests of the current script')) + self.testScriptAct.setWhatsThis(self.tr( + """<b>Test Script</b>""" + """<p>Run tests with the current script.</p>""" )) - self.utScriptAct.triggered.connect(self.__unittestScript) - self.utScriptAct.setEnabled(False) - self.actions.append(self.utScriptAct) - - self.utProjectAct = EricAction( - self.tr('Unittest Project'), + self.testScriptAct.triggered.connect(self.__startTestScript) + self.testScriptAct.setEnabled(False) + self.actions.append(self.testScriptAct) + + self.testProjectAct = EricAction( + self.tr('Test Project'), UI.PixmapCache.getIcon("unittestProject"), - self.tr('Unittest &Project...'), - 0, 0, self.utActGrp, 'unittest_project') - self.utProjectAct.setStatusTip(self.tr( - 'Run unittest with current project')) - self.utProjectAct.setWhatsThis(self.tr( - """<b>Unittest Project</b>""" - """<p>Run unittest with current project.</p>""" + self.tr('Test &Project...'), + 0, 0, self.testingActGrp, 'unittest_project') + self.testProjectAct.setStatusTip(self.tr( + 'Run tests of the current project')) + self.testProjectAct.setWhatsThis(self.tr( + """<b>Test Project</b>""" + """<p>Run test of the current project.</p>""" )) - self.utProjectAct.triggered.connect(self.__unittestProject) - self.utProjectAct.setEnabled(False) - self.actions.append(self.utProjectAct) + self.testProjectAct.triggered.connect(self.__startTestProject) + self.testProjectAct.setEnabled(False) + self.actions.append(self.testProjectAct) # check for Qt5 designer and linguist if Utilities.isWindowsPlatform(): @@ -3399,17 +3400,17 @@ ## Extras/Unittest menu ############################################################## - self.__menus["unittest"] = QMenu(self.tr('&Unittest'), self) - self.__menus["unittest"].setTearOffEnabled(True) - self.__menus["unittest"].addAction(self.utDialogAct) - self.__menus["unittest"].addSeparator() - self.__menus["unittest"].addAction(self.utRestartAct) - self.__menus["unittest"].addAction(self.utRerunFailedAct) - self.__menus["unittest"].addSeparator() - self.__menus["unittest"].addAction(self.utScriptAct) - self.__menus["unittest"].addAction(self.utProjectAct) - - self.__menus["extras"].addMenu(self.__menus["unittest"]) + self.__menus["testing"] = QMenu(self.tr('&Testing'), self) + self.__menus["testing"].setTearOffEnabled(True) + self.__menus["testing"].addAction(self.testingDialogAct) + self.__menus["testing"].addSeparator() + self.__menus["testing"].addAction(self.restartTestAct) + self.__menus["testing"].addAction(self.rerunFailedTestsAct) + self.__menus["testing"].addSeparator() + self.__menus["testing"].addAction(self.testScriptAct) + self.__menus["testing"].addAction(self.testProjectAct) + + self.__menus["extras"].addMenu(self.__menus["testing"]) self.__menus["extras"].addSeparator() ############################################################## @@ -3597,7 +3598,7 @@ multiprojecttb = self.multiProject.initToolbar(self.toolbarManager) projecttb, vcstb = self.project.initToolbars(self.toolbarManager) toolstb = QToolBar(self.tr("Tools"), self) - unittesttb = QToolBar(self.tr("Unittest"), self) + testingtb = QToolBar(self.tr("Testing"), self) bookmarktb = self.viewmanager.initBookmarkToolbar(self.toolbarManager) spellingtb = self.viewmanager.initSpellingToolbar(self.toolbarManager) settingstb = QToolBar(self.tr("Settings"), self) @@ -3606,21 +3607,21 @@ pluginstb = QToolBar(self.tr("Plugins"), self) toolstb.setIconSize(Config.ToolBarIconSize) - unittesttb.setIconSize(Config.ToolBarIconSize) + testingtb.setIconSize(Config.ToolBarIconSize) settingstb.setIconSize(Config.ToolBarIconSize) helptb.setIconSize(Config.ToolBarIconSize) profilestb.setIconSize(Config.ToolBarIconSize) pluginstb.setIconSize(Config.ToolBarIconSize) toolstb.setObjectName("ToolsToolbar") - unittesttb.setObjectName("UnittestToolbar") + testingtb.setObjectName("UnittestToolbar") settingstb.setObjectName("SettingsToolbar") helptb.setObjectName("HelpToolbar") profilestb.setObjectName("ProfilesToolbar") pluginstb.setObjectName("PluginsToolbar") toolstb.setToolTip(self.tr("Tools")) - unittesttb.setToolTip(self.tr("Unittest")) + testingtb.setToolTip(self.tr("Unittest")) settingstb.setToolTip(self.tr("Settings")) helptb.setToolTip(self.tr("Help")) profilestb.setToolTip(self.tr("Profiles")) @@ -3634,15 +3635,15 @@ filetb.insertAction(sep, self.newWindowAct) self.toolbarManager.addToolBar(filetb, filetb.windowTitle()) - # setup the unittest toolbar - unittesttb.addAction(self.utDialogAct) - unittesttb.addSeparator() - unittesttb.addAction(self.utRestartAct) - unittesttb.addAction(self.utRerunFailedAct) - unittesttb.addSeparator() - unittesttb.addAction(self.utScriptAct) - unittesttb.addAction(self.utProjectAct) - self.toolbarManager.addToolBar(unittesttb, unittesttb.windowTitle()) + # setup the testing toolbar + testingtb.addAction(self.testingDialogAct) + testingtb.addSeparator() + testingtb.addAction(self.restartTestAct) + testingtb.addAction(self.rerunFailedTestsAct) + testingtb.addSeparator() + testingtb.addAction(self.testScriptAct) + testingtb.addAction(self.testProjectAct) + self.toolbarManager.addToolBar(testingtb, testingtb.windowTitle()) # setup the tools toolbar if self.designer4Act is not None: @@ -3722,7 +3723,7 @@ self.addToolBar(helptb) self.addToolBar(bookmarktb) self.addToolBar(spellingtb) - self.addToolBar(unittesttb) + self.addToolBar(testingtb) self.addToolBar(profilestb) self.addToolBar(pluginstb) @@ -3733,7 +3734,7 @@ multiprojecttb.hide() helptb.hide() spellingtb.hide() - unittesttb.hide() + testingtb.hide() pluginstb.hide() # just add new toolbars to the end of the list @@ -3751,8 +3752,7 @@ ""] self.__toolbars["bookmarks"] = [bookmarktb.windowTitle(), bookmarktb, ""] - self.__toolbars["unittest"] = [unittesttb.windowTitle(), unittesttb, - ""] + self.__toolbars["testing"] = [testingtb.windowTitle(), testingtb, ""] self.__toolbars["view_profiles"] = [profilestb.windowTitle(), profilestb, ""] self.__toolbars["plugins"] = [pluginstb.windowTitle(), pluginstb, ""] @@ -4433,7 +4433,7 @@ @rtype bool """ yes = EricMessageBox.yesNo( - self, + None, self.tr("Upgrade PyQt"), self.tr("""eric needs to be closed in order to upgrade PyQt. It""" """ will be restarted once the upgrade process has""" @@ -4456,7 +4456,7 @@ @rtype bool """ yes = EricMessageBox.yesNo( - self, + None, self.tr("Upgrade Eric"), self.tr("""eric needs to be closed in order to be upgraded. It""" """ will be restarted once the upgrade process has""" @@ -4480,7 +4480,7 @@ @rtype bool """ yes = EricMessageBox.yesNo( - self, + None, self.tr("Upgrade Eric"), self.tr("""eric needs to be closed in order to upgrade eric and""" """ PyQt. It will be restarted once the upgrade process""" @@ -5331,93 +5331,92 @@ self.toolGroups, self.currentToolGroup, self) if dlg.exec() == QDialog.DialogCode.Accepted: self.toolGroups, self.currentToolGroup = dlg.getToolGroups() - - def __createUnitTestDialog(self): - """ - Private slot to generate the unit test dialog on demand. - """ - if self.unittestDialog is None: - from PyUnit.UnittestDialog import UnittestDialog - self.unittestDialog = UnittestDialog( - None, self.__debugServer, self) - self.unittestDialog.unittestFile.connect( + + def __createTestingDialog(self): + """ + Private slot to generate the testing dialog on demand. + """ + if self.__testingWidget is None: + from Testing.TestingWidget import TestingWidget + self.__testingWidget = TestingWidget() + self.__testingWidget.testFile.connect( self.viewmanager.setFileLine) - self.unittestDialog.unittestStopped.connect(self.__unittestStopped) - - def __unittestStopped(self): - """ - Private slot to handle the end of a unit test run. - """ - self.utRerunFailedAct.setEnabled(self.unittestDialog.hasFailedTests()) - self.utRestartAct.setEnabled(True) - - def __unittest(self): - """ - Private slot for displaying the unittest dialog. - """ - self.__createUnitTestDialog() - self.unittestDialog.show() - self.unittestDialog.raise_() + self.__testingWidget.testRunStopped.connect( + self.__testingStopped) + + def __testingStopped(self): + """ + Private slot to handle the end of a test run. + """ + self.rerunFailedTestsAct.setEnabled( + self.__testingWidget.hasFailedTests()) + self.restartTestAct.setEnabled(True) + + def __startTesting(self): + """ + Private slot for displaying the testing dialog. + """ + self.__createTestingDialog() + self.__testingWidget.show() + self.__testingWidget.raise_() @pyqtSlot() @pyqtSlot(str) - def __unittestScript(self, prog=None): - """ - Private slot for displaying the unittest dialog and run the current + def __startTestScript(self, testFile=None): + """ + Private slot for displaying the testing dialog and run the current script. - @param prog the python program to be opened - """ - if prog is None: + @param testFile file containing the tests to be run + @type str + """ + if testFile is None: aw = self.viewmanager.activeWindow() fn = aw.getFileName() - tfn = Utilities.getTestFileName(fn) - if os.path.exists(tfn): - prog = tfn - else: - prog = fn - - self.__unittest() - self.unittestDialog.setProjectMode(False) - self.unittestDialog.insertProg(prog) - self.utRestartAct.setEnabled(False) - self.utRerunFailedAct.setEnabled(False) - - def __unittestProject(self): - """ - Private slot for displaying the unittest dialog and run the current - project. - """ - prog = None + testFile = [ + f for f in Utilities.getTestFileNames(fn) + [fn] + if os.path.exists(f) + ][0] + + self.__startTesting() + self.__testingWidget.setTestFile(testFile, forProject=False) + self.restartTestAct.setEnabled(False) + self.rerunFailedTestsAct.setEnabled(False) + + @pyqtSlot() + def __startTestProject(self): + """ + Private slot for displaying the testing dialog and run the test for + the current project. + """ + testFile = None fn = self.project.getMainScript(True) if fn: - tfn = Utilities.getTestFileName(fn) - if os.path.exists(tfn): - prog = tfn - else: - prog = fn - - self.__unittest() - self.unittestDialog.setProjectMode(True) - self.unittestDialog.insertProg(prog) - self.utRestartAct.setEnabled(False) - self.utRerunFailedAct.setEnabled(False) - - def __unittestRestart(self): - """ - Private slot to display the unittest dialog and rerun the last - unit test. - """ - self.__unittest() - self.unittestDialog.startTests() - - def __unittestRerunFailed(self): - """ - Private slot to display the unittest dialog and rerun all failed tests + testFile = [ + f for f in Utilities.getTestFileNames(fn) + [fn] + if os.path.exists(f) + ][0] + + self.__startTesting() + self.__testingWidget.setTestFile(testFile, forProject=True) + self.restartTestAct.setEnabled(False) + self.rerunFailedTestsAct.setEnabled(False) + + def __restartTest(self): + """ + Private slot to display the testing dialog and rerun the last + test run. + """ + self.__startTesting() + self.__testingWidget.startTests() + + def __rerunFailedTests(self): + """ + Private slot to display the testing dialog and rerun all failed tests of the last run. """ - self.__unittest() - self.unittestDialog.startTests(failedOnly=True) + self.__startTesting() + self.__testingWidget.startTests(failedOnly=True) @pyqtSlot() @pyqtSlot(str) @@ -6816,7 +6815,7 @@ if dlg.exec() == QDialog.DialogCode.Accepted: # recent files, recent projects, recent multi projects, # debug histories, shell histories - (files, projects, multiProjects, debug, shell, unittests, vcs, + (files, projects, multiProjects, debug, shell, testing, vcs, plugins) = dlg.getData() if files: # clear list of recently opened files @@ -6833,13 +6832,13 @@ if shell: # clear the shell histories self.shell.clearAllHistories() - if unittests: + if testing: # clear the unit test histories - if self.unittestDialog is None: - from PyUnit.UnittestDialog import clearSavedHistories + if self.__testingWidget is None: + from Testing.TestingWidget import clearSavedHistories clearSavedHistories() else: - self.unittestDialog.clearRecent() + self.__testingWidget.clearRecent() if vcs: # clear the VCS related histories self.pluginManager.clearPluginsPrivateData("version_control") @@ -6859,23 +6858,23 @@ """ Private slot to handle the projectOpened signal. """ - from Debugger.DebugClientCapabilities import HasUnittest + import Testing self.__setWindowCaption(project=self.project.name) - cap = self.__debugServer.getClientCapabilities( + supported = Testing.isLanguageSupported( self.project.getProjectLanguage()) - self.utProjectAct.setEnabled(cap & HasUnittest) - self.utProjectOpen = cap & HasUnittest + self.testProjectAct.setEnabled(supported) + self.__testingProjectOpen = supported def __projectClosed(self): """ Private slot to handle the projectClosed signal. """ self.__setWindowCaption(project="") - self.utProjectAct.setEnabled(False) - if not self.utEditorOpen: - self.utRestartAct.setEnabled(False) - self.utRerunFailedAct.setEnabled(False) - self.utProjectOpen = False + self.testProjectAct.setEnabled(False) + if not self.__testingEditorOpen: + self.restartTestAct.setEnabled(False) + self.rerunFailedTestsAct.setEnabled(False) + self.__testingProjectOpen = False def __programChange(self, fn): """ @@ -6896,11 +6895,11 @@ Private slot to handle the lastEditorClosed signal. """ self.wizardsMenuAct.setEnabled(False) - self.utScriptAct.setEnabled(False) - self.utEditorOpen = False - if not self.utProjectOpen: - self.utRestartAct.setEnabled(False) - self.utRerunFailedAct.setEnabled(False) + self.testScriptAct.setEnabled(False) + self.__testingEditorOpen = False + if not self.__testingProjectOpen: + self.restartTestAct.setEnabled(False) + self.rerunFailedTestsAct.setEnabled(False) self.__setWindowCaption(editor="") def __editorOpened(self, fn): @@ -6913,19 +6912,12 @@ len(self.__menus["wizards"].actions()) > 0) if fn and str(fn) != "None": - dbs = self.__debugServer - for language in dbs.getSupportedLanguages(): - exts = dbs.getExtensions(language) - if fn.endswith(exts): - from Debugger.DebugClientCapabilities import HasUnittest - cap = dbs.getClientCapabilities(language) - self.utScriptAct.setEnabled(cap & HasUnittest) - self.utEditorOpen = cap & HasUnittest - return - - if self.viewmanager.getOpenEditor(fn).isPyFile(): - self.utScriptAct.setEnabled(True) - self.utEditorOpen = True + import Testing + if Testing.isLanguageSupported( + self.viewmanager.getOpenEditor(fn).getFileType() + ): + self.testScriptAct.setEnabled(True) + self.__testingEditorOpen = True def __checkActions(self, editor): """ @@ -6936,22 +6928,13 @@ fn = editor.getFileName() if editor else None if fn: - dbs = self.__debugServer - for language in dbs.getSupportedLanguages(): - exts = dbs.getExtensions(language) - if fn.endswith(exts): - from Debugger.DebugClientCapabilities import HasUnittest - cap = dbs.getClientCapabilities(language) - self.utScriptAct.setEnabled(cap & HasUnittest) - self.utEditorOpen = cap & HasUnittest - return - - if editor.isPyFile(): - self.utScriptAct.setEnabled(True) - self.utEditorOpen = True + import Testing + if Testing.isLanguageSupported(editor.getFileType()): + self.testScriptAct.setEnabled(True) + self.__testingEditorOpen = True return - self.utScriptAct.setEnabled(False) + self.testScriptAct.setEnabled(False) def __writeTasks(self): """