From 68fa88bb804a292f767d98eaf8dae7584da45a8a Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Wed, 15 Apr 2015 22:25:16 +0200 Subject: [PATCH] sm-runner: scope-based API for test locator --- .../testIntegration/TestLocationProvider.java | 13 ++-- .../src/META-INF/LangExtensions.xml | 3 - .../sm/CompositeTestLocationProvider.java | 45 +++++++++----- .../testframework/sm/FileUrlProvider.java | 25 ++++---- .../sm/SMTestRunnerConnectionUtil.java | 60 ++++++++++++++++--- ...eralIdBasedToSMTRunnerEventsConvertor.java | 14 ++--- .../sm/runner/GeneralTestEventsProcessor.java | 25 ++++---- .../GeneralToSMTRunnerEventsConvertor.java | 34 ++++++----- .../sm/runner/SMTRunnerConsoleProperties.java | 5 ++ .../sm/runner/SMTestLocator.java | 58 ++++++++++++++++++ .../testframework/sm/runner/SMTestProxy.java | 48 +++++++++++---- .../testframework/sm/FileUrlLocationTest.java | 16 ++--- .../sm/SMLightFixtureTestCase.java | 17 ++---- ...MockGeneralTestEventsProcessorAdapter.java | 5 +- 14 files changed, 245 insertions(+), 123 deletions(-) create mode 100644 platform/smRunner/src/com/intellij/execution/testframework/sm/runner/SMTestLocator.java diff --git a/platform/lang-impl/src/com/intellij/testIntegration/TestLocationProvider.java b/platform/lang-impl/src/com/intellij/testIntegration/TestLocationProvider.java index 94a35f823ed7..46405692e24d 100644 --- a/platform/lang-impl/src/com/intellij/testIntegration/TestLocationProvider.java +++ b/platform/lang-impl/src/com/intellij/testIntegration/TestLocationProvider.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2015 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.intellij.testIntegration; import com.intellij.execution.Location; @@ -23,14 +22,10 @@ import org.jetbrains.annotations.NotNull; import java.util.List; -/** - * @author Roman Chernyatchik - */ +/** @deprecated override SMTRunnerConsoleProperties.getTestLocator() instead (to be removed in IDEA 16) */ public interface TestLocationProvider { - ExtensionPointName EP_NAME = ExtensionPointName.create("com.intellij.testSrcLocator"); + @SuppressWarnings("deprecation") ExtensionPointName EP_NAME = ExtensionPointName.create("com.intellij.testSrcLocator"); @NotNull - List getLocation(@NotNull final String protocolId, - @NotNull final String locationData, - final Project project); + List getLocation(@NotNull String protocolId, @NotNull String locationData, Project project); } diff --git a/platform/platform-resources/src/META-INF/LangExtensions.xml b/platform/platform-resources/src/META-INF/LangExtensions.xml index b42826ccf480..8d3bc0f109db 100644 --- a/platform/platform-resources/src/META-INF/LangExtensions.xml +++ b/platform/platform-resources/src/META-INF/LangExtensions.xml @@ -714,9 +714,6 @@ - - - diff --git a/platform/smRunner/src/com/intellij/execution/testframework/sm/CompositeTestLocationProvider.java b/platform/smRunner/src/com/intellij/execution/testframework/sm/CompositeTestLocationProvider.java index 0f1018f72a83..797bd41d639b 100644 --- a/platform/smRunner/src/com/intellij/execution/testframework/sm/CompositeTestLocationProvider.java +++ b/platform/smRunner/src/com/intellij/execution/testframework/sm/CompositeTestLocationProvider.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2012 JetBrains s.r.o. + * Copyright 2000-2015 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,46 +16,59 @@ package com.intellij.execution.testframework.sm; import com.intellij.execution.Location; +import com.intellij.execution.testframework.sm.runner.SMTestLocator; import com.intellij.openapi.extensions.Extensions; +import com.intellij.openapi.project.DumbAware; import com.intellij.openapi.project.DumbService; import com.intellij.openapi.project.Project; +import com.intellij.psi.search.GlobalSearchScope; import com.intellij.testIntegration.TestLocationProvider; +import com.intellij.util.io.URLUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.Collections; import java.util.List; -/** - * @author Sergey Simonchik - */ -public class CompositeTestLocationProvider implements TestLocationProvider { - - private final TestLocationProvider myPrimaryLocator; +/** to be removed in IDEA 16 */ +public class CompositeTestLocationProvider implements SMTestLocator { + @SuppressWarnings("deprecation") private final TestLocationProvider myPrimaryLocator; + @SuppressWarnings("deprecation") private final TestLocationProvider[] myLocators; + @SuppressWarnings("deprecation") public CompositeTestLocationProvider(@Nullable TestLocationProvider primaryLocator) { myPrimaryLocator = primaryLocator; + myLocators = Extensions.getExtensions(TestLocationProvider.EP_NAME); } @NotNull @Override - public List getLocation(@NotNull String protocolId, @NotNull String locationData, Project project) { - if (myPrimaryLocator != null) { - List locations = myPrimaryLocator.getLocation(protocolId, locationData, project); + public List getLocation(@NotNull String protocol, @NotNull String path, @NotNull Project project, @NotNull GlobalSearchScope scope) { + boolean isDumbMode = DumbService.isDumb(project); + + if (myPrimaryLocator != null && (!isDumbMode || myPrimaryLocator instanceof DumbAware)) { + List locations = myPrimaryLocator.getLocation(protocol, path, project); if (!locations.isEmpty()) { return locations; } } - final boolean isDumbMode = DumbService.isDumb(project); - for (TestLocationProvider provider : Extensions.getExtensions(TestLocationProvider.EP_NAME)) { - if (isDumbMode && !DumbService.isDumbAware(provider)) { - continue; - } - final List locations = provider.getLocation(protocolId, locationData, project); + + if (URLUtil.FILE_PROTOCOL.equals(protocol)) { + List locations = FileUrlProvider.INSTANCE.getLocation(protocol, path, project, scope); if (!locations.isEmpty()) { return locations; } } + + for (@SuppressWarnings("deprecation") TestLocationProvider provider : myLocators) { + if (!isDumbMode || provider instanceof DumbAware) { + List locations = provider.getLocation(protocol, path, project); + if (!locations.isEmpty()) { + return locations; + } + } + } + return Collections.emptyList(); } } diff --git a/platform/smRunner/src/com/intellij/execution/testframework/sm/FileUrlProvider.java b/platform/smRunner/src/com/intellij/execution/testframework/sm/FileUrlProvider.java index 1d3153203314..5061d9d6d1b9 100644 --- a/platform/smRunner/src/com/intellij/execution/testframework/sm/FileUrlProvider.java +++ b/platform/smRunner/src/com/intellij/execution/testframework/sm/FileUrlProvider.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2015 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,6 +17,7 @@ package com.intellij.execution.testframework.sm; import com.intellij.execution.Location; import com.intellij.execution.PsiLocation; +import com.intellij.execution.testframework.sm.runner.SMTestLocator; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.Document; import com.intellij.openapi.project.DumbAware; @@ -24,8 +25,8 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.*; -import com.intellij.testIntegration.TestLocationProvider; -import org.jetbrains.annotations.NonNls; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.util.io.URLUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -37,16 +38,15 @@ import java.util.List; /** * @author Roman Chernyatchik */ -public class FileUrlProvider implements TestLocationProvider, DumbAware { +public class FileUrlProvider implements SMTestLocator, DumbAware { private static final Logger LOG = Logger.getInstance(FileUrlProvider.class.getName()); - @NonNls private static final String FILE_PROTOCOL_ID = "file"; + public static final FileUrlProvider INSTANCE = new FileUrlProvider(); @NotNull - public List getLocation(@NotNull final String protocolId, @NotNull final String path, - final Project project) { - - if (!FILE_PROTOCOL_ID.equals(protocolId)) { + @Override + public List getLocation(@NotNull String protocol, @NotNull String path, @NotNull Project project, @NotNull GlobalSearchScope scope) { + if (!URLUtil.FILE_PROTOCOL.equals(protocol)) { return Collections.emptyList(); } @@ -63,7 +63,7 @@ public class FileUrlProvider implements TestLocationProvider, DumbAware { try { lineNum = Integer.parseInt(lineNumStr); } catch (NumberFormatException e) { - LOG.warn(protocolId + ": Malformed location path: " + path, e); + LOG.warn(protocol + ": Malformed location path: " + path, e); } filePath = normalizedPath.substring(0, lineNoSeparatorIndex); @@ -84,7 +84,7 @@ public class FileUrlProvider implements TestLocationProvider, DumbAware { if (lineNumber < 0) { LOG.warn("Tests location provider: line number should be >= 1. Path: " + path); } - + final List locations = new ArrayList(2); for (VirtualFile file : virtualFiles) { locations.add(createLocationFor(project, file, lineNumber < 1 ? 1 : lineNumber)); @@ -93,8 +93,7 @@ public class FileUrlProvider implements TestLocationProvider, DumbAware { } @Nullable - public static Location createLocationFor(final Project project, - @NotNull final VirtualFile virtualFile, final int lineNum) { + public static Location createLocationFor(Project project, @NotNull VirtualFile virtualFile, int lineNum) { assert lineNum > 0; final PsiFile psiFile = PsiManager.getInstance(project).findFile(virtualFile); diff --git a/platform/smRunner/src/com/intellij/execution/testframework/sm/SMTestRunnerConnectionUtil.java b/platform/smRunner/src/com/intellij/execution/testframework/sm/SMTestRunnerConnectionUtil.java index cf779426584c..832d31bf1479 100644 --- a/platform/smRunner/src/com/intellij/execution/testframework/sm/SMTestRunnerConnectionUtil.java +++ b/platform/smRunner/src/com/intellij/execution/testframework/sm/SMTestRunnerConnectionUtil.java @@ -17,6 +17,7 @@ package com.intellij.execution.testframework.sm; import com.intellij.execution.ExecutionException; import com.intellij.execution.Executor; +import com.intellij.execution.Location; import com.intellij.execution.configurations.CommandLineState; import com.intellij.execution.configurations.ModuleRunConfiguration; import com.intellij.execution.process.ProcessAdapter; @@ -29,12 +30,20 @@ import com.intellij.execution.testframework.sm.runner.ui.*; import com.intellij.execution.testframework.sm.runner.ui.statistics.StatisticsPanel; import com.intellij.execution.testframework.ui.BaseTestsOutputConsoleView; import com.intellij.execution.ui.ConsoleView; +import com.intellij.openapi.project.DumbAware; +import com.intellij.openapi.project.DumbService; +import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Disposer; import com.intellij.openapi.util.Key; +import com.intellij.psi.search.GlobalSearchScope; import com.intellij.testIntegration.TestLocationProvider; +import com.intellij.util.io.URLUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.Collections; +import java.util.List; + /** * @author Roman Chernyatchik */ @@ -98,15 +107,14 @@ public class SMTestRunnerConnectionUtil { public static BaseTestsOutputConsoleView createConsoleWithCustomLocator(@NotNull String testFrameworkName, @NotNull TestConsoleProperties consoleProperties, ExecutionEnvironment environment, - @Nullable TestLocationProvider locator) { - CompositeTestLocationProvider provider = new CompositeTestLocationProvider(locator); - return createConsoleWithCustomLocator(testFrameworkName, consoleProperties, environment, provider, false, null); + @SuppressWarnings("deprecation") @Nullable TestLocationProvider locator) { + return createConsoleWithCustomLocator(testFrameworkName, consoleProperties, environment, locator, false, null); } public static SMTRunnerConsoleView createConsoleWithCustomLocator(@NotNull String testFrameworkName, @NotNull TestConsoleProperties consoleProperties, ExecutionEnvironment environment, - @Nullable TestLocationProvider locator, + @SuppressWarnings("deprecation") @Nullable TestLocationProvider locator, boolean idBasedTreeConstruction, @Nullable TestProxyFilterProvider filterProvider) { String splitterPropertyName = getSplitterPropertyName(testFrameworkName); @@ -122,7 +130,7 @@ public class SMTestRunnerConnectionUtil { public static void initConsoleView(@NotNull final SMTRunnerConsoleView consoleView, @NotNull final String testFrameworkName, - @Nullable final TestLocationProvider locator, + @SuppressWarnings("deprecation") @Nullable final TestLocationProvider locator, final boolean idBasedTreeConstruction, @Nullable final TestProxyFilterProvider filterProvider) { consoleView.addAttachToProcessListener(new AttachToProcessListener() { @@ -132,13 +140,27 @@ public class SMTestRunnerConnectionUtil { if (filterProvider != null) { printerProvider = new TestProxyPrinterProvider(consoleView, filterProvider); } + + TestConsoleProperties properties = consoleView.getProperties(); + + SMTestLocator testLocator = null; + if (properties instanceof SMTRunnerConsoleProperties) { + testLocator = ((SMTRunnerConsoleProperties)properties).getTestLocator(); + } + if (testLocator != null) { + testLocator = new CombinedTestLocator(testLocator); // new API in action + } + else { + testLocator = new CompositeTestLocationProvider(locator); // legacy mode + } + SMTestRunnerResultsForm resultsForm = consoleView.getResultsViewer(); - attachEventsProcessors(consoleView.getProperties(), + attachEventsProcessors(properties, resultsForm, resultsForm.getStatisticsPane(), processHandler, testFrameworkName, - locator, + testLocator, idBasedTreeConstruction, printerProvider); } @@ -163,7 +185,7 @@ public class SMTestRunnerConnectionUtil { StatisticsPanel statisticsPane, ProcessHandler processHandler, @NotNull String testFrameworkName, - @Nullable TestLocationProvider locator, + @Nullable SMTestLocator locator, boolean idBasedTreeConstruction, @Nullable TestProxyPrinterProvider printerProvider) { // build messages consumer @@ -232,6 +254,28 @@ public class SMTestRunnerConnectionUtil { return processHandler; } + private static class CombinedTestLocator implements SMTestLocator, DumbAware { + private final SMTestLocator myLocator; + + public CombinedTestLocator(SMTestLocator locator) { + myLocator = locator; + } + + @NotNull + @Override + public List getLocation(@NotNull String protocol, @NotNull String path, @NotNull Project project, @NotNull GlobalSearchScope scope) { + if (URLUtil.FILE_PROTOCOL.equals(protocol)) { + return FileUrlProvider.INSTANCE.getLocation(protocol, path, project, scope); + } + else if (!DumbService.isDumb(project) || DumbService.isDumbAware(myLocator)) { + return myLocator.getLocation(protocol, path, project, scope); + } + else { + return Collections.emptyList(); + } + } + } + /** @deprecated use {@link #createAndAttachConsole(String, ProcessHandler, TestConsoleProperties, ExecutionEnvironment)} (to be removed in IDEA 16) */ @SuppressWarnings("unused") public static ConsoleView createAndAttachConsole(@NotNull String testFrameworkName, diff --git a/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/GeneralIdBasedToSMTRunnerEventsConvertor.java b/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/GeneralIdBasedToSMTRunnerEventsConvertor.java index 70f33cc426b3..9e09381345af 100644 --- a/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/GeneralIdBasedToSMTRunnerEventsConvertor.java +++ b/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/GeneralIdBasedToSMTRunnerEventsConvertor.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2012 JetBrains s.r.o. + * Copyright 2000-2015 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,7 +23,6 @@ import com.intellij.openapi.application.Application; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.util.Key; -import com.intellij.testIntegration.TestLocationProvider; import com.intellij.util.containers.ContainerUtil; import gnu.trove.TIntObjectHashMap; import org.jetbrains.annotations.NotNull; @@ -44,20 +43,21 @@ public class GeneralIdBasedToSMTRunnerEventsConvertor extends GeneralTestEventsP private final SMTestProxy.SMRootTestProxy myTestsRootProxy; private final Node myTestsRootNode; private final String myTestFrameworkName; + private boolean myIsTestingFinished = false; - private TestLocationProvider myLocator = null; + private SMTestLocator myLocator = null; private TestProxyPrinterProvider myTestProxyPrinterProvider = null; - public GeneralIdBasedToSMTRunnerEventsConvertor(@NotNull SMTestProxy.SMRootTestProxy testsRootProxy, - @NotNull String testFrameworkName) { + public GeneralIdBasedToSMTRunnerEventsConvertor(@NotNull SMTestProxy.SMRootTestProxy testsRootProxy, @NotNull String testFrameworkName) { myTestsRootProxy = testsRootProxy; myTestsRootNode = new Node(0, null, testsRootProxy); myTestFrameworkName = testFrameworkName; myNodeByIdMap.put(myTestsRootNode.getId(), myTestsRootNode); } - public void setLocator(@NotNull TestLocationProvider customLocator) { - myLocator = customLocator; + @Override + public void setLocator(@NotNull SMTestLocator locator) { + myLocator = locator; } public void addEventsListener(@NotNull SMTRunnerEventsListener listener) { diff --git a/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/GeneralTestEventsProcessor.java b/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/GeneralTestEventsProcessor.java index fa79eea38f0d..2562537a58f5 100644 --- a/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/GeneralTestEventsProcessor.java +++ b/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/GeneralTestEventsProcessor.java @@ -22,7 +22,6 @@ import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.util.Condition; import com.intellij.openapi.util.Conditions; import com.intellij.openapi.util.Key; -import com.intellij.testIntegration.TestLocationProvider; import com.intellij.util.Processor; import com.intellij.util.containers.TransferToEDTQueue; import com.intellij.util.ui.UIUtil; @@ -30,7 +29,6 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; -import java.util.List; /** * Processes events of test runner in general text-based form. @@ -49,6 +47,17 @@ public abstract class GeneralTestEventsProcessor implements Disposable { } }, getDisposedCondition(), 300); + + // tree construction events + + public void onSuiteTreeNodeAdded(String testName, String locationHint) { } + + public void onSuiteTreeStarted(String suiteName, String locationHint) { } + + public void onSuiteTreeEnded(String suiteName) { } + + // progress events + public abstract void onStartTesting(); public abstract void onTestsCountInSuite(final int count); @@ -73,7 +82,7 @@ public abstract class GeneralTestEventsProcessor implements Disposable { public abstract void onFinishTesting(); - // Custom progress statistics + // custom progress statistics /** * @param categoryName If isn't empty then progress statistics will use only custom start/failed events. @@ -90,7 +99,7 @@ public abstract class GeneralTestEventsProcessor implements Disposable { public abstract void onTestsReporterAttached(); - public abstract void setLocator(@NotNull TestLocationProvider locator); + public abstract void setLocator(@NotNull SMTestLocator locator); public abstract void addEventsListener(@NotNull SMTRunnerEventsListener viewer); @@ -124,12 +133,4 @@ public abstract class GeneralTestEventsProcessor implements Disposable { myTransferToEDTQueue.offer(runnable); } } - - //tree construction events - - public void onSuiteTreeNodeAdded(String testName, String locationHint) {} - - public void onSuiteTreeStarted(String suiteName, String locationHint) {} - - public void onSuiteTreeEnded(String suiteName) {} } diff --git a/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/GeneralToSMTRunnerEventsConvertor.java b/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/GeneralToSMTRunnerEventsConvertor.java index d6232de605ee..9452b01c166c 100644 --- a/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/GeneralToSMTRunnerEventsConvertor.java +++ b/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/GeneralToSMTRunnerEventsConvertor.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2015 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,7 +25,6 @@ import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.util.Key; import com.intellij.openapi.util.text.StringUtil; -import com.intellij.testIntegration.TestLocationProvider; import com.intellij.util.ObjectUtils; import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NotNull; @@ -35,33 +34,32 @@ import org.jetbrains.annotations.TestOnly; import java.util.*; /** - * @author: Roman Chernyatchik + * This class fires events to SMTRunnerEventsListener in event dispatch thread. * - * This class fires events to RTestUnitEventsListener in EventDispatch thread + * @author: Roman Chernyatchik */ public class GeneralToSMTRunnerEventsConvertor extends GeneralTestEventsProcessor { private static final Logger LOG = Logger.getInstance(GeneralToSMTRunnerEventsConvertor.class.getName()); private final Map myRunningTestsFullNameToProxy = new HashMap(); - private final Set myFailedTestsSet = new HashSet(); - private final TestSuiteStack mySuitesStack = new TestSuiteStack(); private final List myEventsListeners = ContainerUtil.createLockFreeCopyOnWriteList(); private final SMTestProxy.SMRootTestProxy myTestsRootNode; private final String myTestFrameworkName; + private boolean myIsTestingFinished; - private TestLocationProvider myLocator = null; + private SMTestLocator myLocator = null; private boolean myTreeBuildBeforeStart = false; - public GeneralToSMTRunnerEventsConvertor(@NotNull final SMTestProxy.SMRootTestProxy testsRootNode, - @NotNull final String testFrameworkName) { + public GeneralToSMTRunnerEventsConvertor(@NotNull SMTestProxy.SMRootTestProxy testsRootNode, @NotNull String testFrameworkName) { myTestsRootNode = testsRootNode; myTestFrameworkName = testFrameworkName; } - public void setLocator(@NotNull TestLocationProvider customLocator) { - myLocator = customLocator; + @Override + public void setLocator(@NotNull SMTestLocator locator) { + myLocator = locator; } public void addEventsListener(@NotNull final SMTRunnerEventsListener listener) { @@ -176,23 +174,24 @@ public class GeneralToSMTRunnerEventsConvertor extends GeneralTestEventsProcesso if (myRunningTestsFullNameToProxy.containsKey(fullName)) { //Duplicated event logProblem("Test [" + fullName + "] has been already started"); - if (SMTestRunnerConnectionUtil.isInDebugMode()) { return; } } - final SMTestProxy parentSuite = getCurrentSuite(); + SMTestProxy parentSuite = getCurrentSuite(); SMTestProxy testProxy = findChildByName(parentSuite, fullName); if (testProxy == null) { // creates test - testProxy = new SMTestProxy(testName, false, locationUrl); + if (myLocator != null) { testProxy.setLocator(myLocator); } + parentSuite.addChild(testProxy); } + // adds to running tests map myRunningTestsFullNameToProxy.put(fullName, testProxy); @@ -210,14 +209,17 @@ public class GeneralToSMTRunnerEventsConvertor extends GeneralTestEventsProcesso public void run() { final String suiteName = suiteStartedEvent.getName(); final String locationUrl = suiteStartedEvent.getLocationUrl(); - final SMTestProxy parentSuite = getCurrentSuite(); - //new suite + + SMTestProxy parentSuite = getCurrentSuite(); SMTestProxy newSuite = findChildByName(parentSuite, suiteName); if (newSuite == null) { + //new suite newSuite = new SMTestProxy(suiteName, true, locationUrl); + if (myLocator != null) { newSuite.setLocator(myLocator); } + parentSuite.addChild(newSuite); } diff --git a/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/SMTRunnerConsoleProperties.java b/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/SMTRunnerConsoleProperties.java index 1c9a352aed06..0ca074bf4e75 100644 --- a/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/SMTRunnerConsoleProperties.java +++ b/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/SMTRunnerConsoleProperties.java @@ -162,4 +162,9 @@ public class SMTRunnerConsoleProperties extends TestConsoleProperties implements public boolean fixEmptySuite() { return false; } + + @Nullable + public SMTestLocator getTestLocator() { + return null; + } } diff --git a/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/SMTestLocator.java b/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/SMTestLocator.java new file mode 100644 index 000000000000..d31ed80571e3 --- /dev/null +++ b/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/SMTestLocator.java @@ -0,0 +1,58 @@ +/* + * Copyright 2000-2015 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.execution.testframework.sm.runner; + +import com.intellij.execution.Location; +import com.intellij.openapi.project.DumbAware; +import com.intellij.openapi.project.DumbService; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Pair; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.util.containers.ContainerUtil; +import org.jetbrains.annotations.NotNull; + +import java.util.Collections; +import java.util.List; +import java.util.Map; + +/** + * A parser for location URLs reported by test runners. + * See {@link SMTestProxy#getLocation(Project, GlobalSearchScope)} for details. + */ +public interface SMTestLocator { + @NotNull + List getLocation(@NotNull String protocol, @NotNull String path, @NotNull Project project, @NotNull GlobalSearchScope scope); + + class Composite implements SMTestLocator, DumbAware { + private final Map myLocators; + + public Composite(@NotNull Pair first, @NotNull Pair... rest) { + myLocators = ContainerUtil.newHashMap(first, rest); + } + + @NotNull + @Override + public List getLocation(@NotNull String protocol, @NotNull String path, @NotNull Project project, @NotNull GlobalSearchScope scope) { + SMTestLocator locator = myLocators.get(protocol); + + if (locator != null && (!DumbService.isDumb(project) || DumbService.isDumbAware(locator))) { + return locator.getLocation(protocol, path, project, scope); + } + + return Collections.emptyList(); + } + } +} diff --git a/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/SMTestProxy.java b/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/SMTestProxy.java index 9738d9f11f82..65b21d27a05c 100644 --- a/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/SMTestProxy.java +++ b/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/SMTestProxy.java @@ -25,6 +25,8 @@ import com.intellij.execution.ui.ConsoleViewContentType; import com.intellij.ide.util.EditSourceUtil; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.DumbService; +import com.intellij.openapi.project.PossiblyDumbAware; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Key; import com.intellij.openapi.vfs.VirtualFileManager; @@ -44,7 +46,7 @@ import java.util.List; * Represents a test result tree node. * Not thread-safe. All methods should be called in EDT only. * - * @author: Roman Chernyatchik + * @author Roman Chernyatchik */ public class SMTestProxy extends AbstractTestProxy { private static final Logger LOG = Logger.getInstance(SMTestProxy.class.getName()); @@ -69,7 +71,7 @@ public class SMTestProxy extends AbstractTestProxy { private boolean myIsEmptyIsCached = false; // is used for separating unknown and unset values private boolean myIsEmpty = true; - private TestLocationProvider myLocator = null; + private SMTestLocator myLocator = null; private Printer myPreferredPrinter = null; public SMTestProxy(String testName, boolean isSuite, @Nullable String locationUrl) { @@ -83,8 +85,27 @@ public class SMTestProxy extends AbstractTestProxy { myPreservePresentableName = preservePresentableName; } - public void setLocator(@NotNull TestLocationProvider locator) { - myLocator = locator; + public void setLocator(@NotNull SMTestLocator testLocator) { + myLocator = testLocator; + } + + /** @deprecated use {@link #setLocator(SMTestLocator)} (to be removed in IDEA 16) */ + @SuppressWarnings("deprecation") + public void setLocator(@NotNull final TestLocationProvider locator) { + class Adapter implements SMTestLocator, PossiblyDumbAware { + @NotNull + @Override + public List getLocation(@NotNull String protocol, @NotNull String path, @NotNull Project project, @NotNull GlobalSearchScope scope) { + return locator.getLocation(protocol, path, project); + } + + @Override + public boolean isDumbAware() { + return DumbService.isDumbAware(locator); + } + } + + myLocator = new Adapter(); } public void setPreferredPrinter(@NotNull Printer preferredPrinter) { @@ -105,7 +126,6 @@ public class SMTestProxy extends AbstractTestProxy { public int getMagnitude() { // Is used by some of Tests Filters - //WARN: It is Hack, see PoolOfTestStates, API is necessary return getMagnitudeInfo().getValue(); } @@ -244,15 +264,17 @@ public class SMTestProxy extends AbstractTestProxy { } @Nullable - public Location getLocation(final Project project, GlobalSearchScope searchScope) { + public Location getLocation(@NotNull Project project, @NotNull GlobalSearchScope searchScope) { //determines location of test proxy if (myLocationUrl != null && myLocator != null) { String protocolId = VirtualFileManager.extractProtocol(myLocationUrl); if (protocolId != null) { String path = VirtualFileManager.extractPath(myLocationUrl); - List locations = myLocator.getLocation(protocolId, path, project); - if (!locations.isEmpty()) { - return locations.get(0); + if (!DumbService.isDumb(project) || DumbService.isDumbAware(myLocator)) { + List locations = myLocator.getLocation(protocolId, path, project, searchScope); + if (!locations.isEmpty()) { + return locations.get(0); + } } } } @@ -261,14 +283,14 @@ public class SMTestProxy extends AbstractTestProxy { } @Nullable - public Navigatable getDescriptor(final Location location, final TestConsoleProperties testConsoleProperties) { + public Navigatable getDescriptor(@Nullable Location location, @NotNull TestConsoleProperties properties) { // by location gets navigatable element. // It can be file or place in file (e.g. when OPEN_FAILURE_LINE is enabled) if (location == null) return null; - final String stacktrace = myStacktrace; - if (stacktrace != null && (testConsoleProperties instanceof SMStacktraceParser) && isLeaf()) { - final Navigatable result = ((SMStacktraceParser)testConsoleProperties).getErrorNavigatable(location.getProject(), stacktrace); + String stacktrace = myStacktrace; + if (stacktrace != null && properties instanceof SMStacktraceParser && isLeaf()) { + Navigatable result = ((SMStacktraceParser)properties).getErrorNavigatable(location.getProject(), stacktrace); if (result != null) { return result; } diff --git a/platform/smRunner/testSrc/com/intellij/execution/testframework/sm/FileUrlLocationTest.java b/platform/smRunner/testSrc/com/intellij/execution/testframework/sm/FileUrlLocationTest.java index c9ec562ba53d..2fd894225b9b 100644 --- a/platform/smRunner/testSrc/com/intellij/execution/testframework/sm/FileUrlLocationTest.java +++ b/platform/smRunner/testSrc/com/intellij/execution/testframework/sm/FileUrlLocationTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2015 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -29,7 +29,7 @@ public class FileUrlLocationTest extends SMLightFixtureTestCase { return LightProjectDescriptor.EMPTY_PROJECT_DESCRIPTOR; } - public void testSpecNavigation() throws Throwable { + public void testSpecNavigation() { createAndAddFile("my_example_spec.xml", "\n" + "\n" + @@ -42,19 +42,15 @@ public class FileUrlLocationTest extends SMLightFixtureTestCase { doTest(16, "<", path, 3); } - private void doTest(final int expectedOffset, final String expectedStartsWith, - final String filePath, final int lineNum) { - final SMTestProxy testProxy = - new SMTestProxy("myTest", false, "file://" + filePath + ":" + lineNum); - testProxy.setLocator(new CompositeTestLocationProvider(null)); + private void doTest(int expectedOffset, String expectedStartsWith, String filePath, int lineNum) { + final SMTestProxy testProxy = new SMTestProxy("myTest", false, "file://" + filePath + ":" + lineNum); + testProxy.setLocator(FileUrlProvider.INSTANCE); final Location location = testProxy.getLocation(getProject(), GlobalSearchScope.allScope(getProject())); assertNotNull(location); assertNotNull(location.getPsiElement()); - - //System.out.println(location.getPsiElement().getText()); - //System.out.println(location.getPsiElement().getTextOffset()); assertEquals(expectedOffset, location.getPsiElement().getTextOffset()); + final String element = location.getPsiElement().getText(); assertTrue(element, element.startsWith(expectedStartsWith)); } diff --git a/platform/smRunner/testSrc/com/intellij/execution/testframework/sm/SMLightFixtureTestCase.java b/platform/smRunner/testSrc/com/intellij/execution/testframework/sm/SMLightFixtureTestCase.java index 03bc6b5c967b..c387910f6293 100644 --- a/platform/smRunner/testSrc/com/intellij/execution/testframework/sm/SMLightFixtureTestCase.java +++ b/platform/smRunner/testSrc/com/intellij/execution/testframework/sm/SMLightFixtureTestCase.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2015 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -27,13 +27,11 @@ import com.intellij.testFramework.fixtures.TestFixtureBuilder; import com.intellij.testFramework.fixtures.impl.LightTempDirTestFixtureImpl; import org.jetbrains.annotations.Nullable; -import java.io.IOException; - /** * @author Roman.Chernyatchik */ public abstract class SMLightFixtureTestCase extends UsefulTestCase { - + @SuppressWarnings("JUnitTestCaseWithNonTrivialConstructors") protected SMLightFixtureTestCase() { PlatformTestCase.initPlatformLangPrefix(); } @@ -45,15 +43,11 @@ public abstract class SMLightFixtureTestCase extends UsefulTestCase { super.setUp(); final IdeaTestFixtureFactory factory = IdeaTestFixtureFactory.getFixtureFactory(); - final TestFixtureBuilder fixtureBuilder = - factory.createLightFixtureBuilder(getProjectDescriptor()); - + final TestFixtureBuilder fixtureBuilder = factory.createLightFixtureBuilder(getProjectDescriptor()); final IdeaProjectTestFixture fixture = fixtureBuilder.getFixture(); final LightTempDirTestFixtureImpl tempDirTestFixture = new LightTempDirTestFixtureImpl(true); myFixture = IdeaTestFixtureFactory.getFixtureFactory().createCodeInsightFixture(fixture, tempDirTestFixture); myFixture.setUp(); - - setupFixtureWhenInitialized(); } @Override @@ -64,9 +58,6 @@ public abstract class SMLightFixtureTestCase extends UsefulTestCase { super.tearDown(); } - protected void setupFixtureWhenInitialized() throws IOException { - } - @Nullable protected LightProjectDescriptor getProjectDescriptor() { return null; @@ -76,7 +67,7 @@ public abstract class SMLightFixtureTestCase extends UsefulTestCase { return myFixture.getProject(); } - protected void createAndAddFile(final String relativePath, final String text) throws IOException { + protected void createAndAddFile(final String relativePath, final String text) { final PsiFile psiFile = myFixture.addFileToProject(relativePath, text); myFixture.configureFromExistingVirtualFile(psiFile.getVirtualFile()); } diff --git a/platform/smRunner/testSrc/com/intellij/execution/testframework/sm/runner/MockGeneralTestEventsProcessorAdapter.java b/platform/smRunner/testSrc/com/intellij/execution/testframework/sm/runner/MockGeneralTestEventsProcessorAdapter.java index 375f4883dea8..9484336abea9 100644 --- a/platform/smRunner/testSrc/com/intellij/execution/testframework/sm/runner/MockGeneralTestEventsProcessorAdapter.java +++ b/platform/smRunner/testSrc/com/intellij/execution/testframework/sm/runner/MockGeneralTestEventsProcessorAdapter.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2011 JetBrains s.r.o. + * Copyright 2000-2015 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,7 +17,6 @@ package com.intellij.execution.testframework.sm.runner; import com.intellij.execution.testframework.sm.runner.events.*; import com.intellij.openapi.util.Key; -import com.intellij.testIntegration.TestLocationProvider; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -89,7 +88,7 @@ public class MockGeneralTestEventsProcessorAdapter extends GeneralTestEventsProc } @Override - public void setLocator(@NotNull TestLocationProvider locator) { + public void setLocator(@NotNull SMTestLocator locator) { } @Override