Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*
   * Copyright (C) 2012 The Guava Authors
   *
   * Licensed 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 com.google.common.testing;
 
 import static com.google.common.base.Preconditions.checkArgument;
 import static com.google.common.base.Preconditions.checkNotNull;
 import static junit.framework.Assert.assertEquals;
 import static junit.framework.Assert.fail;
 
 
 import java.util.List;
Tester to ensure forwarding wrapper works by delegating calls to the corresponding method with the same parameters forwarded and return value forwarded back or exception propagated as is.

For example:

   new ForwardingWrapperTester().testForwarding(Foo.class, new Function<Foo, Foo>() {
     public Foo apply(Foo foo) {
       return new ForwardingFoo(foo);
     
   });}

Author(s):
Ben Yu
Since:
14.0
 
 public final class ForwardingWrapperTester {
 
   private boolean testsEquals = false;

  
Asks for java.lang.Object.equals(java.lang.Object) and java.lang.Object.hashCode() to be tested. That is, forwarding wrappers of equal instances should be equal.
 
     this. = true;
     return this;
   }

  
Tests that the forwarding wrapper returned by wrapperFunction properly forwards method calls with parameters passed as is, return value returned as is, and exceptions propagated as is.
 
   public <T> void testForwarding(
       Class<T> interfaceTypeFunction<? super T, ? extends T> wrapperFunction) {
     checkNotNull(wrapperFunction);
     checkArgument(interfaceType.isInterface(), "%s isn't an interface"interfaceType);
     Method[] methods = getMostConcreteMethods(interfaceType);
     AccessibleObject.setAccessible(methodstrue);
     for (Method method : methods) {
       // The interface could be package-private or private.
       // filter out equals/hashCode/toString
       if (method.getName().equals("equals")
           && method.getParameterTypes().length == 1
           && method.getParameterTypes()[0] == Object.class) {
         continue;
       }
       if (method.getName().equals("hashCode")
           && method.getParameterTypes().length == 0) {
         continue;
       }
       if (method.getName().equals("toString")
           && method.getParameterTypes().length == 0) {
         continue;
       }
       testSuccessfulForwarding(interfaceTypemethodwrapperFunction);
       testExceptionPropagation(interfaceTypemethodwrapperFunction);
     }
     if () {
       testEquals(interfaceTypewrapperFunction);
     }
     testToString(interfaceTypewrapperFunction);
   }

  
Returns the most concrete public methods from type.
  private static Method[] getMostConcreteMethods(Class<?> type) {
    Method[] methods = type.getMethods();
    for (int i = 0; i < methods.lengthi++) {
      try {
        methods[i] = type.getMethod(methods[i].getName(), methods[i].getParameterTypes());
      } catch (Exception e) {
        throw Throwables.propagate(e);
      }
    }
    return methods;
  }
  private static <T> void testSuccessfulForwarding(
      Class<T> interfaceType,  Method methodFunction<? super T, ? extends T> wrapperFunction) {
    new InteractionTester<T>(interfaceTypemethod).testInteraction(wrapperFunction);
  }
  private static <T> void testExceptionPropagation(
      Class<T> interfaceTypeMethod methodFunction<? super T, ? extends T> wrapperFunction) {
    final RuntimeException exception = new RuntimeException();
    T proxy = Reflection.newProxy(interfaceTypenew AbstractInvocationHandler() {
      @Override protected Object handleInvocation(Object pMethod mObject[] args)
          throws Throwable {
        throw exception;
      }
    });
    T wrapper = wrapperFunction.apply(proxy);
    try {
      method.invoke(wrappergetParameterValues(method));
      fail(method + " failed to throw exception as is.");
    } catch (InvocationTargetException e) {
      if (exception != e.getCause()) {
        throw new RuntimeException(e);
      }
    } catch (IllegalAccessException e) {
      throw new AssertionError(e);
    }
  }
  private static <T> void testEquals(
      Class<T> interfaceTypeFunction<? super T, ? extends T> wrapperFunction) {
    FreshValueGenerator generator = new FreshValueGenerator();
    T instance = generator.newProxy(interfaceType);
    new EqualsTester()
        .addEqualityGroup(wrapperFunction.apply(instance), wrapperFunction.apply(instance))
        .addEqualityGroup(wrapperFunction.apply(generator.newProxy(interfaceType)))
        // TODO: add an overload to EqualsTester to print custom error message?
        .testEquals();
  }
  private static <T> void testToString(
      Class<T> interfaceTypeFunction<? super T, ? extends T> wrapperFunction) {
    T proxy = new FreshValueGenerator().newProxy(interfaceType);
    assertEquals("toString() isn't properly forwarded",
        proxy.toString(), wrapperFunction.apply(proxy).toString());
  }
  private static Object[] getParameterValues(Method method) {
    FreshValueGenerator paramValues = new FreshValueGenerator();
    final List<ObjectpassedArgs = Lists.newArrayList();
    for (Class<?> paramType : method.getParameterTypes()) {
      passedArgs.add(paramValues.generate(paramType));
    }
    return passedArgs.toArray();
  }

  
Tests a single interaction against a method.
  private static final class InteractionTester<T> extends AbstractInvocationHandler {
    private final Class<T> interfaceType;
    private final Method method;
    private final Object[] passedArgs;
    private final Object returnValue;
    private final AtomicInteger called = new AtomicInteger();
    InteractionTester(Class<T> interfaceTypeMethod method) {
      this. = interfaceType;
      this. = method;
      this. = getParameterValues(method);
      this. = new FreshValueGenerator().generate(method.getReturnType());
    }
    @Override protected Object handleInvocation(Object pMethod calledMethodObject[] args)
        throws Throwable {
      assertEquals(calledMethod);
      assertEquals( + " invoked more than once.", 0, .get());
      for (int i = 0; i < .i++) {
        assertEquals("Parameter #" + i + " of " +  + " not forwarded",
            [i], args[i]);
      }
      .getAndIncrement();
      return ;
    }
    void testInteraction(Function<? super T, ? extends T> wrapperFunction) {
      T proxy = Reflection.newProxy(this);
      T wrapper = wrapperFunction.apply(proxy);
      boolean isPossibleChainingCall = .isAssignableFrom(.getReturnType());
      try {
        Object actualReturnValue = .invoke(wrapper);
        // If we think this might be a 'chaining' call then we allow the return value to either
        // be the wrapper or the returnValue.
        if (!isPossibleChainingCall || wrapper != actualReturnValue) {
          assertEquals("Return value of " +  + " not forwarded",
              actualReturnValue);
        }
      } catch (IllegalAccessException e) {
        throw new RuntimeException(e);
      } catch (InvocationTargetException e) {
        throw Throwables.propagate(e.getCause());
      }
      assertEquals("Failed to forward to " + , 1, .get());
    }
    @Override public String toString() {
      return "dummy " + .getSimpleName();
    }
  }
New to GrepCode? Check out our FAQ X