Merge remote-tracking branch 'origin/master'

This commit is contained in:
Roman Shevchenko
2016-09-08 12:43:38 +03:00
13 changed files with 250 additions and 36 deletions
@@ -29,30 +29,33 @@ import org.jetbrains.annotations.NotNull;
* Date: 2/20/12
*/
public class LocationUtil {
public static boolean isJarAttached(@NotNull Location location, @NotNull final PsiPackage aPackage, final String fqn) {
return isJarAttached(location, fqn, aPackage.getDirectories());
public static boolean isJarAttached(@NotNull Location location, @NotNull final PsiPackage aPackage, final String... fqn) {
return isJarAttached(location, aPackage.getDirectories(), fqn);
}
public static boolean isJarAttached(@NotNull Location location,
final String fqn,
final PsiDirectory[] directories) {
final PsiDirectory[] directories,
final String... fqns) {
final JavaPsiFacade facade = JavaPsiFacade.getInstance(location.getProject());
boolean testngJarFound = false;
final Module locationModule = location.getModule();
if (locationModule != null) {
testngJarFound = facade.findClass(fqn, GlobalSearchScope.moduleWithDependenciesAndLibrariesScope(locationModule, true)) != null;
for (String fqn : fqns) {
if (facade.findClass(fqn, GlobalSearchScope.moduleWithDependenciesAndLibrariesScope(locationModule, true)) != null) return true;
}
}
else {
for (PsiDirectory directory : directories) {
final Module module = ModuleUtilCore.findModuleForFile(directory.getVirtualFile(), location.getProject());
if (module != null) {
if (facade.findClass(fqn, GlobalSearchScope.moduleWithDependenciesAndLibrariesScope(module, true)) != null) {
testngJarFound = true;
break;
GlobalSearchScope scope = GlobalSearchScope.moduleWithDependenciesAndLibrariesScope(module, true);
for (String fqn : fqns) {
if (facade.findClass(fqn, scope) != null) {
return true;
}
}
}
}
}
return testngJarFound;
return false;
}
}
@@ -70,8 +70,17 @@ public class ComparisonFailureData {
public static void registerSMAttributes(ComparisonFailureData notification,
String trace,
String failureMessage,
Map attrs,
Map attrs,
Throwable throwable) {
registerSMAttributes(notification, trace, failureMessage, attrs, throwable, "Comparison Failure: ");
}
public static void registerSMAttributes(ComparisonFailureData notification,
String trace,
String failureMessage,
Map attrs,
Throwable throwable,
String comparisonFailurePrefix) {
final int failureIdx = failureMessage != null ? trace.indexOf(failureMessage) : -1;
final int failureMessageLength = failureMessage != null ? failureMessage.length() : 0;
@@ -98,7 +107,7 @@ public class ComparisonFailureData {
comparisonFailureMessage = trace.substring(0, failureIdx + failureMessageLength);
}
else {
comparisonFailureMessage = (failureMessageLength > 0 ? failureMessage + "\n" : "") + "Comparison Failure: ";
comparisonFailureMessage = (failureMessageLength > 0 ? failureMessage + "\n" : "") + comparisonFailurePrefix;
}
attrs.put("message", comparisonFailureMessage);
}
@@ -164,7 +164,6 @@ public class RunInspectionAction extends GotoActionBase {
else {
additionPanel.add(ScrollPaneFactory.createScrollPane(optionsPanel, SideBorder.NONE));
}
additionPanel.setPreferredSize(new JBDimension(-1, 400));
return additionPanel;
} else {
return fileFilter;
@@ -441,19 +441,23 @@ public class SMTestProxy extends AbstractTestProxy {
public void setTestFailed(@NotNull String localizedMessage, @Nullable String stackTrace, boolean testError) {
setStacktraceIfNotSet(stackTrace);
TestFailedState failedState = new TestFailedState(localizedMessage, stackTrace);
if (myState instanceof TestComparisionFailedState) {
CompoundTestFailedState states = new CompoundTestFailedState(localizedMessage, stackTrace);
states.addFailure((TestFailedState)myState);
final TestFailedState failedState = new TestFailedState(localizedMessage, stackTrace);
states.addFailure(failedState);
fireOnNewPrintable(failedState);
myState = states;
}
else if (myState instanceof CompoundTestFailedState) {
((CompoundTestFailedState)myState).addFailure(failedState);
fireOnNewPrintable(failedState);
}
else if (myState instanceof TestFailedState) {
((TestFailedState)myState).addError(localizedMessage, stackTrace, myPrinter);
}
else {
myState = testError ? new TestErrorState(localizedMessage, stackTrace) : new TestFailedState(localizedMessage, stackTrace);
myState = testError ? new TestErrorState(localizedMessage, stackTrace) : failedState;
fireOnNewPrintable(myState);
}
}
@@ -15,12 +15,18 @@
*/
package com.intellij.execution.testframework.sm.runner;
import com.intellij.execution.filters.HyperlinkInfo;
import com.intellij.execution.testframework.Filter;
import com.intellij.execution.testframework.TestConsoleProperties;
import com.intellij.execution.testframework.sm.runner.ui.MockPrinter;
import com.intellij.execution.testframework.stacktrace.DiffHyperlink;
import com.intellij.execution.ui.ConsoleViewContentType;
import com.intellij.psi.search.GlobalSearchScope;
import org.easymock.EasyMock;
import java.util.ArrayList;
import java.util.List;
import static com.intellij.execution.testframework.sm.runner.states.TestStateInfo.Magnitude;
/**
@@ -227,6 +233,40 @@ public class SMTestProxyTest extends BaseSMTRunnerTestCase {
assertTrue(mySimpleTest.getMagnitudeInfo() == Magnitude.FAILED_INDEX);
}
public void testMultipleAssertions() {
mySimpleTest.setStarted();
mySimpleTest.setTestComparisonFailed("a", "stacktrace", "actual1", "expected1");
mySimpleTest.setTestComparisonFailed("b", "stacktrace", "actual2", "expected2");
mySimpleTest.setTestFailed("c", "stacktrace", false);
mySimpleTest.setFinished();
final MockPrinter printer = new MockPrinter(true) {
@Override
public void printHyperlink(String text, HyperlinkInfo info) {
print(text, ConsoleViewContentType.SYSTEM_OUTPUT);
}
};
mySimpleTest.printOn(printer);
assertEquals("", printer.getStdOut());
assertEquals("\n" +
"a\n" +
"Expected :expected1\n" +
"Actual :actual1\n" +
" <Click to see difference>\n" +
"\n" +
"stacktrace\n" +
"\n" +
"b\n" +
"Expected :expected2\n" +
"Actual :actual2\n" +
" <Click to see difference>\n" +
"\n" +
"stacktrace\n" +
"\n" +
"c\n" +
"stacktrace\n", printer.getAllOut());
}
public void testTestFailed_ComparisonAssertion() {
mySimpleTest.setStarted();
mySimpleTest.setTestComparisonFailed("", "", "", "");
@@ -20,6 +20,7 @@ import com.intellij.execution.filters.Filter
import com.intellij.execution.filters.RegexpFilter
import com.intellij.execution.filters.RegexpFilter.FILE_PATH_MACROS
import com.intellij.execution.filters.RegexpFilter.LINE_MACROS
import com.intellij.openapi.application.runReadAction
import com.intellij.openapi.project.Project
import com.intellij.psi.JavaPsiFacade
import com.intellij.psi.search.GlobalSearchScope
@@ -28,7 +29,7 @@ import org.jetbrains.plugins.groovy.lang.psi.util.GroovyCommonClassNames.GROOVY_
class GrCompilationErrorsFilterProvider : ConsoleFilterProvider {
override fun getDefaultFilters(project: Project): Array<Filter> {
JavaPsiFacade.getInstance(project).findClass(GROOVY_OBJECT, GlobalSearchScope.allScope(project)) ?: return Filter.EMPTY_ARRAY
runReadAction { JavaPsiFacade.getInstance(project).findClass(GROOVY_OBJECT, GlobalSearchScope.allScope(project)) } ?: return Filter.EMPTY_ARRAY
return arrayOf(RegexpFilter(project, "${FILE_PATH_MACROS}: ${LINE_MACROS}.*"))
}
}
@@ -38,7 +38,7 @@ public abstract class AbstractAllInPackageConfigurationProducer extends JUnitCon
PsiPackage psiPackage = JavaRuntimeConfigurationProducerBase.checkPackage(context.getPsiLocation());
if (psiPackage == null) return false;
sourceElement.set(psiPackage);
if (!LocationUtil.isJarAttached(context.getLocation(), psiPackage, JUnitUtil.TESTCASE_CLASS)) return false;
if (!LocationUtil.isJarAttached(context.getLocation(), psiPackage, JUnitUtil.TESTCASE_CLASS, JUnitUtil.TEST5_ANNOTATION)) return false;
final JUnitConfiguration.Data data = configuration.getPersistentData();
data.PACKAGE_NAME = psiPackage.getQualifiedName();
data.TEST_OBJECT = JUnitConfiguration.TEST_PACKAGE;
+10
View File
@@ -4,6 +4,7 @@
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/test" isTestSource="true" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
@@ -11,5 +12,14 @@
<orderEntry type="module" module-name="java-runtime" />
<orderEntry type="library" name="junit5_rt" level="project" />
<orderEntry type="library" name="opentest4j" level="project" />
<orderEntry type="module-library">
<library>
<CLASSES>
<root url="jar://$MODULE_DIR$/lib/junit-jupiter-api-5.0.0-M2.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</orderEntry>
</component>
</module>
Binary file not shown.
@@ -32,7 +32,7 @@ public class JUnit5IdeaTestRunner implements IdeaTestRunner {
@Override
public int startRunnerWithArgs(String[] args, ArrayList listeners, String name, int count, boolean sendTree) {
Launcher launcher = LauncherFactory.create();
JUnit5TestExecutionListener listener = new JUnit5TestExecutionListener(System.out);
JUnit5TestExecutionListener listener = new JUnit5TestExecutionListener();
launcher.registerTestExecutionListeners(listener);
final String[] packageNameRef = new String[1];
final LauncherDiscoveryRequest discoveryRequest = JUnit5TestRunnerUtil.buildRequest(args, packageNameRef);
@@ -19,11 +19,13 @@ import com.intellij.junit4.ExpectedPatterns;
import com.intellij.rt.execution.junit.ComparisonFailureData;
import com.intellij.rt.execution.junit.MapSerializerUtil;
import org.junit.platform.engine.TestExecutionResult;
import org.junit.platform.engine.support.descriptor.JavaClassSource;
import org.junit.platform.engine.support.descriptor.JavaMethodSource;
import org.junit.platform.launcher.TestExecutionListener;
import org.junit.platform.launcher.TestIdentifier;
import org.junit.platform.launcher.TestPlan;
import org.opentest4j.AssertionFailedError;
import org.opentest4j.MultipleFailuresError;
import org.opentest4j.ValueWrapper;
import java.io.PrintStream;
@@ -113,12 +115,12 @@ public class JUnit5TestExecutionListener implements TestExecutionListener {
String reason) {
final String displayName = testIdentifier.getDisplayName();
if (testIdentifier.isTest()) {
final long duration = System.currentTimeMillis() - myCurrentTestStart;
final long duration = getDuration();
if (status == TestExecutionResult.Status.FAILED) {
testFailure(testIdentifier, MapSerializerUtil.TEST_FAILED, throwableOptional, duration, reason);
testFailure(testIdentifier, MapSerializerUtil.TEST_FAILED, throwableOptional, duration, reason, true);
}
else if (status == TestExecutionResult.Status.ABORTED) {
testFailure(testIdentifier, MapSerializerUtil.TEST_IGNORED, throwableOptional, duration, reason);
testFailure(testIdentifier, MapSerializerUtil.TEST_IGNORED, throwableOptional, duration, reason, true);
}
testFinished(testIdentifier, duration);
myFinishCount++;
@@ -134,7 +136,7 @@ public class JUnit5TestExecutionListener implements TestExecutionListener {
if (messageName != null && myFinishCount == 0) {
for (TestIdentifier childIdentifier : myTestPlan.getDescendants(testIdentifier)) {
testStarted(childIdentifier);
testFailure(childIdentifier, messageName, throwableOptional, 0, reason);
testFailure(childIdentifier, messageName, throwableOptional, 0, reason, true);
testFinished(childIdentifier, 0);
}
}
@@ -142,6 +144,10 @@ public class JUnit5TestExecutionListener implements TestExecutionListener {
}
}
protected long getDuration() {
return System.currentTimeMillis() - myCurrentTestStart;
}
private void testStarted(TestIdentifier testIdentifier) {
myPrintStream.println("\n##teamcity[testStarted" + idAndName(testIdentifier) + "\']");
}
@@ -154,7 +160,8 @@ public class JUnit5TestExecutionListener implements TestExecutionListener {
String messageName,
Throwable ex,
long duration,
String reason) {
String reason,
boolean includeThrowable) {
final Map<String, String> attrs = new HashMap<>();
attrs.put("name", testIdentifier.getDisplayName());
attrs.put("id", testIdentifier.getUniqueId().toString());
@@ -166,11 +173,13 @@ public class JUnit5TestExecutionListener implements TestExecutionListener {
}
try {
if (ex != null) {
final StringWriter stringWriter = new StringWriter();
final PrintWriter writer = new PrintWriter(stringWriter);
ex.printStackTrace(writer);
ComparisonFailureData failureData = null;
if (ex instanceof AssertionFailedError && ((AssertionFailedError)ex).isActualDefined() && ((AssertionFailedError)ex).isExpectedDefined()) {
if (ex instanceof MultipleFailuresError && ((MultipleFailuresError)ex).hasFailures()) {
for (AssertionError assertionError : ((MultipleFailuresError)ex).getFailures()) {
testFailure(testIdentifier, messageName, assertionError, duration, reason, false);
}
}
else if (ex instanceof AssertionFailedError && ((AssertionFailedError)ex).isActualDefined() && ((AssertionFailedError)ex).isExpectedDefined()) {
final ValueWrapper actual = ((AssertionFailedError)ex).getActual();
final ValueWrapper expected = ((AssertionFailedError)ex).getExpected();
failureData = new ComparisonFailureData(expected.getStringRepresentation(), actual.getStringRepresentation());
@@ -182,7 +191,13 @@ public class JUnit5TestExecutionListener implements TestExecutionListener {
}
catch (Throwable ignore) {}
}
ComparisonFailureData.registerSMAttributes(failureData, stringWriter.toString(), ex.getMessage(), attrs, ex);
if (includeThrowable || failureData == null) {
ComparisonFailureData.registerSMAttributes(failureData, getTrace(ex), ex.getMessage(), attrs, ex);
}
else {
ComparisonFailureData.registerSMAttributes(failureData, "", "", attrs, ex, "");
}
}
}
finally {
@@ -190,6 +205,13 @@ public class JUnit5TestExecutionListener implements TestExecutionListener {
}
}
protected String getTrace(Throwable ex) {
final StringWriter stringWriter = new StringWriter();
final PrintWriter writer = new PrintWriter(stringWriter);
ex.printStackTrace(writer);
return stringWriter.toString();
}
public void sendTree(TestPlan testPlan, String rootName) {
myTestPlan = testPlan;
@@ -224,16 +246,23 @@ public class JUnit5TestExecutionListener implements TestExecutionListener {
}
static String getClassName(TestIdentifier description) {
Optional<JavaMethodSource> javaSource = getJavaSource(description);
return javaSource.map(source -> source.getJavaClass().getName()).orElse(null);
return description.getSource().map(source -> {
if (source instanceof JavaMethodSource) {
return ((JavaMethodSource)source).getJavaClass().getName();
}
if (source instanceof JavaClassSource) {
return ((JavaClassSource)source).getJavaClass().getName();
}
return null;
}).orElse(null);
}
static String getMethodName(TestIdentifier testIdentifier) {
return getJavaSource(testIdentifier).map(JavaMethodSource::getJavaMethodName).orElse(null);
return testIdentifier.getSource().map((source) -> {
if (source instanceof JavaMethodSource) {
return ((JavaMethodSource)source).getJavaMethodName();
}
return null;
}).orElse(null);
}
private static Optional<JavaMethodSource> getJavaSource(TestIdentifier testIdentifier) {
return testIdentifier.getSource().filter(JavaMethodSource.class::isInstance).map(JavaMethodSource.class::cast);
}
}
@@ -0,0 +1,81 @@
/*
* Copyright 2000-2016 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.junit5;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.engine.descriptor.MethodTestDescriptor;
import org.junit.platform.engine.TestDescriptor;
import org.junit.platform.engine.TestExecutionResult;
import org.junit.platform.engine.UniqueId;
import org.junit.platform.launcher.TestIdentifier;
import org.opentest4j.AssertionFailedError;
import org.opentest4j.MultipleFailuresError;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
class JUnit5EventsTest {
@Test
void multipleFailures() throws Exception {
StringBuffer buf = new StringBuffer();
JUnit5TestExecutionListener executionListener = new JUnit5TestExecutionListener(new PrintStream(new OutputStream() {
@Override
public void write(int b) throws IOException {
buf.append(new String(new byte[]{(byte)b}));
}
})) {
@Override
protected long getDuration() {
return 0;
}
@Override
protected String getTrace(Throwable ex) {
return "TRACE";
}
};
TestDescriptor testDescriptor = new MethodTestDescriptor(UniqueId.forEngine("engine"), TestClass.class,
TestClass.class.getDeclaredMethod("test1"));
TestIdentifier identifier = TestIdentifier.from(testDescriptor);
executionListener.executionStarted(identifier);
MultipleFailuresError multipleFailuresError = new MultipleFailuresError("2 errors");
multipleFailuresError.addFailure(new AssertionFailedError("message1", "expected1", "actual1"));
multipleFailuresError.addFailure(new AssertionFailedError("message2", "expected2", "actual2"));
executionListener.executionFinished(identifier, TestExecutionResult.failed(multipleFailuresError));
Assertions.assertEquals("##teamcity[enteredTheMatrix]\n" +
"\n" +
"##teamcity[testStarted id='[engine:engine]' name='test1()']\n" +
"\n" +
"##teamcity[testFailed actual='actual1' expected='expected1' name='test1()' details='' id='|[engine:engine|]' message='']\n" +
"\n" +
"##teamcity[testFailed actual='actual2' expected='expected2' name='test1()' details='' id='|[engine:engine|]' message='']\n" +
"\n" +
"##teamcity[testFailed name='test1()' details='TRACE' id='|[engine:engine|]' message='2 errors (2 failures)|n\tmessage1|n\tmessage2']\n" +
"\n" +
"##teamcity[testFinished id='[engine:engine]' name='test1()']\n", buf.toString());
}
private static class TestClass {
@Test
void test1() {
}
}
}
@@ -0,0 +1,38 @@
/*
* Copyright 2000-2016 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.junit5;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.engine.descriptor.MethodTestDescriptor;
import org.junit.platform.engine.UniqueId;
import org.junit.platform.launcher.TestIdentifier;
@DisplayName("junit 5 navigation features: location strings, etc")
class JUnit5NavigationTest {
@Test
void methodNavigation() throws Exception {
UniqueId uniqueId = UniqueId.parse("[class:JUnit5NavigationTest]/[method:methodNavigation]");
MethodTestDescriptor methodTestDescriptor =
new MethodTestDescriptor(uniqueId, JUnit5NavigationTest.class, JUnit5NavigationTest.class.getDeclaredMethod("methodNavigation"));
TestIdentifier testIdentifier = TestIdentifier.from(methodTestDescriptor);
Assertions.assertEquals(JUnit5NavigationTest.class.getName(), JUnit5TestExecutionListener.getClassName(testIdentifier));
Assertions.assertEquals("methodNavigation", JUnit5TestExecutionListener.getMethodName(testIdentifier));
//Assertions.assertEquals("methodNavigation", testIdentifier.getDisplayName()); todo methodNavigation()
}
}