You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by em...@apache.org on 2021/04/06 15:10:58 UTC

[groovy] branch GROOVY-10009 created (now 4744607)

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

emilles pushed a change to branch GROOVY-10009
in repository https://gitbox.apache.org/repos/asf/groovy.git.


      at 4744607  GROOVY-10009: TracingInterceptor: "java.lang.Object" for null arguments

This branch includes the following new commits:

     new 4744607  GROOVY-10009: TracingInterceptor: "java.lang.Object" for null arguments

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


[groovy] 01/01: GROOVY-10009: TracingInterceptor: "java.lang.Object" for null arguments

Posted by em...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 474460756a8a895f86f88e1e9b18e4e88d5800f7
Author: Eric Milles <er...@thomsonreuters.com>
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 862e4ff..6bcb62b 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;
     }
@@ -108,16 +108,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()
     }
 }