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

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

commit fc0f18944b029502e1b1971aa47b3df39ab97911
Author: Eric Milles <[email protected]>
AuthorDate: Thu Apr 24 14:58:45 2025 -0500

    refactor test
---
 .../classgen/ClassCompletionVerifierTest.java      | 233 +++++++++++----------
 1 file changed, 124 insertions(+), 109 deletions(-)

diff --git 
a/src/test/groovy/org/codehaus/groovy/classgen/ClassCompletionVerifierTest.java 
b/src/test/groovy/org/codehaus/groovy/classgen/ClassCompletionVerifierTest.java
index 157372a1b5..acd1652586 100644
--- 
a/src/test/groovy/org/codehaus/groovy/classgen/ClassCompletionVerifierTest.java
+++ 
b/src/test/groovy/org/codehaus/groovy/classgen/ClassCompletionVerifierTest.java
@@ -24,182 +24,199 @@ import org.codehaus.groovy.ast.FieldNode;
 import org.codehaus.groovy.ast.MethodNode;
 import org.codehaus.groovy.ast.Parameter;
 import org.codehaus.groovy.control.SourceUnit;
+import org.junit.Test;
 
 import java.io.PrintWriter;
 import java.io.StringWriter;
 
-public class ClassCompletionVerifierTest extends TestSupport {
-    private SourceUnit source;
-    private ClassCompletionVerifier verifier;
-    private static final String ABSTRACT_FINAL_CLASS = "AbstractFinalClass";
-    private static final String FINAL_INTERFACE = "FinalInterface";
-    private static final String EXPECTED_CLASS_MODIFIER_ERROR_MESSAGE =
-            "The class '" + ABSTRACT_FINAL_CLASS + "' must not be both final 
and abstract.";
-    private static final String EXPECTED_INTERFACE_MODIFIER_ERROR_MESSAGE =
-            "The interface '" + FINAL_INTERFACE + "' must not be final. It is 
by definition abstract.";
-    private static final String EXPECTED_INTERFACE_FINAL_METHOD_ERROR_MESSAGE =
-            "The method 'java.lang.Object xxx()' from interface 'zzz' must not 
be final. It is by definition abstract.";
-    private static final String EXPECTED_INTERFACE_STATIC_METHOD_ERROR_MESSAGE 
=
-            "The method 'java.lang.Object yyy()' from interface 'zzz' must not 
be static. Only fields may be static in an interface.";
-    private static final String EXPECTED_TRANSIENT_CLASS_ERROR_MESSAGE =
-            "The class 'DodgyClass' has an incorrect modifier transient.";
-    // can't check synchronized here as it doubles up with ACC_SUPER
-    //private static final String EXPECTED_SYNCHRONIZED_CLASS_ERROR_MESSAGE =
-    //        "The class 'DodgyClass' has an incorrect modifier synchronized.";
-    private static final String EXPECTED_NATIVE_CLASS_ERROR_MESSAGE =
-            "The class 'DodgyClass' has an incorrect modifier native.";
-    private static final String EXPECTED_VOLATILE_CLASS_ERROR_MESSAGE =
-            "The class 'DodgyClass' has an incorrect modifier volatile.";
-    private static final String EXPECTED_DUPLICATE_METHOD_ERROR_CLASS_MESSAGE =
-            "Repetitive method name/signature for method 'java.lang.Object 
xxx()' in class 'zzz'.";
-    private static final String 
EXPECTED_DUPLICATE_METHOD_ERROR_INTERFACE_MESSAGE =
-            "Repetitive method name/signature for method 'java.lang.Object 
xxx(java.lang.String)' in interface 'zzz'.";
-    // can't check volatile here as it doubles up with bridge
-    //private static final String EXPECTED_VOLATILE_METHOD_ERROR_MESSAGE =
-    //        "The method 'java.lang.Object vo()' has an incorrect modifier 
volatile.";
-    private static final String EXPECTED_STRICT_METHOD_ERROR_MESSAGE =
-            "The method 'java.lang.Object st()' has an incorrect modifier 
strictfp.";
-    private static final String EXPECTED_NATIVE_METHOD_ERROR_MESSAGE =
-            "The method 'java.lang.Object na()' has an incorrect modifier 
native.";
-    private static final String EXPECTED_SYNCHRONIZED_METHOD_ERROR_MESSAGE =
-            "The method 'java.lang.Object sy()' has an incorrect modifier 
synchronized.";
-    private static final String EXPECTED_TRANSIENT_METHOD_ERROR_MESSAGE =
-            "The method 'java.lang.Object tr()' has an incorrect modifier 
transient.";
-    private static final String EXPECTED_PROTECTED_FIELD_ERROR_MESSAGE =
-            "The field 'prof' is not 'public static final' but is defined in 
interface 'zzz'.";
-    private static final String EXPECTED_PRIVATE_FIELD_ERROR_MESSAGE =
-            "The field 'prif' is not 'public static final' but is defined in 
interface 'zzz'.";
-    private static final String EXPECTED_PROTECTED_METHOD_ERROR_MESSAGE =
-            "Method 'prom' is protected but should be public in interface 
'zzz'.";
-    private static final String EXPECTED_PRIVATE_METHOD_ERROR_MESSAGE =
-            "Method 'prim' is private but should be public in interface 
'zzz'.";
-    private static final String EXPECTED_ABSTRACT_PRIVATE_METHOD_ERROR_MESSAGE 
=
-            "Method 'y' from class 'X' must not be private as it is declared 
as an abstract method.";
-
-    protected void setUp() throws Exception {
-        super.setUp();
-        source = SourceUnit.create("dummy.groovy", "");
-        verifier = new ClassCompletionVerifier(source);
-    }
-
-    public void testDetectsAbstractPrivateMethod() throws Exception {
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.objectweb.asm.Opcodes.ACC_ABSTRACT;
+import static org.objectweb.asm.Opcodes.ACC_FINAL;
+import static org.objectweb.asm.Opcodes.ACC_INTERFACE;
+import static org.objectweb.asm.Opcodes.ACC_NATIVE;
+import static org.objectweb.asm.Opcodes.ACC_PRIVATE;
+import static org.objectweb.asm.Opcodes.ACC_PROTECTED;
+import static org.objectweb.asm.Opcodes.ACC_PUBLIC;
+import static org.objectweb.asm.Opcodes.ACC_STATIC;
+import static org.objectweb.asm.Opcodes.ACC_STRICT;
+import static org.objectweb.asm.Opcodes.ACC_SYNCHRONIZED;
+import static org.objectweb.asm.Opcodes.ACC_TRANSIENT;
+import static org.objectweb.asm.Opcodes.ACC_VOLATILE;
+
+public final class ClassCompletionVerifierTest {
+
+    private SourceUnit source = SourceUnit.create("dummy.groovy", "");
+    private ClassCompletionVerifier verifier = new 
ClassCompletionVerifier(source);
+
+    @Test
+    public void shouldDetectAbstractPrivateMethod() {
         ClassNode node = new ClassNode("X", ACC_ABSTRACT, 
ClassHelper.OBJECT_TYPE);
         node.addMethod(new MethodNode("y", ACC_PRIVATE | ACC_ABSTRACT, 
ClassHelper.VOID_TYPE, Parameter.EMPTY_ARRAY, ClassNode.EMPTY_ARRAY, null));
+
         verifier.visitClass(node);
-        checkErrorMessage(EXPECTED_ABSTRACT_PRIVATE_METHOD_ERROR_MESSAGE);
+
+        checkErrorMessage("Method 'y' from class 'X' must not be private as it 
is declared as an abstract method.");
     }
 
-    public void testDetectsFinalAbstractClass() throws Exception {
+    @Test
+    public void shouldDetectFinalAbstractClass() {
         checkVisitErrors("FinalClass", ACC_FINAL, false);
         checkVisitErrors("AbstractClass", ACC_ABSTRACT, false);
-        checkVisitErrors(ABSTRACT_FINAL_CLASS, ACC_ABSTRACT | ACC_FINAL, true);
-        checkErrorMessage(EXPECTED_CLASS_MODIFIER_ERROR_MESSAGE);
+        checkVisitErrors("AbstractFinalClass", ACC_ABSTRACT | ACC_FINAL, true);
+        checkErrorMessage("The class 'AbstractFinalClass' must not be both 
final and abstract.");
     }
 
-    public void testDetectsDuplicateMethodsForClassNoParams() throws Exception 
{
-        checkDetectsDuplicateMethods(0, 
EXPECTED_DUPLICATE_METHOD_ERROR_CLASS_MESSAGE, Parameter.EMPTY_ARRAY);
+    @Test
+    public void shouldDetectDuplicateMethodsForClassNoParams() {
+        tryDetectDuplicateMethods(ACC_ABSTRACT, "Repetitive method 
name/signature for method 'java.lang.Object xxx()' in class 'zzz'.");
     }
 
-    public void testDetectsDuplicateMethodsForInterfaceOneParam() throws 
Exception {
-        Parameter[] stringParam = {new Parameter(ClassHelper.STRING_TYPE, 
"x")};
-        checkDetectsDuplicateMethods(ACC_INTERFACE, 
EXPECTED_DUPLICATE_METHOD_ERROR_INTERFACE_MESSAGE, stringParam);
+    @Test
+    public void shouldDetectDuplicateMethodsForInterfaceOneParam() {
+        tryDetectDuplicateMethods(ACC_INTERFACE, "Repetitive method 
name/signature for method 'java.lang.Object xxx(java.lang.String)' in interface 
'zzz'.", new Parameter(ClassHelper.STRING_TYPE, "x"));
     }
 
-    private void checkDetectsDuplicateMethods(int modifiers, String 
expectedErrorMessage, Parameter[] params) {
+    private void tryDetectDuplicateMethods(int modifiers, String 
expectedErrorMessage, Parameter... params) {
         ClassNode node = new ClassNode("zzz", modifiers, 
ClassHelper.OBJECT_TYPE);
         node.addMethod(new MethodNode("xxx", ACC_PUBLIC, 
ClassHelper.OBJECT_TYPE, params, ClassNode.EMPTY_ARRAY, null));
         node.addMethod(new MethodNode("xxx", ACC_PUBLIC, 
ClassHelper.OBJECT_TYPE, params, ClassNode.EMPTY_ARRAY, null));
+
         verifier.visitClass(node);
+
         checkErrorCount(2);
         checkErrorMessage(expectedErrorMessage);
     }
 
-    public void testDetectsIncorrectOtherModifier() throws Exception {
+    @Test
+    public void shouldDetectIncorrectOtherModifier() {
         // can't check synchronized here as it doubles up with ACC_SUPER
         checkVisitErrors("DodgyClass", ACC_TRANSIENT | ACC_VOLATILE | 
ACC_NATIVE, true);
-        checkErrorMessage(EXPECTED_TRANSIENT_CLASS_ERROR_MESSAGE);
-        checkErrorMessage(EXPECTED_VOLATILE_CLASS_ERROR_MESSAGE);
-        checkErrorMessage(EXPECTED_NATIVE_CLASS_ERROR_MESSAGE);
+        checkErrorMessage("The class 'DodgyClass' has an incorrect modifier 
transient.");
+        checkErrorMessage("The class 'DodgyClass' has an incorrect modifier 
volatile.");
+        checkErrorMessage("The class 'DodgyClass' has an incorrect modifier 
native.");
     }
 
-    public void testDetectsFinalAbstractInterface() throws Exception {
-        checkVisitErrors(FINAL_INTERFACE, ACC_ABSTRACT | ACC_FINAL | 
ACC_INTERFACE, true);
-        checkErrorMessage(EXPECTED_INTERFACE_MODIFIER_ERROR_MESSAGE);
+    @Test
+    public void shouldDetectFinalAbstractInterface() {
+        checkVisitErrors("FinalInterface", ACC_ABSTRACT | ACC_FINAL | 
ACC_INTERFACE, true);
+        checkErrorMessage("The interface 'FinalInterface' must not be final. 
It is by definition abstract.");
     }
 
-    public void testDetectsFinalAndStaticMethodsInInterface() throws Exception 
{
+    @Test
+    public void shouldDetectFinalMethodsInInterface() {
         ClassNode node = new ClassNode("zzz", ACC_ABSTRACT | ACC_INTERFACE, 
ClassHelper.OBJECT_TYPE);
         node.addMethod(new MethodNode("xxx", ACC_PUBLIC | ACC_FINAL, 
ClassHelper.OBJECT_TYPE, Parameter.EMPTY_ARRAY, ClassNode.EMPTY_ARRAY, null));
         node.addMethod(new MethodNode("yyy", ACC_PUBLIC | ACC_STATIC, 
ClassHelper.OBJECT_TYPE, Parameter.EMPTY_ARRAY, ClassNode.EMPTY_ARRAY, null));
-        addDummyConstructor(node);
+        addStaticConstructor(node);
+
         verifier.visitClass(node);
+
         checkErrorCount(2);
-        checkErrorMessage(EXPECTED_INTERFACE_FINAL_METHOD_ERROR_MESSAGE);
-        checkErrorMessage(EXPECTED_INTERFACE_STATIC_METHOD_ERROR_MESSAGE);
+        checkErrorMessage("The method 'java.lang.Object xxx()' from interface 
'zzz' must not be final. It is by definition abstract.");
+        checkErrorMessage("The method 'java.lang.Object yyy()' from interface 
'zzz' must not be static. Only fields may be static in an interface.");
     }
 
-    public void testDetectsIncorrectMethodModifiersInInterface() throws 
Exception {
-        // can't check volatile here as it doubles up with bridge
+    @Test
+    public void shouldDetectIncorrectMethodModifiersInInterface() {
         ClassNode node = new ClassNode("zzz", ACC_ABSTRACT | ACC_INTERFACE, 
ClassHelper.OBJECT_TYPE);
-        node.addMethod(new MethodNode("st", ACC_STRICT, 
ClassHelper.OBJECT_TYPE, Parameter.EMPTY_ARRAY, ClassNode.EMPTY_ARRAY, null));
         node.addMethod(new MethodNode("na", ACC_NATIVE, 
ClassHelper.OBJECT_TYPE, Parameter.EMPTY_ARRAY, ClassNode.EMPTY_ARRAY, null));
+        node.addMethod(new MethodNode("st", ACC_STRICT, 
ClassHelper.OBJECT_TYPE, Parameter.EMPTY_ARRAY, ClassNode.EMPTY_ARRAY, null));
         node.addMethod(new MethodNode("sy", ACC_SYNCHRONIZED, 
ClassHelper.OBJECT_TYPE, Parameter.EMPTY_ARRAY, ClassNode.EMPTY_ARRAY, null));
         node.addMethod(new MethodNode("tr", ACC_TRANSIENT, 
ClassHelper.OBJECT_TYPE, Parameter.EMPTY_ARRAY, ClassNode.EMPTY_ARRAY, null));
-        addDummyConstructor(node);
+        // can't check volatile here as it doubles up with bridge
+        addStaticConstructor(node);
+
         verifier.visitClass(node);
+
         checkErrorCount(4);
-        checkErrorMessage(EXPECTED_STRICT_METHOD_ERROR_MESSAGE);
-        checkErrorMessage(EXPECTED_NATIVE_METHOD_ERROR_MESSAGE);
-        checkErrorMessage(EXPECTED_SYNCHRONIZED_METHOD_ERROR_MESSAGE);
-        checkErrorMessage(EXPECTED_TRANSIENT_METHOD_ERROR_MESSAGE);
+        checkErrorMessage("The method 'java.lang.Object na()' has an incorrect 
modifier native.");
+        checkErrorMessage("The method 'java.lang.Object st()' has an incorrect 
modifier strictfp.");
+        checkErrorMessage("The method 'java.lang.Object sy()' has an incorrect 
modifier synchronized.");
+        checkErrorMessage("The method 'java.lang.Object tr()' has an incorrect 
modifier transient.");
     }
 
-    public void testDetectsIncorrectMemberVisibilityInInterface() throws 
Exception {
+    @Test
+    public void shouldDetectIncorrectMemberVisibilityInInterface() {
         ClassNode node = new ClassNode("zzz", ACC_ABSTRACT | ACC_INTERFACE, 
ClassHelper.OBJECT_TYPE);
         node.addMethod(new MethodNode("prim", ACC_PRIVATE, 
ClassHelper.OBJECT_TYPE, Parameter.EMPTY_ARRAY, ClassNode.EMPTY_ARRAY, null));
         node.addMethod(new MethodNode("prom", ACC_PROTECTED, 
ClassHelper.OBJECT_TYPE, Parameter.EMPTY_ARRAY, ClassNode.EMPTY_ARRAY, null));
         node.addField("prif", ACC_PRIVATE, ClassHelper.OBJECT_TYPE, null);
         node.addField("prof", ACC_PROTECTED, ClassHelper.OBJECT_TYPE, null);
-        addDummyConstructor(node);
+        addStaticConstructor(node);
+
         verifier.visitClass(node);
+
         checkErrorCount(4);
-        checkErrorMessage(EXPECTED_PROTECTED_FIELD_ERROR_MESSAGE);
-        checkErrorMessage(EXPECTED_PRIVATE_FIELD_ERROR_MESSAGE);
-        checkErrorMessage(EXPECTED_PROTECTED_METHOD_ERROR_MESSAGE);
-        checkErrorMessage(EXPECTED_PRIVATE_METHOD_ERROR_MESSAGE);
+        checkErrorMessage("The field 'prof' is not 'public static final' but 
is defined in interface 'zzz'.");
+        checkErrorMessage("The field 'prif' is not 'public static final' but 
is defined in interface 'zzz'.");
+        checkErrorMessage("Method 'prom' is protected but should be public in 
interface 'zzz'.");
+        checkErrorMessage("Method 'prim' is private but should be public in 
interface 'zzz'.");
     }
 
-    public void testDetectsCorrectMethodModifiersInClass() throws Exception {
+    @Test
+    public void shouldAcceptCorrectMethodModifiersInClass() {
         // can't check volatile here as it doubles up with bridge
         ClassNode node = new ClassNode("zzz", ACC_PUBLIC, 
ClassHelper.OBJECT_TYPE);
         node.addMethod(new MethodNode("st", ACC_STRICT, 
ClassHelper.OBJECT_TYPE, Parameter.EMPTY_ARRAY, ClassNode.EMPTY_ARRAY, null));
         node.addMethod(new MethodNode("na", ACC_NATIVE, 
ClassHelper.OBJECT_TYPE, Parameter.EMPTY_ARRAY, ClassNode.EMPTY_ARRAY, null));
         node.addMethod(new MethodNode("sy", ACC_SYNCHRONIZED, 
ClassHelper.OBJECT_TYPE, Parameter.EMPTY_ARRAY, ClassNode.EMPTY_ARRAY, null));
-        addDummyConstructor(node);
+        addStaticConstructor(node);
+
         verifier.visitClass(node);
+
         checkErrorCount(0);
     }
 
-    public void testDetectsIncorrectMethodModifiersInClass() throws Exception {
-        // can't check volatile here as it doubles up with bridge
+    @Test
+    public void shouldDetectIncorrectMethodModifiersInClass() {
         ClassNode node = new ClassNode("zzz", ACC_PUBLIC, 
ClassHelper.OBJECT_TYPE);
         node.addMethod(new MethodNode("tr", ACC_TRANSIENT, 
ClassHelper.OBJECT_TYPE, Parameter.EMPTY_ARRAY, ClassNode.EMPTY_ARRAY, null));
-        addDummyConstructor(node);
+        // can't check volatile here as it doubles up with bridge
+        addStaticConstructor(node);
+
         verifier.visitClass(node);
+
         checkErrorCount(1);
-        checkErrorMessage(EXPECTED_TRANSIENT_METHOD_ERROR_MESSAGE);
+        checkErrorMessage("The method 'java.lang.Object tr()' has an incorrect 
modifier transient.");
     }
 
-    public void testDetectsInvalidFieldModifiers() {
-        ClassNode foo = new ClassNode("foo", ACC_PUBLIC, 
ClassHelper.OBJECT_TYPE);
-        FieldNode bar = new FieldNode("bar", (ACC_FINAL | ACC_VOLATILE), 
ClassHelper.STRING_TYPE, foo, null);
-        foo.addField(bar);
-        verifier.visitClass(foo);
+    @Test
+    public void shouldDetectInvalidFieldModifiers() {
+        ClassNode node = new ClassNode("foo", ACC_PUBLIC, 
ClassHelper.OBJECT_TYPE);
+        node.addField(new FieldNode("bar", (ACC_FINAL | ACC_VOLATILE), 
ClassHelper.STRING_TYPE, node, null));
+
+        verifier.visitClass(node);
+
         checkErrorCount(1);
         checkErrorMessage("Illegal combination of modifiers, final and 
volatile, for field 'bar'");
     }
 
-    private void addDummyConstructor(ClassNode node) {
+    @Test
+    public void shouldDetectClassExtendsInterface() {
+        ClassNode node = new ClassNode("C", ACC_PUBLIC, 
ClassHelper.SERIALIZABLE_TYPE);
+
+        verifier.visitClass(node);
+
+        checkErrorCount(1);
+        checkErrorMessage("You are not allowed to extend the interface 
'java.io.Serializable', use implements instead.");
+    }
+
+    @Test
+    public void shouldDetectClassImplementsNonInterface() {
+        ClassNode[] impl = {ClassHelper.OBJECT_TYPE, 
ClassHelper.SERIALIZABLE_TYPE, ClassHelper.ELEMENT_TYPE_TYPE};
+        ClassNode node = new ClassNode("C", ACC_PUBLIC, 
ClassHelper.OBJECT_TYPE, impl, null);
+
+        verifier.visitClass(node);
+
+        checkErrorCount(2);
+        checkErrorMessage("You are not allowed to implement the class 
'java.lang.Object', use extends instead.");
+        checkErrorMessage("You are not allowed to implement the class 
'java.lang.annotation.ElementType', use extends instead.");
+    }
+
+    //-----------------------------------------------------------------------
+
+    private void addStaticConstructor(ClassNode node) {
         // constructors should not be treated as errors (they have no real 
meaning for interfaces anyway)
         node.addMethod(new MethodNode("<clinit>", ACC_PUBLIC | ACC_STATIC, 
ClassHelper.OBJECT_TYPE, Parameter.EMPTY_ARRAY, ClassNode.EMPTY_ARRAY, null));
     }
@@ -225,18 +242,16 @@ public class ClassCompletionVerifierTest extends 
TestSupport {
 
     private void checkErrorMessage(String expectedErrorMessage) {
         assertTrue("Expected an error message but none found.", 
source.getErrorCollector().hasErrors());
-        assertTrue("Expected message to contain <" + expectedErrorMessage +
-                "> but was <" + flattenErrorMessage() + ">.",
-                flattenErrorMessage().contains(expectedErrorMessage));
+        assertTrue("Expected message to contain <" + expectedErrorMessage + "> 
but was <" + flattenErrorMessage() + ">.", 
flattenErrorMessage().contains(expectedErrorMessage));
     }
 
     private String flattenErrorMessage() {
         StringWriter stringWriter = new StringWriter();
-        PrintWriter writer = new PrintWriter(stringWriter, true);
-        for (int i = source.getErrorCollector().getErrorCount() - 1; i >= 0; 
i--) {
-            source.getErrorCollector().getError(i).write(writer);
+        try (PrintWriter printWriter = new PrintWriter(stringWriter, true)) {
+            for (int i = source.getErrorCollector().getErrorCount() - 1; i >= 
0; i -= 1) {
+                source.getErrorCollector().getError(i).write(printWriter);
+            }
         }
-        writer.close();
         return stringWriter.toString();
     }
 }

Reply via email to