diff --git a/java/execution/impl/src/com/intellij/execution/testframework/JavaTestLocator.java b/java/execution/impl/src/com/intellij/execution/testframework/JavaTestLocator.java index 291b3888b779..daf085ae662c 100644 --- a/java/execution/impl/src/com/intellij/execution/testframework/JavaTestLocator.java +++ b/java/execution/impl/src/com/intellij/execution/testframework/JavaTestLocator.java @@ -23,12 +23,14 @@ import com.intellij.execution.testframework.sm.runner.SMTestLocator; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiElement; import com.intellij.psi.PsiManager; import com.intellij.psi.PsiMethod; import com.intellij.psi.search.GlobalSearchScope; import com.intellij.psi.util.ClassUtil; import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.Collections; import java.util.List; @@ -69,10 +71,32 @@ public class JavaTestLocator implements SMTestLocator { return results; } + @NotNull + @Override + public List getLocation(@NotNull String protocol, + @NotNull String path, + @Nullable String metainfo, + @NotNull Project project, + @NotNull GlobalSearchScope scope) { + List locations = getLocation(protocol, path, project, scope); + if (locations.size() > 1 && metainfo != null) { + + for (Location location : locations) { + PsiElement element = location.getPsiElement(); + if (element instanceof PsiMethod) { + if (metainfo.equals(ClassUtil.getVMParametersMethodSignature((PsiMethod)element))) { + return Collections.singletonList(location); + } + } + } + } + return locations; + } + private static List collectMethodNavigatables(@NotNull String path, @NotNull Project project, @NotNull GlobalSearchScope scope, - String paramName) { + String paramName) { List results = Collections.emptyList(); String className = StringUtil.getPackageName(path); if (!StringUtil.isEmpty(className)) { diff --git a/java/java-psi-api/src/com/intellij/psi/util/ClassUtil.java b/java/java-psi-api/src/com/intellij/psi/util/ClassUtil.java index 8f0a9a8ad4b3..d7ac28da7256 100644 --- a/java/java-psi-api/src/com/intellij/psi/util/ClassUtil.java +++ b/java/java-psi-api/src/com/intellij/psi/util/ClassUtil.java @@ -17,6 +17,7 @@ package com.intellij.psi.util; import com.intellij.lang.java.JavaLanguage; import com.intellij.openapi.util.Comparing; +import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.*; import com.intellij.psi.search.GlobalSearchScope; import gnu.trove.TObjectIntHashMap; @@ -270,4 +271,41 @@ public class ClassUtil { PsiFile parentFile = aClass.getContainingFile(); return parentFile != null && parentFile.getLanguage() == JavaLanguage.INSTANCE; // do not select JspClass } + + public static String getVMParametersMethodSignature(PsiMethod method) { + return StringUtil.join(method.getParameterList().getParameters(), + param -> { + PsiType type = TypeConversionUtil.erasure(param.getType()); + return type != null ? type.accept(createSignatureVisitor()) : ""; + }, + ","); + } + + private static PsiTypeVisitor createSignatureVisitor() { + return new PsiTypeVisitor() { + @Override + public String visitPrimitiveType(PsiPrimitiveType primitiveType) { + return primitiveType.getCanonicalText(); + } + + @Override + public String visitClassType(PsiClassType classType) { + PsiClass aClass = classType.resolve(); + if (aClass == null) { + return ""; + } + return getJVMClassName(aClass); + } + + @Override + public String visitArrayType(PsiArrayType arrayType) { + PsiType componentType = arrayType.getComponentType(); + String typePresentation = componentType.accept(this); + if (componentType instanceof PsiClassType) { + typePresentation = "L" + typePresentation + ";"; + } + return "[" + typePresentation; + } + }; + } } \ No newline at end of file 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 8bb157c2ad57..fcbeaa68208d 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 @@ -156,14 +156,14 @@ public class GeneralIdBasedToSMTRunnerEventsConvertor extends GeneralTestEventsP } @Override - protected SMTestProxy createSuite(String suiteName, String locationHint, String id, String parentNodeId) { - Node node = createNode(new TestSuiteStartedEvent(suiteName, id, parentNodeId, locationHint, null, null, null, false), true); + protected SMTestProxy createSuite(String suiteName, String locationHint, String metaInfo, String id, String parentNodeId) { + Node node = createNode(new TestSuiteStartedEvent(suiteName, id, parentNodeId, locationHint, metaInfo, null, null, false), true); return node.getProxy(); } @Override - protected SMTestProxy createProxy(String testName, String locationHint, String id, String parentNodeId) { - Node node = createNode(new TestStartedEvent(testName, id, parentNodeId, locationHint, null, null, null, false), false); + protected SMTestProxy createProxy(String testName, String locationHint, String metaInfo, String id, String parentNodeId) { + Node node = createNode(new TestStartedEvent(testName, id, parentNodeId, locationHint, metaInfo, null, null, false), false); return node.getProxy(); } 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 f14238d9dc22..69fa8a24ac0c 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 @@ -76,20 +76,20 @@ public abstract class GeneralTestEventsProcessor implements Disposable { }); } - protected SMTestProxy createProxy(String testName, String locationHint, String id, String parentNodeId) { - return new SMTestProxy(testName, false, locationHint); + protected SMTestProxy createProxy(String testName, String locationHint, String metaInfo, String id, String parentNodeId) { + return new SMTestProxy(testName, false, locationHint, metaInfo, false); } - protected SMTestProxy createSuite(String suiteName, String locationHint, String id, String parentNodeId) { - return new SMTestProxy(suiteName, true, locationHint); + protected SMTestProxy createSuite(String suiteName, String locationHint, String metaInfo, String id, String parentNodeId) { + return new SMTestProxy(suiteName, true, locationHint, metaInfo, false); } protected final List myBuildTreeRunnables = new ArrayList<>(); - public void onSuiteTreeNodeAdded(final String testName, final String locationHint, String id, String parentNodeId) { + public void onSuiteTreeNodeAdded(final String testName, final String locationHint, final String metaInfo, String id, String parentNodeId) { myTreeBuildBeforeStart = true; myBuildTreeRunnables.add(() -> { - final SMTestProxy testProxy = createProxy(testName, locationHint, id, parentNodeId); + final SMTestProxy testProxy = createProxy(testName, locationHint, metaInfo, id, parentNodeId); testProxy.setTreeBuildBeforeStart(); if (myLocator != null) { testProxy.setLocator(myLocator); @@ -103,10 +103,10 @@ public abstract class GeneralTestEventsProcessor implements Disposable { }); } - public void onSuiteTreeStarted(final String suiteName, final String locationHint, String id, String parentNodeId) { + public void onSuiteTreeStarted(final String suiteName, final String locationHint, String metaInfo, String id, String parentNodeId) { myTreeBuildBeforeStart = true; myBuildTreeRunnables.add(() -> { - final SMTestProxy newSuite = createSuite(suiteName, locationHint, id, parentNodeId); + final SMTestProxy newSuite = createSuite(suiteName, locationHint, metaInfo, id, parentNodeId); if (myLocator != null) { newSuite.setLocator(myLocator); } 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 c9b50d66fa93..6229c3342e6d 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 @@ -15,7 +15,6 @@ */ package com.intellij.execution.testframework.sm.runner; -import com.intellij.execution.process.ProcessOutputType; import com.intellij.execution.process.ProcessOutputTypes; import com.intellij.execution.testframework.sm.SMTestRunnerConnectionUtil; import com.intellij.execution.testframework.sm.runner.events.*; @@ -53,16 +52,16 @@ public class GeneralToSMTRunnerEventsConvertor extends GeneralTestEventsProcesso } @Override - protected SMTestProxy createProxy(String testName, String locationHint, String id, String parentNodeId) { - SMTestProxy proxy = super.createProxy(testName, locationHint, id, parentNodeId); + protected SMTestProxy createProxy(String testName, String locationHint, String metaInfo, String id, String parentNodeId) { + SMTestProxy proxy = super.createProxy(testName, locationHint, metaInfo, id, parentNodeId); SMTestProxy currentSuite = getCurrentSuite(); currentSuite.addChild(proxy); return proxy; } @Override - protected SMTestProxy createSuite(String suiteName, String locationHint, String id, String parentNodeId) { - SMTestProxy newSuite = super.createSuite(suiteName, locationHint, id, parentNodeId); + protected SMTestProxy createSuite(String suiteName, String locationHint, String metaInfo, String id, String parentNodeId) { + SMTestProxy newSuite = super.createSuite(suiteName, locationHint, metaInfo, id, parentNodeId); final SMTestProxy parentSuite = getCurrentSuite(); parentSuite.addChild(newSuite); diff --git a/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/OutputToGeneralTestEventsConverter.java b/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/OutputToGeneralTestEventsConverter.java index 93e5aa42fc0c..5001860d2992 100644 --- a/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/OutputToGeneralTestEventsConverter.java +++ b/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/OutputToGeneralTestEventsConverter.java @@ -222,10 +222,10 @@ public class OutputToGeneralTestEventsConverter implements ProcessOutputConsumer } } - private void fireOnSuiteTreeNodeAdded(String testName, String locationHint, String id, String parentNodeId) { + private void fireOnSuiteTreeNodeAdded(String testName, String locationHint, String metaInfo, String id, String parentNodeId) { final GeneralTestEventsProcessor processor = myProcessor; if (processor != null) { - processor.onSuiteTreeNodeAdded(testName, locationHint, id, parentNodeId); + processor.onSuiteTreeNodeAdded(testName, locationHint, metaInfo, id, parentNodeId); } } @@ -237,11 +237,11 @@ public class OutputToGeneralTestEventsConverter implements ProcessOutputConsumer } } - private void fireOnSuiteTreeStarted(String suiteName, String locationHint, String id, String parentNodeId) { + private void fireOnSuiteTreeStarted(String suiteName, String locationHint, String metainfo, String id, String parentNodeId) { final GeneralTestEventsProcessor processor = myProcessor; if (processor != null) { - processor.onSuiteTreeStarted(suiteName, locationHint, id, parentNodeId); + processor.onSuiteTreeStarted(suiteName, locationHint, metainfo, id, parentNodeId); } } @@ -564,13 +564,21 @@ public class OutputToGeneralTestEventsConverter implements ProcessOutputConsumer fireOnTestFrameworkAttached(); } else if (SUITE_TREE_STARTED.equals(name)) { - fireOnSuiteTreeStarted(msg.getAttributes().get("name"), msg.getAttributes().get(ATTR_KEY_LOCATION_URL), TreeNodeEvent.getNodeId(msg), msg.getAttributes().get("parentNodeId")); + fireOnSuiteTreeStarted(msg.getAttributes().get("name"), + msg.getAttributes().get(ATTR_KEY_LOCATION_URL), + BaseStartedNodeEvent.getMetainfo(msg), + TreeNodeEvent.getNodeId(msg), + msg.getAttributes().get("parentNodeId")); } else if (SUITE_TREE_ENDED.equals(name)) { fireOnSuiteTreeEnded(msg.getAttributes().get("name")); } else if (SUITE_TREE_NODE.equals(name)) { - fireOnSuiteTreeNodeAdded(msg.getAttributes().get("name"), msg.getAttributes().get(ATTR_KEY_LOCATION_URL), TreeNodeEvent.getNodeId(msg), msg.getAttributes().get("parentNodeId")); + fireOnSuiteTreeNodeAdded(msg.getAttributes().get("name"), + msg.getAttributes().get(ATTR_KEY_LOCATION_URL), + BaseStartedNodeEvent.getMetainfo(msg), + TreeNodeEvent.getNodeId(msg), + msg.getAttributes().get("parentNodeId")); } else if (BUILD_TREE_ENDED_NODE.equals(name)) { fireOnBuildTreeEnded(); diff --git a/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/events/BaseStartedNodeEvent.java b/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/events/BaseStartedNodeEvent.java index d020fbead832..529e42dccc9f 100644 --- a/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/events/BaseStartedNodeEvent.java +++ b/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/events/BaseStartedNodeEvent.java @@ -17,6 +17,7 @@ package com.intellij.execution.testframework.sm.runner.events; import com.intellij.openapi.util.text.StringUtil; import jetbrains.buildServer.messages.serviceMessages.MessageWithAttributes; +import jetbrains.buildServer.messages.serviceMessages.ServiceMessage; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -97,7 +98,7 @@ public abstract class BaseStartedNodeEvent extends TreeNodeEvent { } @Nullable - public static String getMetainfo(@NotNull MessageWithAttributes message) { + public static String getMetainfo(@NotNull ServiceMessage message) { return message.getAttributes().get("metainfo"); } diff --git a/platform/smRunner/testSrc/com/intellij/execution/testframework/sm/runner/ui/SMTestRunnerResultsFormTest.java b/platform/smRunner/testSrc/com/intellij/execution/testframework/sm/runner/ui/SMTestRunnerResultsFormTest.java index 35c6392185ed..067715ee1a87 100644 --- a/platform/smRunner/testSrc/com/intellij/execution/testframework/sm/runner/ui/SMTestRunnerResultsFormTest.java +++ b/platform/smRunner/testSrc/com/intellij/execution/testframework/sm/runner/ui/SMTestRunnerResultsFormTest.java @@ -289,8 +289,8 @@ public class SMTestRunnerResultsFormTest extends BaseSMTRunnerTestCase { //with test tree build before start actual tests public void testPrependTreeAndSameTestsStartFinish() { //send tree - myEventsProcessor.onSuiteTreeStarted("suite1", null, "suite1", "0"); - myEventsProcessor.onSuiteTreeNodeAdded("test1", null, "test1", "suite1"); + myEventsProcessor.onSuiteTreeStarted("suite1", null, null, "suite1", "0"); + myEventsProcessor.onSuiteTreeNodeAdded("test1", null, null,"test1", "suite1"); myEventsProcessor.onSuiteTreeEnded("suite1"); //start testing diff --git a/plugins/junit/src/com/intellij/execution/junit/JUnitConfiguration.java b/plugins/junit/src/com/intellij/execution/junit/JUnitConfiguration.java index 1a360147ee63..18077f8733fe 100644 --- a/plugins/junit/src/com/intellij/execution/junit/JUnitConfiguration.java +++ b/plugins/junit/src/com/intellij/execution/junit/JUnitConfiguration.java @@ -31,7 +31,6 @@ import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.*; import com.intellij.psi.util.ClassUtil; -import com.intellij.psi.util.TypeConversionUtil; import com.intellij.refactoring.listeners.RefactoringElementListener; import com.intellij.rt.execution.junit.RepeatCount; import com.intellij.util.ArrayUtil; @@ -651,46 +650,13 @@ public class JUnitConfiguration extends JavaTestConfigurationBase { public static String getMethodPresentation(PsiMethod method) { if (method.getParameterList().getParametersCount() > 0 && MetaAnnotationUtil.isMetaAnnotated(method, JUnitUtil.TEST5_ANNOTATIONS)) { - return method.getName() + "(" + StringUtil.join(method.getParameterList().getParameters(), - param -> { - PsiType type = TypeConversionUtil.erasure(param.getType()); - return type != null ? type.accept(createSignatureVisitor()) : ""; - }, - ",") + ")"; + return method.getName() + "(" + ClassUtil.getVMParametersMethodSignature(method) + ")"; } else { return method.getName(); } } - private static PsiTypeVisitor createSignatureVisitor() { - return new PsiTypeVisitor() { - @Override - public String visitPrimitiveType(PsiPrimitiveType primitiveType) { - return primitiveType.getCanonicalText(); - } - - @Override - public String visitClassType(PsiClassType classType) { - PsiClass aClass = classType.resolve(); - if (aClass == null) { - return ""; - } - return ClassUtil.getJVMClassName(aClass); - } - - @Override - public String visitArrayType(PsiArrayType arrayType) { - PsiType componentType = arrayType.getComponentType(); - String typePresentation = componentType.accept(this); - if (componentType instanceof PsiClassType) { - typePresentation = "L" + typePresentation + ";"; - } - return "[" + typePresentation; - } - }; - } - public String getGeneratedName(final JavaRunConfigurationModule configurationModule) { if (TEST_PACKAGE.equals(TEST_OBJECT) || TEST_DIRECTORY.equals(TEST_OBJECT)) { if (TEST_SEARCH_SCOPE.getScope() == TestSearchScope.WHOLE_PROJECT) { diff --git a/plugins/junit5_rt/src/com/intellij/junit5/JUnit5TestExecutionListener.java b/plugins/junit5_rt/src/com/intellij/junit5/JUnit5TestExecutionListener.java index eca7f4a2b534..92d5bfc543d9 100644 --- a/plugins/junit5_rt/src/com/intellij/junit5/JUnit5TestExecutionListener.java +++ b/plugins/junit5_rt/src/com/intellij/junit5/JUnit5TestExecutionListener.java @@ -346,10 +346,17 @@ public class JUnit5TestExecutionListener implements TestExecutionListener { return root.getSource() .map(testSource -> getLocationHintValue(testSource)) .filter(maybeLocationHintValue -> !NO_LOCATION_HINT_VALUE.equals(maybeLocationHintValue)) - .map(locationHintValue -> "locationHint=\'" + locationHintValue + "\'") + .map(locationHintValue -> "locationHint=\'" + locationHintValue + "\'" + getMetainfo(root)) .orElse(NO_LOCATION_HINT); } + private static String getMetainfo(TestIdentifier root) { + return root.getSource() + .filter(testSource -> testSource instanceof MethodSource) + .map(testSource -> " metainfo=\'" + ((MethodSource)testSource).getMethodParameterTypes() + "\'") + .orElse(NO_LOCATION_HINT); + } + static String getLocationHintValue(TestSource testSource) { if (testSource instanceof CompositeTestSource) { diff --git a/plugins/junit5_rt_tests/test/com/intellij/junit5/JUnit5EventsTest.java b/plugins/junit5_rt_tests/test/com/intellij/junit5/JUnit5EventsTest.java index fb6e0ce2f2f4..b0f3569b70ea 100644 --- a/plugins/junit5_rt_tests/test/com/intellij/junit5/JUnit5EventsTest.java +++ b/plugins/junit5_rt_tests/test/com/intellij/junit5/JUnit5EventsTest.java @@ -90,7 +90,7 @@ class JUnit5EventsTest { String lineSeparator = MapSerializerUtil.escapeStr(System.getProperty("line.separator"), MapSerializerUtil.STD_ESCAPER); Assertions.assertEquals("##teamcity[enteredTheMatrix]\n" + "\n" + - "##teamcity[testStarted id='|[engine:testMethod|]' name='test1()' nodeId='|[engine:testMethod|]' parentNodeId='|[engine:testClass|]' locationHint='java:test://com.intellij.junit5.JUnit5EventsTest$TestClass.test1']\n" + + "##teamcity[testStarted id='|[engine:testMethod|]' name='test1()' nodeId='|[engine:testMethod|]' parentNodeId='|[engine:testClass|]' locationHint='java:test://com.intellij.junit5.JUnit5EventsTest$TestClass.test1' metainfo='']\n" + "\n" + "##teamcity[testFailed name='test1()' id='|[engine:testMethod|]' nodeId='|[engine:testMethod|]' parentNodeId='|[engine:testClass|]' message='' expected='expected1' actual='actual1' details='']\n" + "\n" + @@ -117,11 +117,11 @@ class JUnit5EventsTest { Assertions.assertEquals("##teamcity[enteredTheMatrix]\n" + "##teamcity[suiteTreeStarted id='|[engine:testClass|]' name='JUnit5EventsTest$TestClass' nodeId='|[engine:testClass|]' parentNodeId='0' locationHint='java:suite://com.intellij.junit5.JUnit5EventsTest$TestClass']\n" + - "##teamcity[suiteTreeStarted id='|[engine:testMethod|]' name='brokenStream()' nodeId='|[engine:testMethod|]' parentNodeId='|[engine:testClass|]' locationHint='java:test://com.intellij.junit5.JUnit5EventsTest$TestClass.brokenStream']\n" + + "##teamcity[suiteTreeStarted id='|[engine:testMethod|]' name='brokenStream()' nodeId='|[engine:testMethod|]' parentNodeId='|[engine:testClass|]' locationHint='java:test://com.intellij.junit5.JUnit5EventsTest$TestClass.brokenStream' metainfo='']\n" + "##teamcity[suiteTreeEnded id='|[engine:testMethod|]' name='brokenStream()' nodeId='|[engine:testMethod|]' parentNodeId='|[engine:testClass|]']\n" + "##teamcity[suiteTreeEnded id='|[engine:testClass|]' name='JUnit5EventsTest$TestClass' nodeId='|[engine:testClass|]' parentNodeId='0']\n" + "##teamcity[treeEnded]\n" + - "##teamcity[testSuiteStarted id='|[engine:testMethod|]' name='brokenStream()' nodeId='|[engine:testMethod|]' parentNodeId='|[engine:testClass|]'locationHint='java:test://com.intellij.junit5.JUnit5EventsTest$TestClass.brokenStream']\n" + + "##teamcity[testSuiteStarted id='|[engine:testMethod|]' name='brokenStream()' nodeId='|[engine:testMethod|]' parentNodeId='|[engine:testClass|]'locationHint='java:test://com.intellij.junit5.JUnit5EventsTest$TestClass.brokenStream' metainfo='']\n" + "\n" + "##teamcity[testFailed name='Class Configuration' id='|[engine:testMethod|]' nodeId='|[engine:testMethod|]' parentNodeId='|[engine:testClass|]' error='true' message='' details='TRACE']\n" + "\n" +