This is an automated email from the ASF dual-hosted git repository. johnmcdonnell pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/incubator-netbeans.git
The following commit(s) were added to refs/heads/master by this push: new 55c814d NETBEANS-1663: Better support for JUnit 5 ParameterizedTest (#1019) 55c814d is described below commit 55c814dd124ad87e44d23fbb8d913f6b5b27883e Author: Stig Døssing <stigdoess...@gmail.com> AuthorDate: Mon Dec 31 03:51:39 2018 +0100 NETBEANS-1663: Better support for JUnit 5 ParameterizedTest (#1019) --- .../gsf/testrunner/ui/api/TestMethodNode.java | 14 ++--- .../modules/gsf/testrunner/api/Testcase.java | 17 ++++- java/junit.ui/nbproject/project.properties | 2 +- .../junit/ui/actions/TestClassInfoTask.java | 72 ++++++++++++++-------- .../netbeans/modules/junit/api/JUnitTestcase.java | 17 ++++- .../maven/junit/JUnitOutputListenerProvider.java | 15 ++++- 6 files changed, 101 insertions(+), 36 deletions(-) diff --git a/ide/gsf.testrunner.ui/src/org/netbeans/modules/gsf/testrunner/ui/api/TestMethodNode.java b/ide/gsf.testrunner.ui/src/org/netbeans/modules/gsf/testrunner/ui/api/TestMethodNode.java index f03f6b3..67eee3b 100644 --- a/ide/gsf.testrunner.ui/src/org/netbeans/modules/gsf/testrunner/ui/api/TestMethodNode.java +++ b/ide/gsf.testrunner.ui/src/org/netbeans/modules/gsf/testrunner/ui/api/TestMethodNode.java @@ -110,23 +110,23 @@ public class TestMethodNode extends AbstractNode { : testcase.getTrouble().isError() ? 1 : 2; if ((status == 0) && (testcase.getTimeMillis() < 0)) { - setDisplayName(testcase.getName()); + setDisplayName(testcase.getDisplayName()); return; } if(testcase.getTimeMillis() < 0) { if(status == 1) { - setDisplayName(Bundle.MSG_TestMethodError(testcase.getName())); + setDisplayName(Bundle.MSG_TestMethodError(testcase.getDisplayName())); } else if(status == 2) { - setDisplayName(Bundle.MSG_TestMethodFailed(testcase.getName())); + setDisplayName(Bundle.MSG_TestMethodFailed(testcase.getDisplayName())); } } else { if(status == 0) { - setDisplayName(Bundle.MSG_TestMethodPassed_time(testcase.getName(), testcase.getTimeMillis() / 1000f)); + setDisplayName(Bundle.MSG_TestMethodPassed_time(testcase.getDisplayName(), testcase.getTimeMillis() / 1000f)); } else if(status == 1) { - setDisplayName(Bundle.MSG_TestMethodError_time(testcase.getName(), testcase.getTimeMillis() / 1000f)); + setDisplayName(Bundle.MSG_TestMethodError_time(testcase.getDisplayName(), testcase.getTimeMillis() / 1000f)); } else if(status == 2) { - setDisplayName(Bundle.MSG_TestMethodFailed_time(testcase.getName(), testcase.getTimeMillis() / 1000f)); + setDisplayName(Bundle.MSG_TestMethodFailed_time(testcase.getDisplayName(), testcase.getTimeMillis() / 1000f)); } } } @@ -145,7 +145,7 @@ public class TestMethodNode extends AbstractNode { Status status = testcase.getStatus(); StringBuffer buf = new StringBuffer(60); - buf.append(testcase.getName()); + buf.append(testcase.getDisplayName()); buf.append(" "); //NOI18N buf.append("<font color='#"); //NOI18N buf.append(status.getHtmlDisplayColor() + "'>"); //NOI18N diff --git a/ide/gsf.testrunner/src/org/netbeans/modules/gsf/testrunner/api/Testcase.java b/ide/gsf.testrunner/src/org/netbeans/modules/gsf/testrunner/api/Testcase.java index 138162a..fd2b290 100644 --- a/ide/gsf.testrunner/src/org/netbeans/modules/gsf/testrunner/api/Testcase.java +++ b/ide/gsf.testrunner/src/org/netbeans/modules/gsf/testrunner/api/Testcase.java @@ -37,6 +37,7 @@ public class Testcase { */ private String className; private final String name; + private final String displayName; private long timeMillis; private Trouble trouble; private Status status; @@ -50,18 +51,25 @@ public class Testcase { private String location; private TestSession session; + public Testcase(String name, String type, TestSession session) { + this(name, name, type, session); + } + /** * Creates a new Testcase. * * @param name the name of this test case. + * @param displayName The display name of this test case. * @param type the type of the test case, e.g. for Ruby it might be * <code>"RSPEC"</code> or <code>"TEST/UNIT"</code>. May be <code>null</code>. * @param session the session where this test case is executed. */ - public Testcase(String name, String type, TestSession session) { + public Testcase(String name, String displayName, String type, TestSession session) { Parameters.notNull("name", name); + Parameters.notNull("displayName", displayName); Parameters.notNull("session", session); this.name = name; + this.displayName = displayName; this.session = session; this.type = type; } @@ -153,6 +161,13 @@ public class Testcase { public String getName() { return name; } + + /** + * @return The display name of this test case. + */ + public String getDisplayName() { + return displayName; + } /** * @return the timeMillis diff --git a/java/junit.ui/nbproject/project.properties b/java/junit.ui/nbproject/project.properties index 375b088..26aa41b 100644 --- a/java/junit.ui/nbproject/project.properties +++ b/java/junit.ui/nbproject/project.properties @@ -15,6 +15,6 @@ # specific language governing permissions and limitations # under the License. is.eager=true -javac.source=1.6 +javac.source=1.8 javac.compilerargs=-Xlint -Xlint:-serial requires.nb.javac=true diff --git a/java/junit.ui/src/org/netbeans/modules/junit/ui/actions/TestClassInfoTask.java b/java/junit.ui/src/org/netbeans/modules/junit/ui/actions/TestClassInfoTask.java index 2ba63c6..4d1c2b4 100644 --- a/java/junit.ui/src/org/netbeans/modules/junit/ui/actions/TestClassInfoTask.java +++ b/java/junit.ui/src/org/netbeans/modules/junit/ui/actions/TestClassInfoTask.java @@ -20,8 +20,13 @@ package org.netbeans.modules.junit.ui.actions; import com.sun.source.tree.Tree.Kind; import com.sun.source.util.TreePath; +import java.util.ArrayDeque; +import java.util.HashSet; import java.util.Iterator; import java.util.List; +import java.util.Queue; +import java.util.Set; +import java.util.stream.Collectors; import javax.lang.model.element.AnnotationMirror; import javax.lang.model.element.Element; import javax.lang.model.element.ElementKind; @@ -39,18 +44,20 @@ final class TestClassInfoTask implements CancellableTask<CompilationController> private final int caretPosition; private String className; private String methodName; - - private static String JUNIT4_ANNOTATION = "org.junit.Test"; //NOI18N - private static String JUNIT5_ANNOTATION = "org.junit.platform.commons.annotation.Testable"; //NOI18N - private static String TESTCASE = "junit.framework.TestCase"; //NOI18N + + private static final String JUNIT4_ANNOTATION = "org.junit.Test"; //NOI18N + private static final String JUNIT5_ANNOTATION = "org.junit.platform.commons.annotation.Testable"; //NOI18N + private static final String TESTCASE = "junit.framework.TestCase"; //NOI18N TestClassInfoTask(int caretPosition) { this.caretPosition = caretPosition; } + @Override public void cancel() { } + @Override public void run(CompilationController controller) throws Exception { controller.toPhase(Phase.RESOLVED); fileObject = controller.getFileObject(); @@ -72,23 +79,17 @@ final class TestClassInfoTask implements CancellableTask<CompilationController> } if (tp != null) { Element element = controller.getTrees().getElement(tp); - if (element != null) { - String mn = element.getSimpleName().toString(); - if (junit3) { - methodName = mn.startsWith("test") ? mn : null; //NOI18N - } else { - List<? extends AnnotationMirror> allAnnotationMirrors = elements.getAllAnnotationMirrors(element); - for (Iterator<? extends AnnotationMirror> it = allAnnotationMirrors.iterator(); it.hasNext();) { - AnnotationMirror annotationMirror = it.next(); - typeElement = (TypeElement) annotationMirror.getAnnotationType().asElement(); - if (typeElement.getQualifiedName().contentEquals(JUNIT4_ANNOTATION) - || isJunit5Testable(typeElement)) { - methodName = mn; - break; - } - } - } - } + if (element != null) { + String mn = element.getSimpleName().toString(); + if (junit3) { + methodName = mn.startsWith("test") ? mn : null; //NOI18N + } else { + List<? extends AnnotationMirror> allAnnotationMirrors = elements.getAllAnnotationMirrors(element); + if (isJunit4Test(allAnnotationMirrors) || isJunit5Testable(allAnnotationMirrors)) { + methodName = mn; + } + } + } } } @@ -103,13 +104,34 @@ final class TestClassInfoTask implements CancellableTask<CompilationController> String getMethodName() { return methodName; } + + private boolean isJunit4Test(List<? extends AnnotationMirror> allAnnotationMirrors) { + for (Iterator<? extends AnnotationMirror> it = allAnnotationMirrors.iterator(); it.hasNext();) { + AnnotationMirror annotationMirror = it.next(); + TypeElement typeElement = (TypeElement) annotationMirror.getAnnotationType().asElement(); + if (typeElement.getQualifiedName().contentEquals(JUNIT4_ANNOTATION)) { + return true; + } + } + return false; + } - private boolean isJunit5Testable(TypeElement typeElement) { - for (AnnotationMirror annotationMirror : typeElement.getAnnotationMirrors()) { - TypeElement parentTypeElement = (TypeElement) annotationMirror.getAnnotationType().asElement(); - if (parentTypeElement.getQualifiedName().contentEquals(JUNIT5_ANNOTATION)){ + private boolean isJunit5Testable(List<? extends AnnotationMirror> allAnnotationMirrors) { + Queue<AnnotationMirror> pendingMirrorsToCheck = new ArrayDeque<>(allAnnotationMirrors); + Set<AnnotationMirror> alreadyAddedMirrorsToCheck = new HashSet<>(allAnnotationMirrors); + + while (pendingMirrorsToCheck.peek()!= null) { + AnnotationMirror annotationMirror = pendingMirrorsToCheck.poll(); + TypeElement annotationElement = (TypeElement) annotationMirror.getAnnotationType().asElement(); + if (annotationElement.getQualifiedName().contentEquals(JUNIT5_ANNOTATION)) { return true; } + List<? extends AnnotationMirror> parentAnnotationMirrors = annotationElement.getAnnotationMirrors(); + Set<? extends AnnotationMirror> newlySeenParentAnnotationMirrors = parentAnnotationMirrors.stream() + .filter(parentAnnotationMirror -> !alreadyAddedMirrorsToCheck.contains(parentAnnotationMirror)) + .collect(Collectors.toSet()); + pendingMirrorsToCheck.addAll(newlySeenParentAnnotationMirrors); + alreadyAddedMirrorsToCheck.addAll(newlySeenParentAnnotationMirrors); } return false; } diff --git a/java/junit/src/org/netbeans/modules/junit/api/JUnitTestcase.java b/java/junit/src/org/netbeans/modules/junit/api/JUnitTestcase.java index eb86dd1..00912c3 100644 --- a/java/junit/src/org/netbeans/modules/junit/api/JUnitTestcase.java +++ b/java/junit/src/org/netbeans/modules/junit/api/JUnitTestcase.java @@ -32,8 +32,23 @@ import org.openide.filesystems.FileObject; public class JUnitTestcase extends Testcase{ private FileObject classFO = null; + /** + * @param name The method name of this test method + * @param type The type of test case + * @param session The session where this test is executed + */ public JUnitTestcase(String name, String type, TestSession session) { - super(name, type, session); + this(name, name, type, session); + } + + /** + * @param name The method name of this test method + * @param displayName The display name of this test method + * @param type The type of test case + * @param session the session where this test case is executed. + */ + public JUnitTestcase(String name, String displayName, String type, TestSession session) { + super(name, displayName, type, session); } @Override diff --git a/java/maven.junit/src/org/netbeans/modules/maven/junit/JUnitOutputListenerProvider.java b/java/maven.junit/src/org/netbeans/modules/maven/junit/JUnitOutputListenerProvider.java index 28a8cd2..4deadc9 100644 --- a/java/maven.junit/src/org/netbeans/modules/maven/junit/JUnitOutputListenerProvider.java +++ b/java/maven.junit/src/org/netbeans/modules/maven/junit/JUnitOutputListenerProvider.java @@ -599,7 +599,20 @@ public class JUnitOutputListenerProvider implements OutputProcessor { if (name.endsWith(nameSuffix)) { name = name.substring(0, name.length() - nameSuffix.length()); } - Testcase test = new JUnitTestcase(name, null, session); + String displayName = name; + String methodName = name; + //In some cases (e.g. parameterized tests) Surefire appends some extra text to the test method name. + //Remove anything past the first non-dot non-Java identifier character (i.e. anything that would not be part of a legal method name) + int dotCodePoint = ".".codePointAt(0); + for (int i = 0; i < name.length(); i++) { + int codePoint = name.codePointAt(i); + if (!Character.isJavaIdentifierPart(codePoint) && codePoint != dotCodePoint) { + methodName = methodName.substring(0, i); + break; + } + } + + Testcase test = new JUnitTestcase(methodName, displayName, null, session); Element stdout = testcase.getChild("system-out"); //NOI18N // If *-output.txt file exists do not log standard output here to avoid logging it twice. // By default surefire only reports standard output for failing testcases. --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@netbeans.apache.org For additional commands, e-mail: commits-h...@netbeans.apache.org For further information about the NetBeans mailing lists, visit: https://cwiki.apache.org/confluence/display/NETBEANS/Mailing+lists