You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by pa...@apache.org on 2020/04/04 06:54:16 UTC
[groovy] 02/02: GROOVY-9492: Relax groovy.test.NotYetImplemented
dependency on JUnit 4's AssertionFailedError (adjustments for Groovy 3)
This is an automated email from the ASF dual-hosted git repository.
paulk pushed a commit to branch GROOVY_3_0_X
in repository https://gitbox.apache.org/repos/asf/groovy.git
commit 40752788ffd63343f4a7497131a4f0397cd4bc26
Author: Paul King <pa...@asert.com.au>
AuthorDate: Sat Apr 4 16:52:42 2020 +1000
GROOVY-9492: Relax groovy.test.NotYetImplemented dependency on JUnit 4's AssertionFailedError (adjustments for Groovy 3)
---
.../main/java/groovy/test/NotYetImplemented.java | 3 +-
.../java/groovy/transform/NotYetImplemented.java | 2 +-
.../NotYetImplementedLegacyASTTransformation.java | 77 ++++++++++++++++++++++
.../NotYetImplementedTransformTest.groovy | 21 ++++++
4 files changed, 101 insertions(+), 2 deletions(-)
diff --git a/subprojects/groovy-test/src/main/java/groovy/test/NotYetImplemented.java b/subprojects/groovy-test/src/main/java/groovy/test/NotYetImplemented.java
index 712b852..2c948a8 100644
--- a/subprojects/groovy-test/src/main/java/groovy/test/NotYetImplemented.java
+++ b/subprojects/groovy-test/src/main/java/groovy/test/NotYetImplemented.java
@@ -33,7 +33,8 @@ import java.lang.annotation.Target;
* This is helpful for tests that don't currently work but should work one day,
* when the tested functionality has been implemented.
* <p>
- * Note: JUnit 3 users should use the optional {@code exception} attribute, e.g. {@code @NotYetImplemented(exception=junit.framework.AssertionFailedError)}.
+ * Note: JUnit 3 users should use the optional {@code exception} attribute, e.g. {@code @NotYetImplemented(exception=junit.framework.AssertionFailedError)}
+ * or the legacy {@code groovy.transform.NotYetImplemented} annotation.
*
* @since 3.0.0
*/
diff --git a/subprojects/groovy-test/src/main/java/groovy/transform/NotYetImplemented.java b/subprojects/groovy-test/src/main/java/groovy/transform/NotYetImplemented.java
index 0f9ddf3..cb39797 100644
--- a/subprojects/groovy-test/src/main/java/groovy/transform/NotYetImplemented.java
+++ b/subprojects/groovy-test/src/main/java/groovy/transform/NotYetImplemented.java
@@ -42,6 +42,6 @@ import java.lang.annotation.Target;
@java.lang.annotation.Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
-@GroovyASTTransformationClass("org.apache.groovy.test.transform.NotYetImplementedASTTransformation")
+@GroovyASTTransformationClass("org.apache.groovy.test.transform.NotYetImplementedLegacyASTTransformation")
public @interface NotYetImplemented {
}
diff --git a/subprojects/groovy-test/src/main/java/org/apache/groovy/test/transform/NotYetImplementedLegacyASTTransformation.java b/subprojects/groovy-test/src/main/java/org/apache/groovy/test/transform/NotYetImplementedLegacyASTTransformation.java
new file mode 100644
index 0000000..2dcb969
--- /dev/null
+++ b/subprojects/groovy-test/src/main/java/org/apache/groovy/test/transform/NotYetImplementedLegacyASTTransformation.java
@@ -0,0 +1,77 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.groovy.test.transform;
+
+import org.codehaus.groovy.ast.ASTNode;
+import org.codehaus.groovy.ast.AnnotationNode;
+import org.codehaus.groovy.ast.ClassHelper;
+import org.codehaus.groovy.ast.ClassNode;
+import org.codehaus.groovy.ast.MethodNode;
+import org.codehaus.groovy.ast.stmt.BlockStatement;
+import org.codehaus.groovy.ast.stmt.ReturnStatement;
+import org.codehaus.groovy.ast.stmt.ThrowStatement;
+import org.codehaus.groovy.ast.stmt.TryCatchStatement;
+import org.codehaus.groovy.control.CompilePhase;
+import org.codehaus.groovy.control.SourceUnit;
+import org.codehaus.groovy.transform.AbstractASTTransformation;
+import org.codehaus.groovy.transform.GroovyASTTransformation;
+
+import java.util.Arrays;
+import junit.framework.AssertionFailedError;
+
+import static org.codehaus.groovy.ast.tools.GeneralUtils.args;
+import static org.codehaus.groovy.ast.tools.GeneralUtils.block;
+import static org.codehaus.groovy.ast.tools.GeneralUtils.catchS;
+import static org.codehaus.groovy.ast.tools.GeneralUtils.constX;
+import static org.codehaus.groovy.ast.tools.GeneralUtils.ctorX;
+import static org.codehaus.groovy.ast.tools.GeneralUtils.param;
+import static org.codehaus.groovy.ast.tools.GeneralUtils.throwS;
+import static org.codehaus.groovy.ast.tools.GeneralUtils.tryCatchS;
+
+/**
+ * Generates code for the legacy {@code @NotYetImplemented} annotation.
+ *
+ * @see groovy.transform.NotYetImplemented
+ */
+@Deprecated
+@GroovyASTTransformation(phase = CompilePhase.CANONICALIZATION)
+public class NotYetImplementedLegacyASTTransformation extends AbstractASTTransformation {
+
+ private static final ClassNode CATCH_TYPE = ClassHelper.make(Throwable.class);
+ private static final ClassNode THROW_TYPE = ClassHelper.make(AssertionFailedError.class); // TODO: java.lang.AssertionError
+
+ public void visit(ASTNode[] nodes, SourceUnit source) {
+ if (!(nodes.length == 2 && nodes[0] instanceof AnnotationNode && nodes[1] instanceof MethodNode)) {
+ throw new RuntimeException("Internal error: expecting [AnnotationNode, MethodNode] but got: " + Arrays.toString(nodes));
+ }
+
+ MethodNode methodNode = (MethodNode) nodes[1];
+
+ if (methodNode.getCode() instanceof BlockStatement && !((BlockStatement) methodNode.getCode()).isEmpty()) {
+ // wrap code in try/catch with return for failure path followed by throws for success path
+
+ TryCatchStatement tryCatchStatement = tryCatchS(methodNode.getCode());
+ tryCatchStatement.addCatch(catchS(param(CATCH_TYPE, "ignore"), ReturnStatement.RETURN_NULL_OR_VOID));
+
+ ThrowStatement throwStatement = throwS(ctorX(THROW_TYPE, args(constX("Method is marked with @NotYetImplemented but passes unexpectedly"))));
+
+ methodNode.setCode(block(tryCatchStatement, throwStatement));
+ }
+ }
+}
diff --git a/subprojects/groovy-test/src/test/groovy/org/apache/groovy/test/transform/NotYetImplementedTransformTest.groovy b/subprojects/groovy-test/src/test/groovy/org/apache/groovy/test/transform/NotYetImplementedTransformTest.groovy
index b4fbad5..36b4fa5 100644
--- a/subprojects/groovy-test/src/test/groovy/org/apache/groovy/test/transform/NotYetImplementedTransformTest.groovy
+++ b/subprojects/groovy-test/src/test/groovy/org/apache/groovy/test/transform/NotYetImplementedTransformTest.groovy
@@ -18,6 +18,7 @@
*/
package org.apache.groovy.test.transform
+import junit.framework.AssertionFailedError
import org.junit.Test
final class NotYetImplementedTransformTest {
@@ -61,6 +62,26 @@ final class NotYetImplementedTransformTest {
}
@Test
+ @Deprecated
+ void testNotYetImplementedLegacyJunit3PassThrough() {
+ def output = shell.evaluate('''
+ import groovy.test.GroovyTestCase
+ import groovy.transform.NotYetImplemented
+
+ class MyTests extends GroovyTestCase {
+ @NotYetImplemented void testThatPasses() {
+ assertTrue(true)
+ }
+ }
+
+ junit.textui.TestRunner.run(new junit.framework.TestSuite(MyTests))
+ ''')
+
+ assert output.failureCount() == 1 : 'succeeding test method marked with legacy @NotYetImplemented must throw an AssertionFailedError'
+ assert output.failures().nextElement().thrownException() instanceof AssertionFailedError : 'succeeding test method marked with legacy @NotYetImplemented must throw an AssertionFailedError'
+ }
+
+ @Test
void testNotYetImplementedJunit3PassThrough() {
def output = shell.evaluate('''
import groovy.test.GroovyTestCase