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

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

commit 076ccf30c177990051b7673f2b74b16a90e6205b
Author: Eric Milles <[email protected]>
AuthorDate: Tue Apr 6 10:10:42 2021 -0500

    GROOVY-10009: TracingInterceptor: "java.lang.Object" for null arguments
---
 src/main/java/groovy/lang/TracingInterceptor.java | 35 ++++++++++----------
 src/test/groovy/lang/InterceptorTest.groovy       | 39 +++++++++++++----------
 2 files changed, 39 insertions(+), 35 deletions(-)

diff --git a/src/main/java/groovy/lang/TracingInterceptor.java 
b/src/main/java/groovy/lang/TracingInterceptor.java
index f67de11..cd6f1d7 100644
--- a/src/main/java/groovy/lang/TracingInterceptor.java
+++ b/src/main/java/groovy/lang/TracingInterceptor.java
@@ -23,12 +23,12 @@ import java.io.PrintWriter;
 import java.io.Writer;
 
 /*
- * This {@link Interceptor} traces method calls on the proxied object to a 
log. 
- * By default, the log is simply <pre>System.out</pre>; however, that can be 
+ * This {@link Interceptor} traces method calls on the proxied object to a log.
+ * By default, the log is simply <pre>System.out</pre>; however, that can be
  * changed with the <pre>setWriter(Writer)</pre> method.
  * <p>
  * A message will be written to output before a method is invoked and after a 
method
- * is invoked. If methods are nested, and invoke one another, then indentation 
+ * is invoked. If methods are nested, and invoke one another, then indentation
  * of two spaces is written.
  * <p>
  * Here is an example usage on the ArrayList object: <br>
@@ -41,7 +41,7 @@ import java.io.Writer;
  *     assert list.contains(1)
  * }
  * </pre>
- * Running this code produces this output: 
+ * Running this code produces this output:
  * <pre>
  * before java.util.ArrayList.size()
  * after  java.util.ArrayList.size()
@@ -55,15 +55,15 @@ public class TracingInterceptor implements Interceptor {
     private int indent = 0;
 
     /**
-    * Returns the writer associated with this interceptor. 
-    */ 
+    * Returns the writer associated with this interceptor.
+    */
     public Writer getWriter() {
         return writer;
     }
 
     /**
-    * Changes the writer associated with this interceptor. 
-    */ 
+    * Changes the writer associated with this interceptor.
+    */
     public void setWriter(Writer writer) {
         this.writer = writer;
     }
@@ -105,16 +105,13 @@ public class TracingInterceptor implements Interceptor {
         }
     }
 
-    protected void writeInfo(final Class aClass, String methodName, Object[] 
arguments) throws IOException {
-        writer.write(aClass.getName());
-        writer.write(".");
-        writer.write(methodName);
-        writer.write("(");
-        for (int i = 0; i < arguments.length; i++) {
-            if (i > 0) writer.write(", ");
-            Object argument = arguments[i];
-            writer.write(argument.getClass().getName());
-        }
-        writer.write(")");
+    protected void writeInfo(final Class aClass, final String methodName, 
final Object[] arguments) throws IOException {
+        String argumentTypes = java.util.stream.Stream.of(arguments)
+                .map(arg -> arg != null ? arg.getClass().getName() : 
"java.lang.Object") // GROOVY-10009
+                .collect(java.util.stream.Collectors.joining(", "));
+        StringBuilder result = new StringBuilder(aClass.getName());
+        result.append('.').append(methodName).append('(');
+        result.append(argumentTypes).append(')');
+        writer.write(result.toString());
     }
 }
diff --git a/src/test/groovy/lang/InterceptorTest.groovy 
b/src/test/groovy/lang/InterceptorTest.groovy
index 13db0ff..95d84ed 100644
--- a/src/test/groovy/lang/InterceptorTest.groovy
+++ b/src/test/groovy/lang/InterceptorTest.groovy
@@ -23,25 +23,21 @@ import org.codehaus.groovy.runtime.StringBufferWriter
 
 /**
  * Test for the Interceptor Interface usage as implemented by the
- * TracingInterceptor. Makes also use of the ProxyMetaClass and
+ * {@link TracingInterceptor}. Makes use of the {@link ProxyMetaClass} and
  * shows the collaboration.
- * As a side Effect, the ProxyMetaClass is also partly tested.
+ * <p>
+ * As a side effect, the {@code ProxyMetaClass} is also partly tested.
  */
-class InterceptorTest extends GroovyTestCase {
+final class InterceptorTest extends GroovyTestCase {
 
-    def Interceptor logInterceptor
-    def StringBuffer log
-    def interceptable   // the object to intercept method calls on
-    def proxy
+    private final Interceptor interceptor = new TracingInterceptor() // class 
under test
+    private final String interceptable = 'Interceptable String' // the object 
to observe
+    private final ProxyMetaClass proxy = 
ProxyMetaClass.getInstance(interceptable.class)
+    private final StringBuffer log = new StringBuffer('\n')
 
     void setUp() {
-        logInterceptor = new TracingInterceptor()
-        log = new StringBuffer("\n")
-        logInterceptor.writer = new StringBufferWriter(log)
-        // we intercept calls from Groovy to the java.lang.String object
-        interceptable = 'Interceptable String'
-        proxy = ProxyMetaClass.getInstance(interceptable.class)
-        proxy.setInterceptor(logInterceptor)
+        interceptor.writer = new StringBufferWriter(log)
+        proxy.interceptor = interceptor
     }
 
     void testSimpleInterception() {
@@ -90,7 +86,7 @@ after  java.lang.String.valueOf(java.lang.Boolean)
     void testInterceptionOfGroovyClasses() {
         def slicer = new groovy.mock.example.CheeseSlicer()
         def proxy = ProxyMetaClass.getInstance(slicer.class)
-        proxy.setInterceptor(logInterceptor)
+        proxy.setInterceptor(interceptor)
         proxy.use(slicer) {
             slicer.coffeeBreak('')
         }
@@ -101,6 +97,17 @@ after  
groovy.mock.example.CheeseSlicer.coffeeBreak(java.lang.String)
     }
 
     void testProxyMetaClassUseMethodShouldReturnTheResultOfClosure() {
-        assertEquals true, proxy.use { true }
+        assertTrue proxy.use { true }
+    }
+
+    // GROOVY-10009
+    void testNullArgumentToMethodCall() {
+        interceptable.metaClass = proxy
+        interceptable.equals(null)
+
+        assertEquals '''
+            |before java.lang.String.equals(java.lang.Object)
+            |after  java.lang.String.equals(java.lang.Object)
+            |'''.stripMargin(), log.toString()
     }
 }

Reply via email to