From 88c6cba90bd7433924f8f37dd5dbbebe195e6eb5 Mon Sep 17 00:00:00 2001 From: anna Date: Tue, 12 Apr 2011 19:13:22 +0200 Subject: [PATCH] notify that wrong module was selected (IDEA-67795) --- .../openapi/wm/ToolWindowManager.java | 4 + .../impl/ToolWindowHeadlessManagerImpl.java | 6 + .../wm/impl/ToolWindowManagerImpl.java | 5 + .../intellij/execution/junit/TestObject.java | 6 +- .../intellij/execution/junit/TestPackage.java | 106 +++++++++++++++++- 5 files changed, 125 insertions(+), 2 deletions(-) diff --git a/platform/platform-api/src/com/intellij/openapi/wm/ToolWindowManager.java b/platform/platform-api/src/com/intellij/openapi/wm/ToolWindowManager.java index 03246ddd2959..ab54442cfcf4 100644 --- a/platform/platform-api/src/com/intellij/openapi/wm/ToolWindowManager.java +++ b/platform/platform-api/src/com/intellij/openapi/wm/ToolWindowManager.java @@ -18,6 +18,7 @@ package com.intellij.openapi.wm; import com.intellij.openapi.Disposable; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.MessageType; +import com.intellij.openapi.ui.popup.Balloon; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -130,4 +131,7 @@ public abstract class ToolWindowManager { public abstract void notifyByBalloon(@NotNull final String toolWindowId, @NotNull final MessageType type, @NotNull final String htmlBody, @Nullable final Icon icon, @Nullable HyperlinkListener listener); + @Nullable + public abstract Balloon getToolWindowBalloon(String id); + } diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowHeadlessManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowHeadlessManagerImpl.java index cbe8df88ad06..657ff811f8dc 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowHeadlessManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowHeadlessManagerImpl.java @@ -27,6 +27,7 @@ import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.DataProvider; import com.intellij.openapi.components.ServiceManager; import com.intellij.openapi.ui.MessageType; +import com.intellij.openapi.ui.popup.Balloon; import com.intellij.openapi.util.ActionCallback; import com.intellij.openapi.util.ActiveRunnable; import com.intellij.openapi.util.Condition; @@ -342,6 +343,11 @@ public class ToolWindowHeadlessManagerImpl extends ToolWindowManagerEx { @Nullable final HyperlinkListener listener) { } + @Override + public Balloon getToolWindowBalloon(String id) { + return null; + } + public void addToolWindowManagerListener(@NotNull ToolWindowManagerListener l) { } diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowManagerImpl.java index 52f92bdc4530..1fb1e20fe224 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowManagerImpl.java @@ -1364,6 +1364,11 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements } + @Override + public Balloon getToolWindowBalloon(String id) { + return myWindow2Balloon.get(id); + } + public boolean isEditorComponentActive() { ApplicationManager.getApplication().assertIsDispatchThread(); diff --git a/plugins/junit/src/com/intellij/execution/junit/TestObject.java b/plugins/junit/src/com/intellij/execution/junit/TestObject.java index db67b7457406..ca038658308c 100644 --- a/plugins/junit/src/com/intellij/execution/junit/TestObject.java +++ b/plugins/junit/src/com/intellij/execution/junit/TestObject.java @@ -305,7 +305,7 @@ public abstract class TestObject implements JavaCommandLine { unboundOutputRoot.flush(); packetsReceiver.checkTerminated(); final JUnitRunningModel model = packetsReceiver.getModel(); - TestsUIUtil.notifyByBalloon(myProject, model != null ? model.getRoot() : null, consoleProperties); + notifyByBalloon(model, consoleProperties); } }); } @@ -352,6 +352,10 @@ public abstract class TestObject implements JavaCommandLine { return result; } + protected void notifyByBalloon(JUnitRunningModel model, JUnitConsoleProperties consoleProperties) { + TestsUIUtil.notifyByBalloon(myProject, model != null ? model.getRoot() : null, consoleProperties); + } + protected JUnitProcessHandler createHandler() throws ExecutionException { appendForkInfo(); return JUnitProcessHandler.runCommandLine(CommandLineBuilder.createFromJavaParameters(myJavaParameters, myProject, true)); diff --git a/plugins/junit/src/com/intellij/execution/junit/TestPackage.java b/plugins/junit/src/com/intellij/execution/junit/TestPackage.java index 264a81c20bdd..185a8b438ce7 100644 --- a/plugins/junit/src/com/intellij/execution/junit/TestPackage.java +++ b/plugins/junit/src/com/intellij/execution/junit/TestPackage.java @@ -21,41 +21,57 @@ import com.intellij.execution.configurations.ConfigurationPerRunnerSettings; import com.intellij.execution.configurations.RunnerSettings; import com.intellij.execution.configurations.RuntimeConfigurationException; import com.intellij.execution.configurations.RuntimeConfigurationWarning; +import com.intellij.execution.executors.DefaultDebugExecutor; +import com.intellij.execution.executors.DefaultRunExecutor; +import com.intellij.execution.junit2.ui.model.JUnitRunningModel; +import com.intellij.execution.junit2.ui.properties.JUnitConsoleProperties; import com.intellij.execution.process.ProcessAdapter; import com.intellij.execution.process.ProcessEvent; +import com.intellij.execution.runners.ExecutionEnvironment; import com.intellij.execution.runners.ProgramRunner; import com.intellij.execution.testframework.SourceScope; import com.intellij.execution.testframework.TestSearchScope; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.ModuleManager; +import com.intellij.openapi.module.ModuleUtil; import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.progress.Task; import com.intellij.openapi.progress.impl.BackgroundableProcessIndicator; import com.intellij.openapi.progress.impl.ProgressManagerImpl; import com.intellij.openapi.project.DumbModeAction; import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.MessageType; +import com.intellij.openapi.ui.popup.Balloon; import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.io.FileUtil; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.openapi.wm.ToolWindowId; +import com.intellij.openapi.wm.ToolWindowManager; import com.intellij.psi.*; import com.intellij.psi.search.GlobalSearchScope; import com.intellij.psi.search.PackageScope; import com.intellij.refactoring.listeners.RefactoringElementListener; +import com.intellij.ui.HyperlinkAdapter; import com.intellij.util.Function; import gnu.trove.THashSet; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import javax.swing.event.HyperlinkEvent; import java.io.DataOutputStream; -import java.io.File; import java.io.IOException; import java.net.InetAddress; import java.net.ServerSocket; import java.net.Socket; import java.util.Collection; +import java.util.HashSet; +import java.util.Set; public class TestPackage extends TestObject { private BackgroundableProcessIndicator mySearchForTestsIndicator; private ServerSocket myServerSocket; + private boolean myFoundTests = true; public TestPackage(final Project project, final JUnitConfiguration configuration, @@ -249,6 +265,53 @@ public class TestPackage extends TestObject { return ApplicationManager.getApplication().isUnitTestMode(); } + @Override + protected void notifyByBalloon(JUnitRunningModel model, final JUnitConsoleProperties consoleProperties) { + if (myFoundTests) { + super.notifyByBalloon(model, consoleProperties); + } + else { + final String packageName = myConfiguration.getPackage(); + if (packageName == null) return; + final Project project = myConfiguration.getProject(); + final PsiPackage aPackage = JavaPsiFacade.getInstance(project).findPackage(packageName); + if (aPackage == null) return; + final Module module = myConfiguration.getConfigurationModule().getModule(); + if (module == null) return; + final Set modulesWithPackage = new HashSet(); + final PsiDirectory[] directories = aPackage.getDirectories(); + for (PsiDirectory directory : directories) { + final Module currentModule = ModuleUtil.findModuleForFile(directory.getVirtualFile(), project); + if (module != currentModule) { + modulesWithPackage.add(currentModule); + } + } + if (!modulesWithPackage.isEmpty()) { + final String testRunDebugId = consoleProperties.isDebug() ? ToolWindowId.DEBUG : ToolWindowId.RUN; + final ToolWindowManager toolWindowManager = ToolWindowManager.getInstance(project); + final Function moduleNameRef = new Function() { + @Override + public String fun(Module module) { + final String moduleName = module.getName(); + return "" + moduleName + ""; + } + }; + String message = "Tests were not found in module \"" + module.getName() + "\".\n" + + "Use "; + if (modulesWithPackage.size() == 1) { + message += "module \"" + moduleNameRef.fun(modulesWithPackage.iterator().next()) + "\" "; + } + else { + message += "one of\n" + StringUtil.join(modulesWithPackage, moduleNameRef, "\n") + "\n"; + } + message += "instead"; + toolWindowManager.notifyByBalloon(testRunDebugId, MessageType.WARNING, message, null, + new ResetConfigurationModuleAdapter(project, consoleProperties, toolWindowManager, + testRunDebugId)); + } + } + } + public interface FindCallback { /** * Invoked in dispatch thread @@ -280,6 +343,7 @@ public class TestPackage extends TestObject { LOG.info(e); } myJunit4[0] = ConfigurationUtil.findAllTestClasses(myClassFilter, myClasses); + myFoundTests = !myClasses.isEmpty(); } @Override @@ -324,4 +388,44 @@ public class TestPackage extends TestObject { } } } + + private class ResetConfigurationModuleAdapter extends HyperlinkAdapter { + private final Project myProject; + private final JUnitConsoleProperties myConsoleProperties; + private final ToolWindowManager myToolWindowManager; + private final String myTestRunDebugId; + + public ResetConfigurationModuleAdapter(final Project project, + final JUnitConsoleProperties consoleProperties, + final ToolWindowManager toolWindowManager, + final String testRunDebugId) { + myProject = project; + myConsoleProperties = consoleProperties; + myToolWindowManager = toolWindowManager; + myTestRunDebugId = testRunDebugId; + } + + @Override + protected void hyperlinkActivated(HyperlinkEvent e) { + final Module moduleByName = ModuleManager.getInstance(myProject).findModuleByName(e.getDescription()); + if (moduleByName != null) { + myConfiguration.getConfigurationModule().setModule(moduleByName); + try { + final Executor executor = myConsoleProperties.isDebug() ? DefaultDebugExecutor.getDebugExecutorInstance() + : DefaultRunExecutor.getRunExecutorInstance(); + final ProgramRunner runner = RunnerRegistry.getInstance().getRunner(executor.getId(), myConfiguration); + assert runner != null; + runner.execute(executor, + new ExecutionEnvironment(myConfiguration, myProject, getRunnerSettings(), getConfigurationSettings(), null)); + final Balloon balloon = myToolWindowManager.getToolWindowBalloon(myTestRunDebugId); + if (balloon != null) { + balloon.hide(); + } + } + catch (ExecutionException e1) { + LOG.error(e1); + } + } + } + } }