You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by su...@apache.org on 2021/02/16 17:31:23 UTC

[groovy] branch GROOVY_3_0_X updated: GROOVY-9932: Fix callCurrent invocation on MockProxyMetaClass

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

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


The following commit(s) were added to refs/heads/GROOVY_3_0_X by this push:
     new a48863d  GROOVY-9932: Fix callCurrent invocation on MockProxyMetaClass
a48863d is described below

commit a48863d8a0ed69b4b0ff874df4092203142128a8
Author: Ryan Tandy <ry...@nardis.ca>
AuthorDate: Tue Feb 16 05:19:42 2021 +0800

    GROOVY-9932: Fix callCurrent invocation on MockProxyMetaClass
    
    Override new signature of invokeMethod added by 34ad466ba6a87a5eb26cf4a444f817299b744edb
    
    (cherry picked from commit e1fa173e9ecc72c53471d9bb84425d6c8fad07ab)
---
 src/test/groovy/bugs/Groovy9932.groovy             | 55 ++++++++++++++++++++++
 .../mock/interceptor/MockProxyMetaClass.java       | 26 ++++++++++
 2 files changed, 81 insertions(+)

diff --git a/src/test/groovy/bugs/Groovy9932.groovy b/src/test/groovy/bugs/Groovy9932.groovy
new file mode 100644
index 0000000..46bea95
--- /dev/null
+++ b/src/test/groovy/bugs/Groovy9932.groovy
@@ -0,0 +1,55 @@
+/*
+ *  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 groovy.bugs
+
+import groovy.mock.interceptor.MockFor
+import org.junit.Test
+
+final class Groovy9932 {
+    @Test
+    void testCallCurrentOnMock() {
+        def mockForHelper = new MockFor(Helper)
+
+        mockForHelper.demand.helperMethod { -> 'intercepted' }
+        mockForHelper.ignore('getMyString')
+
+        mockForHelper.use {
+            def helper = new Helper()
+            assert helper.myString == 'intercepted'
+        }
+    }
+
+    static class Helper {
+        String myString
+
+        Helper() {
+            myString = internalMethod()
+        }
+
+        // separate method to ensure callCurrent is used.
+        // in the constructor it uses a direct call without checking stMC
+        private String internalMethod() {
+            return helperMethod()
+        }
+
+        String helperMethod() {
+            return 'not intercepted'
+        }
+    }
+}
diff --git a/subprojects/groovy-test/src/main/java/groovy/mock/interceptor/MockProxyMetaClass.java b/subprojects/groovy-test/src/main/java/groovy/mock/interceptor/MockProxyMetaClass.java
index d1df519..523819b 100644
--- a/subprojects/groovy-test/src/main/java/groovy/mock/interceptor/MockProxyMetaClass.java
+++ b/subprojects/groovy-test/src/main/java/groovy/mock/interceptor/MockProxyMetaClass.java
@@ -75,6 +75,7 @@ public class MockProxyMetaClass extends ProxyMetaClass {
         return new MockProxyMetaClass(metaRegistry, theClass, meta, interceptConstruction);
     }
 
+    @Override
     public Object invokeMethod(final Object object, final String methodName, final Object[] arguments) {
         if (null == interceptor && !fallingThrough) {
             throw new RuntimeException("cannot invoke method '" + methodName + "' without interceptor");
@@ -95,6 +96,28 @@ public class MockProxyMetaClass extends ProxyMetaClass {
         return result;
     }
 
+    @Override
+    public Object invokeMethod(final Class sender, final Object object, final String methodName, final Object[] arguments, final boolean isCallToSuper, final boolean fromInsideClass) {
+        if (null == interceptor && !fallingThrough) {
+            throw new RuntimeException("cannot invoke method '" + methodName + "' without interceptor");
+        }
+        Object result = FALL_THROUGH_MARKER;
+        if (interceptor != null) {
+            result = interceptor.beforeInvoke(object, methodName, arguments);
+        }
+        if (result == FALL_THROUGH_MARKER) {
+            Interceptor saved = interceptor;
+            interceptor = null;
+            boolean savedFallingThrough = fallingThrough;
+            fallingThrough = true;
+            result = adaptee.invokeMethod(sender, object, methodName, arguments, isCallToSuper, fromInsideClass);
+            fallingThrough = savedFallingThrough;
+            interceptor = saved;
+        }
+        return result;
+    }
+
+    @Override
     public Object invokeStaticMethod(final Object object, final String methodName, final Object[] arguments) {
         if (null == interceptor && !fallingThrough) {
             throw new RuntimeException("cannot invoke static method '" + methodName + "' without interceptor");
@@ -115,6 +138,7 @@ public class MockProxyMetaClass extends ProxyMetaClass {
         return result;
     }
 
+    @Override
     public Object getProperty(Class aClass, Object object, String property, boolean b, boolean b1) {
         if (null == interceptor && !fallingThrough) {
             throw new RuntimeException("cannot get property '" + property + "' without interceptor");
@@ -135,6 +159,7 @@ public class MockProxyMetaClass extends ProxyMetaClass {
         return result;
     }
 
+    @Override
     public void setProperty(Class aClass, Object object, String property, Object newValue, boolean b, boolean b1) {
         if (null == interceptor && !fallingThrough) {
             throw new RuntimeException("cannot set property '" + property + "' without interceptor");
@@ -162,6 +187,7 @@ public class MockProxyMetaClass extends ProxyMetaClass {
      * Unlike general impl in superclass, ctors are not intercepted but relayed
      * unless interceptConstruction is set.
      */
+    @Override
     public Object invokeConstructor(final Object[] arguments) {
         if (interceptConstruction && null == interceptor)
             throw new RuntimeException("cannot invoke constructor without interceptor");