diff options
2 files changed, 125 insertions, 15 deletions
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AnnotationTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AnnotationTest.java index f967c52489..26b37e44c7 100644 --- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AnnotationTest.java +++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AnnotationTest.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2018 IBM Corporation and others. + * Copyright (c) 2000, 2019 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -25,8 +25,9 @@ * bug 412153 - [1.8][compiler] Check validity of annotations which may be repeatable * Ulrich Grave <ulrich.grave@gmx.de> - Contributions for * bug 386692 - Missing "unused" warning on "autowired" fields - * Pierre-Yves B. <pyvesdev@gmail.com> - Contribution for + * Pierre-Yves B. <pyvesdev@gmail.com> - Contributions for * bug 542520 - [JUnit 5] Warning The method xxx from the type X is never used locally is shown when using MethodSource + * bug 546084 - Using Junit 5s MethodSource leads to ClassCastException *******************************************************************************/ package org.eclipse.jdt.core.tests.compiler.regression; @@ -12116,4 +12117,95 @@ public void testBug542520d() throws Exception { "----------\n", JavacTestOptions.Excuse.EclipseWarningConfiguredAsError); } +// https://bugs.eclipse.org/bugs/show_bug.cgi?id=546084 - Using Junit 5s MethodSource leads to +// ClassCastException - string concatenation, i.e. BinaryExpression in @MethodSource annotation +public void testBug546084a() throws Exception { + Runner runner = new Runner(); + runner.customOptions = getCompilerOptions(); + runner.customOptions.put(CompilerOptions.OPTION_ReportUnusedPrivateMember, CompilerOptions.ERROR); + runner.testFiles = + new String[] { + JUNIT_METHODSOURCE_NAME, + JUNIT_METHODSOURCE_CONTENT, + "ExampleTest.java", + "import java.util.Arrays;\n" + + "import java.util.List;\n" + + "import org.junit.jupiter.params.provider.MethodSource;\n" + + "public class ExampleTest {\n" + + "\n" + + " private final String TEST_METHOD_PREFIX = \"get\";\n" + + " @MethodSource(TEST_METHOD_PREFIX + \"Integers\")\n" + + " void testIntegers(Integer integer) {}\n" + + " \n" + + " private static List<Integer> getIntegers() {\n" + + " return Arrays.asList(0, 5, 1);\n" + + " }\n" + + "}\n", + }; + runner.runConformTest(); +} +// https://bugs.eclipse.org/bugs/show_bug.cgi?id=546084 - Using Junit 5s MethodSource leads to +// ClassCastException - non string value, e.g. ClassLiteralAccess in @MethodSource annotation +public void testBug546084b() throws Exception { + Map customOptions = getCompilerOptions(); + customOptions.put(CompilerOptions.OPTION_ReportUnusedPrivateMember, CompilerOptions.ERROR); + this.runNegativeTest( + true, + new String[] { + JUNIT_METHODSOURCE_NAME, + JUNIT_METHODSOURCE_CONTENT, + "ExampleTest.java", + "import java.util.Arrays;\n" + + "import java.util.List;\n" + + "import org.junit.jupiter.params.provider.MethodSource;\n" + + "public class ExampleTest {\n" + + "\n" + + " @MethodSource(Object.class)\n" + + " void testIntegers(Integer integer) {}\n" + + " \n" + + " private static List<Integer> getIntegers(int i) {\n" + + " return Arrays.asList(0, 5, 1);\n" + + " }\n" + + "}\n", + }, + null, customOptions, + "----------\n" + + "1. ERROR in ExampleTest.java (at line 6)\n" + + " @MethodSource(Object.class)\n" + + " ^^^^^^^^^^^^\n" + + "Type mismatch: cannot convert from Class<Object> to String[]\n" + + "----------\n" + + "2. ERROR in ExampleTest.java (at line 9)\n" + + " private static List<Integer> getIntegers(int i) {\n" + + " ^^^^^^^^^^^^^^^^^^\n" + + "The method getIntegers(int) from the type ExampleTest is never used locally\n" + + "----------\n", + JavacTestOptions.Excuse.EclipseWarningConfiguredAsError); +} +//https://bugs.eclipse.org/bugs/show_bug.cgi?id=546084 - Using Junit 5s MethodSource leads to +//ClassCastException - array of string values, e.g. ArrayInitializer in @MethodSource annotation +public void testBug546084c() throws Exception { + Runner runner = new Runner(); + runner.customOptions = getCompilerOptions(); + runner.customOptions.put(CompilerOptions.OPTION_ReportUnusedPrivateMember, CompilerOptions.ERROR); + runner.testFiles = + new String[] { + JUNIT_METHODSOURCE_NAME, + JUNIT_METHODSOURCE_CONTENT, + "ExampleTest.java", + "import java.util.Arrays;\n" + + "import java.util.List;\n" + + "import org.junit.jupiter.params.provider.MethodSource;\n" + + "public class ExampleTest {\n" + + "\n" + + " @MethodSource({ \"getIntegers\" })\n" + + " void testIntegers(Integer integer) {}\n" + + " \n" + + " private static List<Integer> getIntegers() {\n" + + " return Arrays.asList(0, 5, 1);\n" + + " }\n" + + "}\n", + }; + runner.runConformTest(); +} } diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeDeclaration.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeDeclaration.java index afb99dfd62..34bc92b70f 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeDeclaration.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeDeclaration.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2018 IBM Corporation and others. + * Copyright (c) 2000, 2019 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -18,8 +18,9 @@ * Bug 424727 - [compiler][null] NullPointerException in nullAnnotationUnsupportedLocation(ProblemReporter.java:5708) * Bug 457210 - [1.8][compiler][null] Wrong Nullness errors given on full build build but not on incremental build? * Keigo Imai - Contribution for bug 388903 - Cannot extend inner class as an anonymous class when it extends the outer class - * Pierre-Yves B. <pyvesdev@gmail.com> - Contribution for + * Pierre-Yves B. <pyvesdev@gmail.com> - Contributions for * Bug 542520 - [JUnit 5] Warning The method xxx from the type X is never used locally is shown when using MethodSource + * Bug 546084 - Using Junit 5s MethodSource leads to ClassCastException *******************************************************************************/ package org.eclipse.jdt.internal.compiler.ast; @@ -782,25 +783,42 @@ private void internalAnalyseCode(FlowContext flowContext, FlowInfo flowInfo) { private SimpleSetOfCharArray getJUnitMethodSourceValues() { SimpleSetOfCharArray junitMethodSourceValues = new SimpleSetOfCharArray(); for (AbstractMethodDeclaration methodDeclaration : this.methods) { - junitMethodSourceValues.add(getJUnitMethodSourceValue(methodDeclaration)); + if (methodDeclaration.annotations != null) { + for (Annotation annotation : methodDeclaration.annotations) { + if (annotation.resolvedType != null && annotation.resolvedType.id == TypeIds.T_OrgJunitJupiterParamsProviderMethodSource) { + addJUnitMethodSourceValues(junitMethodSourceValues, annotation, methodDeclaration.selector); + } + } + } } return junitMethodSourceValues; } -private char[] getJUnitMethodSourceValue(AbstractMethodDeclaration methodDeclaration) { - if (methodDeclaration.annotations != null) { - for (Annotation annotation : methodDeclaration.annotations) { - if (annotation.resolvedType != null && annotation.resolvedType.id == TypeIds.T_OrgJunitJupiterParamsProviderMethodSource) { - for (MemberValuePair memberValuePair : annotation.memberValuePairs()) { - if (CharOperation.equals(memberValuePair.name, TypeConstants.VALUE)) { - return ((StringLiteral) memberValuePair.value).source; - } +private void addJUnitMethodSourceValues(SimpleSetOfCharArray junitMethodSourceValues, Annotation annotation, char[] methodName) { + for (MemberValuePair memberValuePair : annotation.memberValuePairs()) { + if (CharOperation.equals(memberValuePair.name, TypeConstants.VALUE)) { + Expression value = memberValuePair.value; + if (value instanceof ArrayInitializer) { // e.g. @MethodSource({ "someMethod" }) + ArrayInitializer arrayInitializer = (ArrayInitializer) value; + for (Expression arrayValue : arrayInitializer.expressions) { + junitMethodSourceValues.add(getValueAsChars(arrayValue)); } - // value member not specified (i.e. marker annotation): JUnit 5 defaults to the test method's name - return methodDeclaration.selector; + } else { + junitMethodSourceValues.add(getValueAsChars(value)); } + return; } } + // value member not specified (i.e. marker annotation): JUnit 5 defaults to the test method's name + junitMethodSourceValues.add(methodName); +} + +private char[] getValueAsChars(Expression value) { + if (value instanceof StringLiteral) { // e.g. "someMethod" + return ((StringLiteral) value).source; + } else if (value.constant instanceof StringConstant) { // e.g. SOME_CONSTANT + "value" + return ((StringConstant) value.constant).stringValue().toCharArray(); + } return CharOperation.NO_CHAR; } |