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 2019/05/05 22:59:47 UTC

[groovy] 04/04: GROOVY-9065: Add support for @Testable annotation in JUnit5Runner (closes #922)

This is an automated email from the ASF dual-hosted git repository.

paulk pushed a commit to branch GROOVY_2_5_X
in repository https://gitbox.apache.org/repos/asf/groovy.git

commit 4d069746b7a084f8da5da9d6802f65c916774f04
Author: Paul King <pa...@asert.com.au>
AuthorDate: Sun May 5 20:54:34 2019 +1000

    GROOVY-9065: Add support for @Testable annotation in JUnit5Runner (closes #922)
---
 .../java/groovy/junit5/plugin/JUnit5Runner.java    | 31 +++++++++++-----
 .../src/test/groovy/TestableTest.groovy            | 42 ++++++++++++++++++++++
 .../src/test/groovy/testable/MyTest.groovy         | 28 +++++++++++++++
 .../src/test/groovy/testable/MyTestable.groovy     | 29 +++++++++++++++
 .../test/groovy/testable/TestableExtension.groovy  | 41 +++++++++++++++++++++
 5 files changed, 163 insertions(+), 8 deletions(-)

diff --git a/subprojects/groovy-test-junit5/src/main/java/groovy/junit5/plugin/JUnit5Runner.java b/subprojects/groovy-test-junit5/src/main/java/groovy/junit5/plugin/JUnit5Runner.java
index 8cd13f6..15e6709 100644
--- a/subprojects/groovy-test-junit5/src/main/java/groovy/junit5/plugin/JUnit5Runner.java
+++ b/subprojects/groovy-test-junit5/src/main/java/groovy/junit5/plugin/JUnit5Runner.java
@@ -41,14 +41,16 @@ public class JUnit5Runner implements GroovyRunner {
      */
     @Override
     public boolean canRun(Class<?> scriptClass, GroovyClassLoader loader) {
+        if (!tryLoadClass("org.junit.jupiter.api.Test", loader)) {
+            return false;
+        }
         if (isJUnit5AnnotationPresent(scriptClass.getAnnotations(), loader)) {
             return true;
-        } else {
-            Method[] methods = scriptClass.getMethods();
-            for (Method method : methods) {
-                if (isJUnit5AnnotationPresent(method.getAnnotations(), loader)) {
-                    return true;
-                }
+        }
+        Method[] methods = scriptClass.getMethods();
+        for (Method method : methods) {
+            if (isJUnit5AnnotationPresent(method.getAnnotations(), loader)) {
+                return true;
             }
         }
         return false;
@@ -56,17 +58,30 @@ public class JUnit5Runner implements GroovyRunner {
 
     private boolean isJUnit5AnnotationPresent(Annotation[] annotations, GroovyClassLoader loader) {
         for (Annotation annotation : annotations) {
-            String name = annotation.annotationType().getName();
+            Class<? extends Annotation> type = annotation.annotationType();
+            String name = type.getName();
             if (name.startsWith("org.junit.jupiter.api.") && tryLoadClass(name, loader)) {
                 return true;
             }
+            if (isJUnit5TestableMetaAnnotationPresent(type) && tryLoadClass(name, loader)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private boolean isJUnit5TestableMetaAnnotationPresent(Class<? extends Annotation> type) {
+        for (Annotation annotation : type.getAnnotations()) {
+            if ("org.junit.platform.commons.annotation.Testable".equals(annotation.annotationType().getName())) {
+                return true;
+            }
         }
         return false;
     }
 
     private boolean tryLoadClass(String name, GroovyClassLoader loader) {
         try {
-            loader.loadClass("org.junit.jupiter.api.Test");
+            loader.loadClass(name);
             return true;
         } catch (ClassNotFoundException ignore) {
             // fall through
diff --git a/subprojects/groovy-test-junit5/src/test/groovy/TestableTest.groovy b/subprojects/groovy-test-junit5/src/test/groovy/TestableTest.groovy
new file mode 100644
index 0000000..57cb874
--- /dev/null
+++ b/subprojects/groovy-test-junit5/src/test/groovy/TestableTest.groovy
@@ -0,0 +1,42 @@
+/*
+ *  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.
+ */
+import org.junit.jupiter.api.Test
+import testable.TestableExtension
+
+class TestableTest {
+    @Test
+    void testTestableRecognized() {
+        new GroovyShell().run '''
+            import testable.*
+
+            @MyTestable
+            class Dummy {
+                @MyTest
+                void testNumber1() {}
+
+                @MyTest
+                void testNumber2() {}
+
+                @MyTest
+                void testNumber3() {}
+            }
+        ''', 'DummyName'
+        assert TestableExtension.testNames == ['testNumber1', 'testNumber2', 'testNumber3']
+    }
+}
diff --git a/subprojects/groovy-test-junit5/src/test/groovy/testable/MyTest.groovy b/subprojects/groovy-test-junit5/src/test/groovy/testable/MyTest.groovy
new file mode 100644
index 0000000..96018d5
--- /dev/null
+++ b/subprojects/groovy-test-junit5/src/test/groovy/testable/MyTest.groovy
@@ -0,0 +1,28 @@
+/*
+ *  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 testable
+
+import org.junit.jupiter.api.Test
+
+import java.lang.annotation.*
+
+@Test
+@Target(ElementType.METHOD)
+@Retention(RetentionPolicy.RUNTIME)
+@interface MyTest {}
diff --git a/subprojects/groovy-test-junit5/src/test/groovy/testable/MyTestable.groovy b/subprojects/groovy-test-junit5/src/test/groovy/testable/MyTestable.groovy
new file mode 100644
index 0000000..34eb925
--- /dev/null
+++ b/subprojects/groovy-test-junit5/src/test/groovy/testable/MyTestable.groovy
@@ -0,0 +1,29 @@
+/*
+ *  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 testable
+
+import java.lang.annotation.*
+import org.junit.jupiter.api.extension.ExtendWith
+import org.junit.platform.commons.annotation.Testable
+
+@Testable
+@ExtendWith(TestableExtension)
+@Target(ElementType.TYPE)
+@Retention(RetentionPolicy.RUNTIME)
+@interface MyTestable {}
diff --git a/subprojects/groovy-test-junit5/src/test/groovy/testable/TestableExtension.groovy b/subprojects/groovy-test-junit5/src/test/groovy/testable/TestableExtension.groovy
new file mode 100644
index 0000000..e80c9ff
--- /dev/null
+++ b/subprojects/groovy-test-junit5/src/test/groovy/testable/TestableExtension.groovy
@@ -0,0 +1,41 @@
+/*
+ *  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 testable
+
+import org.junit.jupiter.api.extension.BeforeEachCallback
+import org.junit.jupiter.api.extension.BeforeAllCallback
+import org.junit.jupiter.api.extension.ExtensionContext
+
+/**
+ * Trivial extension that logs test names. Not designed for anything other than
+ * it usage in this test suite.
+ */
+class TestableExtension implements BeforeAllCallback, BeforeEachCallback {
+    public static List<String> testNames = []
+
+    @Override
+    void beforeEach(ExtensionContext context) throws Exception {
+        testNames << context.requiredTestMethod.name
+    }
+
+    @Override
+    void beforeAll(ExtensionContext context) throws Exception {
+        testNames.clear()
+    }
+}