예제 #1
0
  /**
   * This method is a default implementation for the invoke method given in InvocationHandler. Any
   * call to a method with a declaring class that is not Object, excluding toString() and default
   * methods is redirected to invokeCustom.
   *
   * <p>Methods like equals and hashcode are called on the class itself instead of the delegate
   * because they are considered fundamental methods that should not be overwritten. The toString()
   * method gets special treatment as it is deemed to be a method that you might wish to override
   * when called from Groovy. Interface default methods from Java 8 on the other hand are considered
   * being default implementations you don't normally want to change. So they are called directly
   * too
   *
   * <p>In many scenarios, it is better to overwrite the invokeCustom method where the core Object
   * related methods are filtered out.
   *
   * @param proxy the proxy
   * @param method the method
   * @param args the arguments
   * @return the result of the invocation by method or delegate
   * @throws Throwable if caused by the delegate or the method
   * @see #invokeCustom(Object, Method, Object[])
   * @see InvocationHandler#invoke(java.lang.Object, java.lang.reflect.Method, java.lang.Object[])
   */
  public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    VMPlugin plugin = VMPluginFactory.getPlugin();
    if (plugin.getVersion() >= 7 && isDefaultMethod(method)) {
      Object handle = handleCache.get(method);
      if (handle == null) {
        handle = plugin.getInvokeSpecialHandle(method, proxy);
        handleCache.put(method, handle);
      }
      return plugin.invokeHandle(handle, args);
    }

    if (!checkMethod(method)) {
      try {
        if (method.getDeclaringClass() == GroovyObject.class) {
          if ("getMetaClass".equals(method.getName())) {
            return getMetaClass(proxy);
          } else if ("setMetaClass".equals(method.getName())) {
            return setMetaClass((MetaClass) args[0]);
          }
        }
        return invokeCustom(proxy, method, args);
      } catch (GroovyRuntimeException gre) {
        throw ScriptBytecodeAdapter.unwrap(gre);
      }
    }

    try {
      return method.invoke(this, args);
    } catch (InvocationTargetException ite) {
      throw ite.getTargetException();
    }
  }
 public Object callConstructor(Object receiver, Object[] args) throws Throwable {
   try {
     if (receiver == metaClass.getTheClass()
         && version == classInfo.getVersion()) // metaClass still be valid
     return metaClass.invokeConstructor(args);
     else return CallSiteArray.defaultCallConstructor(this, receiver, args);
   } catch (GroovyRuntimeException gre) {
     throw ScriptBytecodeAdapter.unwrap(gre);
   }
 }
예제 #3
0
  /**
   * Asserts that the given code closure fails when it is evaluated and that a particular Exception
   * type can be attributed to the cause. The expected exception class is compared recursively with
   * any nested exceptions using getCause() until either a match is found or no more nested
   * exceptions exist.
   *
   * <p>If a match is found, the matching exception is returned otherwise the method will fail.
   *
   * @param expectedCause the class of the expected exception
   * @param code the closure that should fail
   * @return the cause
   */
  public static Throwable shouldFailWithCause(Class expectedCause, Closure code) {
    if (expectedCause == null) {
      fail("The expectedCause class cannot be null");
    }
    Throwable cause = null;
    Throwable orig = null;
    int level = 0;
    try {
      code.call();
    } catch (GroovyRuntimeException gre) {
      orig = ScriptBytecodeAdapter.unwrap(gre);
      cause = orig.getCause();
    } catch (Throwable e) {
      orig = e;
      cause = orig.getCause();
    }

    if (orig != null && cause == null) {
      fail(
          "Closure "
              + code
              + " was expected to fail due to a nested cause of type "
              + expectedCause.getName()
              + " but instead got a direct exception of type "
              + orig.getClass().getName()
              + " with no nested cause(s). Code under test has a bug or perhaps you meant shouldFail?");
    }

    while (cause != null
        && !expectedCause.isInstance(cause)
        && cause != cause.getCause()
        && level < MAX_NESTED_EXCEPTIONS) {
      cause = cause.getCause();
      level++;
    }

    if (orig == null) {
      fail(
          "Closure "
              + code
              + " should have failed with an exception having a nested cause of type "
              + expectedCause.getName());
    } else if (cause == null || !expectedCause.isInstance(cause)) {
      fail(
          "Closure "
              + code
              + " should have failed with an exception having a nested cause of type "
              + expectedCause.getName()
              + ", instead found these Exceptions:\n"
              + buildExceptionList(orig));
    }
    return cause;
  }
예제 #4
0
 /**
  * Asserts that the given code closure fails when it is evaluated
  *
  * @param code the code expected to fail
  * @return the caught exception
  */
 public static Throwable shouldFail(Closure code) {
   boolean failed = false;
   Throwable th = null;
   try {
     code.call();
   } catch (GroovyRuntimeException gre) {
     failed = true;
     th = ScriptBytecodeAdapter.unwrap(gre);
   } catch (Throwable e) {
     failed = true;
     th = e;
   }
   assertTrue("Closure " + code + " should have failed", failed);
   return th;
 }
예제 #5
0
  /**
   * Asserts that the given code closure fails when it is evaluated and that a particular type of
   * exception is thrown.
   *
   * @param clazz the class of the expected exception
   * @param code the closure that should fail
   * @return the caught exception
   */
  public static Throwable shouldFail(Class clazz, Closure code) {
    Throwable th = null;
    try {
      code.call();
    } catch (GroovyRuntimeException gre) {
      th = ScriptBytecodeAdapter.unwrap(gre);
    } catch (Throwable e) {
      th = e;
    }

    if (th == null) {
      fail("Closure " + code + " should have failed with an exception of type " + clazz.getName());
    } else if (!clazz.isInstance(th)) {
      fail(
          "Closure "
              + code
              + " should have failed with an exception of type "
              + clazz.getName()
              + ", instead got Exception "
              + th);
    }
    return th;
  }
예제 #6
0
 public void testGreaterThan() {
   assertTrue(ScriptBytecodeAdapter.compareGreaterThan(new Integer(3), new Integer(2)));
   assertTrue(ScriptBytecodeAdapter.compareGreaterThanEqual(new Integer(2), new Integer(2)));
 }
예제 #7
0
 public void testLessThan() {
   assertTrue(ScriptBytecodeAdapter.compareLessThan(new Integer(1), new Integer(2)));
   assertTrue(ScriptBytecodeAdapter.compareLessThanEqual(new Integer(2), new Integer(2)));
 }