17dd252788645e940eada959bdde927426e2531c9Paul Duffin/*
27dd252788645e940eada959bdde927426e2531c9Paul Duffin * Copyright (C) 2012 The Guava Authors
37dd252788645e940eada959bdde927426e2531c9Paul Duffin *
47dd252788645e940eada959bdde927426e2531c9Paul Duffin * Licensed under the Apache License, Version 2.0 (the "License");
57dd252788645e940eada959bdde927426e2531c9Paul Duffin * you may not use this file except in compliance with the License.
67dd252788645e940eada959bdde927426e2531c9Paul Duffin * You may obtain a copy of the License at
77dd252788645e940eada959bdde927426e2531c9Paul Duffin *
87dd252788645e940eada959bdde927426e2531c9Paul Duffin * http://www.apache.org/licenses/LICENSE-2.0
97dd252788645e940eada959bdde927426e2531c9Paul Duffin *
107dd252788645e940eada959bdde927426e2531c9Paul Duffin * Unless required by applicable law or agreed to in writing, software
117dd252788645e940eada959bdde927426e2531c9Paul Duffin * distributed under the License is distributed on an "AS IS" BASIS,
127dd252788645e940eada959bdde927426e2531c9Paul Duffin * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
137dd252788645e940eada959bdde927426e2531c9Paul Duffin * See the License for the specific language governing permissions and
147dd252788645e940eada959bdde927426e2531c9Paul Duffin * limitations under the License.
157dd252788645e940eada959bdde927426e2531c9Paul Duffin */
167dd252788645e940eada959bdde927426e2531c9Paul Duffin
177dd252788645e940eada959bdde927426e2531c9Paul Duffinpackage com.google.common.testing.anotherpackage;
187dd252788645e940eada959bdde927426e2531c9Paul Duffin
193ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffinimport static com.google.common.truth.Truth.assertThat;
207dd252788645e940eada959bdde927426e2531c9Paul Duffin
217dd252788645e940eada959bdde927426e2531c9Paul Duffinimport com.google.common.base.Equivalence;
227dd252788645e940eada959bdde927426e2531c9Paul Duffinimport com.google.common.base.Function;
237dd252788645e940eada959bdde927426e2531c9Paul Duffinimport com.google.common.base.Functions;
247dd252788645e940eada959bdde927426e2531c9Paul Duffinimport com.google.common.base.Joiner;
257dd252788645e940eada959bdde927426e2531c9Paul Duffinimport com.google.common.base.Predicate;
267dd252788645e940eada959bdde927426e2531c9Paul Duffinimport com.google.common.collect.Ordering;
277dd252788645e940eada959bdde927426e2531c9Paul Duffinimport com.google.common.primitives.UnsignedInteger;
287dd252788645e940eada959bdde927426e2531c9Paul Duffinimport com.google.common.primitives.UnsignedLong;
297dd252788645e940eada959bdde927426e2531c9Paul Duffinimport com.google.common.testing.ForwardingWrapperTester;
307dd252788645e940eada959bdde927426e2531c9Paul Duffinimport com.google.common.testing.NullPointerTester;
317dd252788645e940eada959bdde927426e2531c9Paul Duffin
327dd252788645e940eada959bdde927426e2531c9Paul Duffinimport junit.framework.TestCase;
337dd252788645e940eada959bdde927426e2531c9Paul Duffin
347dd252788645e940eada959bdde927426e2531c9Paul Duffinimport java.io.InputStream;
357dd252788645e940eada959bdde927426e2531c9Paul Duffinimport java.nio.charset.Charset;
367dd252788645e940eada959bdde927426e2531c9Paul Duffinimport java.util.concurrent.TimeUnit;
377dd252788645e940eada959bdde927426e2531c9Paul Duffinimport java.util.regex.Pattern;
387dd252788645e940eada959bdde927426e2531c9Paul Duffin
397dd252788645e940eada959bdde927426e2531c9Paul Duffin/**
407dd252788645e940eada959bdde927426e2531c9Paul Duffin * Tests for {@link ForwardingWrapperTester}. Live in a different package to detect reflection
417dd252788645e940eada959bdde927426e2531c9Paul Duffin * access issues, if any.
427dd252788645e940eada959bdde927426e2531c9Paul Duffin *
437dd252788645e940eada959bdde927426e2531c9Paul Duffin * @author Ben Yu
447dd252788645e940eada959bdde927426e2531c9Paul Duffin */
457dd252788645e940eada959bdde927426e2531c9Paul Duffinpublic class ForwardingWrapperTesterTest extends TestCase {
467dd252788645e940eada959bdde927426e2531c9Paul Duffin
477dd252788645e940eada959bdde927426e2531c9Paul Duffin  private final ForwardingWrapperTester tester = new ForwardingWrapperTester();
487dd252788645e940eada959bdde927426e2531c9Paul Duffin
497dd252788645e940eada959bdde927426e2531c9Paul Duffin  public void testGoodForwarder() {
507dd252788645e940eada959bdde927426e2531c9Paul Duffin    tester.testForwarding(Arithmetic.class,
517dd252788645e940eada959bdde927426e2531c9Paul Duffin        new Function<Arithmetic, Arithmetic>() {
527dd252788645e940eada959bdde927426e2531c9Paul Duffin          @Override public Arithmetic apply(Arithmetic arithmetic) {
537dd252788645e940eada959bdde927426e2531c9Paul Duffin            return new ForwardingArithmetic(arithmetic);
547dd252788645e940eada959bdde927426e2531c9Paul Duffin          }
557dd252788645e940eada959bdde927426e2531c9Paul Duffin        });
567dd252788645e940eada959bdde927426e2531c9Paul Duffin    tester.testForwarding(ParameterTypesDifferent.class,
577dd252788645e940eada959bdde927426e2531c9Paul Duffin        new Function<ParameterTypesDifferent, ParameterTypesDifferent>() {
587dd252788645e940eada959bdde927426e2531c9Paul Duffin          @Override public ParameterTypesDifferent apply(ParameterTypesDifferent delegate) {
597dd252788645e940eada959bdde927426e2531c9Paul Duffin            return new ParameterTypesDifferentForwarder(delegate);
607dd252788645e940eada959bdde927426e2531c9Paul Duffin          }
617dd252788645e940eada959bdde927426e2531c9Paul Duffin        });
627dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
637dd252788645e940eada959bdde927426e2531c9Paul Duffin
647dd252788645e940eada959bdde927426e2531c9Paul Duffin  public void testVoidMethodForwarding() {
657dd252788645e940eada959bdde927426e2531c9Paul Duffin    tester.testForwarding(Runnable.class,
667dd252788645e940eada959bdde927426e2531c9Paul Duffin        new Function<Runnable, Runnable>() {
677dd252788645e940eada959bdde927426e2531c9Paul Duffin          @Override public Runnable apply(final Runnable runnable) {
687dd252788645e940eada959bdde927426e2531c9Paul Duffin            return new ForwardingRunnable(runnable);
697dd252788645e940eada959bdde927426e2531c9Paul Duffin          }
707dd252788645e940eada959bdde927426e2531c9Paul Duffin        });
717dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
727dd252788645e940eada959bdde927426e2531c9Paul Duffin
737dd252788645e940eada959bdde927426e2531c9Paul Duffin  public void testToStringForwarding() {
747dd252788645e940eada959bdde927426e2531c9Paul Duffin    tester.testForwarding(Runnable.class,
757dd252788645e940eada959bdde927426e2531c9Paul Duffin        new Function<Runnable, Runnable>() {
767dd252788645e940eada959bdde927426e2531c9Paul Duffin          @Override public Runnable apply(final Runnable runnable) {
777dd252788645e940eada959bdde927426e2531c9Paul Duffin            return new ForwardingRunnable(runnable) {
787dd252788645e940eada959bdde927426e2531c9Paul Duffin              @Override public String toString() {
797dd252788645e940eada959bdde927426e2531c9Paul Duffin                return runnable.toString();
807dd252788645e940eada959bdde927426e2531c9Paul Duffin              }
817dd252788645e940eada959bdde927426e2531c9Paul Duffin            };
827dd252788645e940eada959bdde927426e2531c9Paul Duffin          }
837dd252788645e940eada959bdde927426e2531c9Paul Duffin        });
847dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
857dd252788645e940eada959bdde927426e2531c9Paul Duffin
867dd252788645e940eada959bdde927426e2531c9Paul Duffin  public void testFailsToForwardToString() {
877dd252788645e940eada959bdde927426e2531c9Paul Duffin    assertFailure(Runnable.class, new Function<Runnable, Runnable>() {
887dd252788645e940eada959bdde927426e2531c9Paul Duffin      @Override public Runnable apply(final Runnable runnable) {
897dd252788645e940eada959bdde927426e2531c9Paul Duffin        return new ForwardingRunnable(runnable) {
907dd252788645e940eada959bdde927426e2531c9Paul Duffin          @Override public String toString() {
917dd252788645e940eada959bdde927426e2531c9Paul Duffin            return "";
927dd252788645e940eada959bdde927426e2531c9Paul Duffin          }
937dd252788645e940eada959bdde927426e2531c9Paul Duffin        };
947dd252788645e940eada959bdde927426e2531c9Paul Duffin      }
957dd252788645e940eada959bdde927426e2531c9Paul Duffin    }, "toString()");
967dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
977dd252788645e940eada959bdde927426e2531c9Paul Duffin
987dd252788645e940eada959bdde927426e2531c9Paul Duffin  public void testFailsToForwardHashCode() {
997dd252788645e940eada959bdde927426e2531c9Paul Duffin    tester.includingEquals();
1007dd252788645e940eada959bdde927426e2531c9Paul Duffin    assertFailure(Runnable.class, new Function<Runnable, Runnable>() {
1017dd252788645e940eada959bdde927426e2531c9Paul Duffin      @Override public Runnable apply(final Runnable runnable) {
1027dd252788645e940eada959bdde927426e2531c9Paul Duffin        return new ForwardingRunnable(runnable) {
1037dd252788645e940eada959bdde927426e2531c9Paul Duffin          @Override public boolean equals(Object o) {
1047dd252788645e940eada959bdde927426e2531c9Paul Duffin            if (o instanceof ForwardingRunnable) {
1057dd252788645e940eada959bdde927426e2531c9Paul Duffin              ForwardingRunnable that = (ForwardingRunnable) o;
1067dd252788645e940eada959bdde927426e2531c9Paul Duffin              return runnable.equals(that.runnable);
1077dd252788645e940eada959bdde927426e2531c9Paul Duffin            }
1087dd252788645e940eada959bdde927426e2531c9Paul Duffin            return false;
1097dd252788645e940eada959bdde927426e2531c9Paul Duffin          }
1107dd252788645e940eada959bdde927426e2531c9Paul Duffin        };
1117dd252788645e940eada959bdde927426e2531c9Paul Duffin      }
1127dd252788645e940eada959bdde927426e2531c9Paul Duffin    }, "Runnable");
1137dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
1147dd252788645e940eada959bdde927426e2531c9Paul Duffin
1157dd252788645e940eada959bdde927426e2531c9Paul Duffin  public void testEqualsAndHashCodeForwarded() {
1167dd252788645e940eada959bdde927426e2531c9Paul Duffin    tester.includingEquals();
1177dd252788645e940eada959bdde927426e2531c9Paul Duffin    tester.testForwarding(Runnable.class, new Function<Runnable, Runnable>() {
1187dd252788645e940eada959bdde927426e2531c9Paul Duffin      @Override public Runnable apply(final Runnable runnable) {
1197dd252788645e940eada959bdde927426e2531c9Paul Duffin        return new ForwardingRunnable(runnable) {
1207dd252788645e940eada959bdde927426e2531c9Paul Duffin          @Override public boolean equals(Object o) {
1217dd252788645e940eada959bdde927426e2531c9Paul Duffin            if (o instanceof ForwardingRunnable) {
1227dd252788645e940eada959bdde927426e2531c9Paul Duffin              ForwardingRunnable that = (ForwardingRunnable) o;
1237dd252788645e940eada959bdde927426e2531c9Paul Duffin              return runnable.equals(that.runnable);
1247dd252788645e940eada959bdde927426e2531c9Paul Duffin            }
1257dd252788645e940eada959bdde927426e2531c9Paul Duffin            return false;
1267dd252788645e940eada959bdde927426e2531c9Paul Duffin          }
1277dd252788645e940eada959bdde927426e2531c9Paul Duffin          @Override public int hashCode() {
1287dd252788645e940eada959bdde927426e2531c9Paul Duffin            return runnable.hashCode();
1297dd252788645e940eada959bdde927426e2531c9Paul Duffin          }
1307dd252788645e940eada959bdde927426e2531c9Paul Duffin        };
1317dd252788645e940eada959bdde927426e2531c9Paul Duffin      }
1327dd252788645e940eada959bdde927426e2531c9Paul Duffin    });
1337dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
1347dd252788645e940eada959bdde927426e2531c9Paul Duffin
1357dd252788645e940eada959bdde927426e2531c9Paul Duffin  public void testFailsToForwardEquals() {
1367dd252788645e940eada959bdde927426e2531c9Paul Duffin    tester.includingEquals();
1377dd252788645e940eada959bdde927426e2531c9Paul Duffin    assertFailure(Runnable.class, new Function<Runnable, Runnable>() {
1387dd252788645e940eada959bdde927426e2531c9Paul Duffin      @Override public Runnable apply(final Runnable runnable) {
1397dd252788645e940eada959bdde927426e2531c9Paul Duffin        return new ForwardingRunnable(runnable) {
1407dd252788645e940eada959bdde927426e2531c9Paul Duffin          @Override public int hashCode() {
1417dd252788645e940eada959bdde927426e2531c9Paul Duffin            return runnable.hashCode();
1427dd252788645e940eada959bdde927426e2531c9Paul Duffin          }
1437dd252788645e940eada959bdde927426e2531c9Paul Duffin        };
1447dd252788645e940eada959bdde927426e2531c9Paul Duffin      }
1457dd252788645e940eada959bdde927426e2531c9Paul Duffin    }, "Runnable");
1467dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
1477dd252788645e940eada959bdde927426e2531c9Paul Duffin
1487dd252788645e940eada959bdde927426e2531c9Paul Duffin  public void testFailsToForward() {
1497dd252788645e940eada959bdde927426e2531c9Paul Duffin    assertFailure(Runnable.class,
1507dd252788645e940eada959bdde927426e2531c9Paul Duffin        new Function<Runnable, Runnable>() {
1517dd252788645e940eada959bdde927426e2531c9Paul Duffin          @Override public Runnable apply(Runnable runnable) {
1527dd252788645e940eada959bdde927426e2531c9Paul Duffin            return new ForwardingRunnable(runnable) {
1537dd252788645e940eada959bdde927426e2531c9Paul Duffin              @Override public void run() {}
1547dd252788645e940eada959bdde927426e2531c9Paul Duffin            };
1557dd252788645e940eada959bdde927426e2531c9Paul Duffin          }
1567dd252788645e940eada959bdde927426e2531c9Paul Duffin        }, "run()", "Failed to forward");
1577dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
1587dd252788645e940eada959bdde927426e2531c9Paul Duffin
1597dd252788645e940eada959bdde927426e2531c9Paul Duffin  public void testRedundantForwarding() {
1607dd252788645e940eada959bdde927426e2531c9Paul Duffin    assertFailure(Runnable.class,
1617dd252788645e940eada959bdde927426e2531c9Paul Duffin        new Function<Runnable, Runnable>() {
1627dd252788645e940eada959bdde927426e2531c9Paul Duffin          @Override public Runnable apply(final Runnable runnable) {
1637dd252788645e940eada959bdde927426e2531c9Paul Duffin            return new Runnable() {
1647dd252788645e940eada959bdde927426e2531c9Paul Duffin              @Override public void run() {
1657dd252788645e940eada959bdde927426e2531c9Paul Duffin                runnable.run();
1667dd252788645e940eada959bdde927426e2531c9Paul Duffin                runnable.run();
1677dd252788645e940eada959bdde927426e2531c9Paul Duffin              }
1687dd252788645e940eada959bdde927426e2531c9Paul Duffin            };
1697dd252788645e940eada959bdde927426e2531c9Paul Duffin          }
1707dd252788645e940eada959bdde927426e2531c9Paul Duffin        }, "run()", "invoked more than once");
1717dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
1727dd252788645e940eada959bdde927426e2531c9Paul Duffin
1737dd252788645e940eada959bdde927426e2531c9Paul Duffin  public void testFailsToForwardParameters() {
1747dd252788645e940eada959bdde927426e2531c9Paul Duffin    assertFailure(Adder.class, new Function<Adder, Adder>() {
1757dd252788645e940eada959bdde927426e2531c9Paul Duffin      @Override public Adder apply(Adder adder) {
1767dd252788645e940eada959bdde927426e2531c9Paul Duffin        return new FailsToForwardParameters(adder);
1777dd252788645e940eada959bdde927426e2531c9Paul Duffin      }
1787dd252788645e940eada959bdde927426e2531c9Paul Duffin    }, "add(", "Parameter #0");
1797dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
1807dd252788645e940eada959bdde927426e2531c9Paul Duffin
1817dd252788645e940eada959bdde927426e2531c9Paul Duffin  public void testForwardsToTheWrongMethod() {
1827dd252788645e940eada959bdde927426e2531c9Paul Duffin    assertFailure(Arithmetic.class, new Function<Arithmetic, Arithmetic>() {
1837dd252788645e940eada959bdde927426e2531c9Paul Duffin      @Override public Arithmetic apply(Arithmetic adder) {
1847dd252788645e940eada959bdde927426e2531c9Paul Duffin        return new ForwardsToTheWrongMethod(adder);
1857dd252788645e940eada959bdde927426e2531c9Paul Duffin      }
1867dd252788645e940eada959bdde927426e2531c9Paul Duffin    }, "minus");
1877dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
1887dd252788645e940eada959bdde927426e2531c9Paul Duffin
1897dd252788645e940eada959bdde927426e2531c9Paul Duffin  public void testFailsToForwardReturnValue() {
1907dd252788645e940eada959bdde927426e2531c9Paul Duffin    assertFailure(Adder.class, new Function<Adder, Adder>() {
1917dd252788645e940eada959bdde927426e2531c9Paul Duffin      @Override public Adder apply(Adder adder) {
1927dd252788645e940eada959bdde927426e2531c9Paul Duffin        return new FailsToForwardReturnValue(adder);
1937dd252788645e940eada959bdde927426e2531c9Paul Duffin      }
1947dd252788645e940eada959bdde927426e2531c9Paul Duffin    }, "add(", "Return value");
1957dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
1967dd252788645e940eada959bdde927426e2531c9Paul Duffin
1977dd252788645e940eada959bdde927426e2531c9Paul Duffin  public void testFailsToPropagateException() {
1987dd252788645e940eada959bdde927426e2531c9Paul Duffin    assertFailure(Adder.class, new Function<Adder, Adder>() {
1997dd252788645e940eada959bdde927426e2531c9Paul Duffin      @Override public Adder apply(Adder adder) {
2007dd252788645e940eada959bdde927426e2531c9Paul Duffin        return new FailsToPropagageException(adder);
2017dd252788645e940eada959bdde927426e2531c9Paul Duffin      }
2027dd252788645e940eada959bdde927426e2531c9Paul Duffin    }, "add(", "exception");
2037dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
2047dd252788645e940eada959bdde927426e2531c9Paul Duffin
2057dd252788645e940eada959bdde927426e2531c9Paul Duffin  public void testNotInterfaceType() {
2067dd252788645e940eada959bdde927426e2531c9Paul Duffin    try {
2077dd252788645e940eada959bdde927426e2531c9Paul Duffin      new ForwardingWrapperTester().testForwarding(String.class, Functions.<String>identity());
2087dd252788645e940eada959bdde927426e2531c9Paul Duffin      fail();
2097dd252788645e940eada959bdde927426e2531c9Paul Duffin    } catch (IllegalArgumentException expected) {}
2107dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
2117dd252788645e940eada959bdde927426e2531c9Paul Duffin
2127dd252788645e940eada959bdde927426e2531c9Paul Duffin  public void testNulls() {
2137dd252788645e940eada959bdde927426e2531c9Paul Duffin    new NullPointerTester()
2147dd252788645e940eada959bdde927426e2531c9Paul Duffin        .setDefault(Class.class, Runnable.class)
2157dd252788645e940eada959bdde927426e2531c9Paul Duffin        .testAllPublicInstanceMethods(new ForwardingWrapperTester());
2167dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
2177dd252788645e940eada959bdde927426e2531c9Paul Duffin
2187dd252788645e940eada959bdde927426e2531c9Paul Duffin  private <T> void assertFailure(
2197dd252788645e940eada959bdde927426e2531c9Paul Duffin      Class<T> interfaceType, Function<T, ? extends T> wrapperFunction,
2207dd252788645e940eada959bdde927426e2531c9Paul Duffin      String... expectedMessages) {
2217dd252788645e940eada959bdde927426e2531c9Paul Duffin    try {
2227dd252788645e940eada959bdde927426e2531c9Paul Duffin      tester.testForwarding(interfaceType, wrapperFunction);
2237dd252788645e940eada959bdde927426e2531c9Paul Duffin    } catch (AssertionError expected) {
2247dd252788645e940eada959bdde927426e2531c9Paul Duffin      for (String message : expectedMessages) {
2253ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin        assertThat(expected.getMessage()).contains(message);
2267dd252788645e940eada959bdde927426e2531c9Paul Duffin      }
2277dd252788645e940eada959bdde927426e2531c9Paul Duffin      return;
2287dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
2297dd252788645e940eada959bdde927426e2531c9Paul Duffin    fail("expected failure not reported");
2307dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
2317dd252788645e940eada959bdde927426e2531c9Paul Duffin
2327dd252788645e940eada959bdde927426e2531c9Paul Duffin  private class ForwardingRunnable implements Runnable {
2337dd252788645e940eada959bdde927426e2531c9Paul Duffin
2347dd252788645e940eada959bdde927426e2531c9Paul Duffin    private final Runnable runnable;
2357dd252788645e940eada959bdde927426e2531c9Paul Duffin
2367dd252788645e940eada959bdde927426e2531c9Paul Duffin    ForwardingRunnable(Runnable runnable) {
2377dd252788645e940eada959bdde927426e2531c9Paul Duffin      this.runnable = runnable;
2387dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
2397dd252788645e940eada959bdde927426e2531c9Paul Duffin
2407dd252788645e940eada959bdde927426e2531c9Paul Duffin    @Override public void run() {
2417dd252788645e940eada959bdde927426e2531c9Paul Duffin      runnable.run();
2427dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
2437dd252788645e940eada959bdde927426e2531c9Paul Duffin
2447dd252788645e940eada959bdde927426e2531c9Paul Duffin    @Override public String toString() {
2457dd252788645e940eada959bdde927426e2531c9Paul Duffin      return runnable.toString();
2467dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
2477dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
2487dd252788645e940eada959bdde927426e2531c9Paul Duffin
2497dd252788645e940eada959bdde927426e2531c9Paul Duffin  private interface Adder {
2507dd252788645e940eada959bdde927426e2531c9Paul Duffin    int add(int a, int b);
2517dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
2527dd252788645e940eada959bdde927426e2531c9Paul Duffin
2537dd252788645e940eada959bdde927426e2531c9Paul Duffin  private static class ForwardingArithmetic implements Arithmetic {
2547dd252788645e940eada959bdde927426e2531c9Paul Duffin    private final Arithmetic arithmetic;
2557dd252788645e940eada959bdde927426e2531c9Paul Duffin
2567dd252788645e940eada959bdde927426e2531c9Paul Duffin    public ForwardingArithmetic(Arithmetic arithmetic) {
2577dd252788645e940eada959bdde927426e2531c9Paul Duffin      this.arithmetic = arithmetic;
2587dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
2597dd252788645e940eada959bdde927426e2531c9Paul Duffin
2607dd252788645e940eada959bdde927426e2531c9Paul Duffin    @Override public int add(int a, int b) {
2617dd252788645e940eada959bdde927426e2531c9Paul Duffin      return arithmetic.add(a, b);
2627dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
2637dd252788645e940eada959bdde927426e2531c9Paul Duffin
2647dd252788645e940eada959bdde927426e2531c9Paul Duffin    @Override public int minus(int a, int b) {
2657dd252788645e940eada959bdde927426e2531c9Paul Duffin      return arithmetic.minus(a, b);
2667dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
2677dd252788645e940eada959bdde927426e2531c9Paul Duffin
2687dd252788645e940eada959bdde927426e2531c9Paul Duffin    @Override public String toString() {
2697dd252788645e940eada959bdde927426e2531c9Paul Duffin      return arithmetic.toString();
2707dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
2717dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
2727dd252788645e940eada959bdde927426e2531c9Paul Duffin
2737dd252788645e940eada959bdde927426e2531c9Paul Duffin  private static class FailsToForwardParameters implements Adder {
2747dd252788645e940eada959bdde927426e2531c9Paul Duffin    private final Adder adder;
2757dd252788645e940eada959bdde927426e2531c9Paul Duffin
2767dd252788645e940eada959bdde927426e2531c9Paul Duffin    FailsToForwardParameters(Adder adder) {
2777dd252788645e940eada959bdde927426e2531c9Paul Duffin      this.adder = adder;
2787dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
2797dd252788645e940eada959bdde927426e2531c9Paul Duffin
2807dd252788645e940eada959bdde927426e2531c9Paul Duffin    @Override public int add(int a, int b) {
2817dd252788645e940eada959bdde927426e2531c9Paul Duffin      return adder.add(b, a);
2827dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
2837dd252788645e940eada959bdde927426e2531c9Paul Duffin
2847dd252788645e940eada959bdde927426e2531c9Paul Duffin    @Override public String toString() {
2857dd252788645e940eada959bdde927426e2531c9Paul Duffin      return adder.toString();
2867dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
2877dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
2887dd252788645e940eada959bdde927426e2531c9Paul Duffin
2897dd252788645e940eada959bdde927426e2531c9Paul Duffin  private static class FailsToForwardReturnValue implements Adder {
2907dd252788645e940eada959bdde927426e2531c9Paul Duffin    private final Adder adder;
2917dd252788645e940eada959bdde927426e2531c9Paul Duffin
2927dd252788645e940eada959bdde927426e2531c9Paul Duffin    FailsToForwardReturnValue(Adder adder) {
2937dd252788645e940eada959bdde927426e2531c9Paul Duffin      this.adder = adder;
2947dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
2957dd252788645e940eada959bdde927426e2531c9Paul Duffin
2967dd252788645e940eada959bdde927426e2531c9Paul Duffin    @Override public int add(int a, int b) {
2977dd252788645e940eada959bdde927426e2531c9Paul Duffin      return adder.add(a, b) + 1;
2987dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
2997dd252788645e940eada959bdde927426e2531c9Paul Duffin
3007dd252788645e940eada959bdde927426e2531c9Paul Duffin    @Override public String toString() {
3017dd252788645e940eada959bdde927426e2531c9Paul Duffin      return adder.toString();
3027dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
3037dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
3047dd252788645e940eada959bdde927426e2531c9Paul Duffin
3057dd252788645e940eada959bdde927426e2531c9Paul Duffin  private static class FailsToPropagageException implements Adder {
3067dd252788645e940eada959bdde927426e2531c9Paul Duffin    private final Adder adder;
3077dd252788645e940eada959bdde927426e2531c9Paul Duffin
3087dd252788645e940eada959bdde927426e2531c9Paul Duffin    FailsToPropagageException(Adder adder) {
3097dd252788645e940eada959bdde927426e2531c9Paul Duffin      this.adder = adder;
3107dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
3117dd252788645e940eada959bdde927426e2531c9Paul Duffin
3127dd252788645e940eada959bdde927426e2531c9Paul Duffin    @Override public int add(int a, int b) {
3137dd252788645e940eada959bdde927426e2531c9Paul Duffin      try {
3147dd252788645e940eada959bdde927426e2531c9Paul Duffin        return adder.add(a, b);
3157dd252788645e940eada959bdde927426e2531c9Paul Duffin      } catch (Exception e) {
3167dd252788645e940eada959bdde927426e2531c9Paul Duffin        // swallow!
3177dd252788645e940eada959bdde927426e2531c9Paul Duffin        return 0;
3187dd252788645e940eada959bdde927426e2531c9Paul Duffin      }
3197dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
3207dd252788645e940eada959bdde927426e2531c9Paul Duffin
3217dd252788645e940eada959bdde927426e2531c9Paul Duffin    @Override public String toString() {
3227dd252788645e940eada959bdde927426e2531c9Paul Duffin      return adder.toString();
3237dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
3247dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
3257dd252788645e940eada959bdde927426e2531c9Paul Duffin
3267dd252788645e940eada959bdde927426e2531c9Paul Duffin  public interface Arithmetic extends Adder {
3277dd252788645e940eada959bdde927426e2531c9Paul Duffin    int minus(int a, int b);
3287dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
3297dd252788645e940eada959bdde927426e2531c9Paul Duffin
3307dd252788645e940eada959bdde927426e2531c9Paul Duffin  private static class ForwardsToTheWrongMethod implements Arithmetic {
3317dd252788645e940eada959bdde927426e2531c9Paul Duffin    private final Arithmetic arithmetic;
3327dd252788645e940eada959bdde927426e2531c9Paul Duffin
3337dd252788645e940eada959bdde927426e2531c9Paul Duffin    ForwardsToTheWrongMethod(Arithmetic arithmetic) {
3347dd252788645e940eada959bdde927426e2531c9Paul Duffin      this.arithmetic = arithmetic;
3357dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
3367dd252788645e940eada959bdde927426e2531c9Paul Duffin
3377dd252788645e940eada959bdde927426e2531c9Paul Duffin    @Override public int minus(int a, int b) { // bad!
3387dd252788645e940eada959bdde927426e2531c9Paul Duffin      return arithmetic.add(b, a);
3397dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
3407dd252788645e940eada959bdde927426e2531c9Paul Duffin
3417dd252788645e940eada959bdde927426e2531c9Paul Duffin    @Override public int add(int a, int b) {
3427dd252788645e940eada959bdde927426e2531c9Paul Duffin      return arithmetic.add(b, a);
3437dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
3447dd252788645e940eada959bdde927426e2531c9Paul Duffin
3457dd252788645e940eada959bdde927426e2531c9Paul Duffin    @Override public String toString() {
3467dd252788645e940eada959bdde927426e2531c9Paul Duffin      return arithmetic.toString();
3477dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
3487dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
3497dd252788645e940eada959bdde927426e2531c9Paul Duffin
3507dd252788645e940eada959bdde927426e2531c9Paul Duffin  private interface ParameterTypesDifferent {
3517dd252788645e940eada959bdde927426e2531c9Paul Duffin    void foo(String s, Runnable r, Number n, Iterable<?> it, boolean b, Equivalence<String> eq,
3527dd252788645e940eada959bdde927426e2531c9Paul Duffin        Exception e, InputStream in, Comparable<?> c, Ordering<Integer> ord,
3537dd252788645e940eada959bdde927426e2531c9Paul Duffin        Charset charset, TimeUnit unit, Class<?> cls, Joiner joiner,
3547dd252788645e940eada959bdde927426e2531c9Paul Duffin        Pattern pattern, UnsignedInteger ui, UnsignedLong ul, StringBuilder sb,
3557dd252788645e940eada959bdde927426e2531c9Paul Duffin        Predicate<?> pred, Function<?, ?> func, Object obj);
3567dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
3577dd252788645e940eada959bdde927426e2531c9Paul Duffin
3587dd252788645e940eada959bdde927426e2531c9Paul Duffin  private static class ParameterTypesDifferentForwarder implements ParameterTypesDifferent {
3597dd252788645e940eada959bdde927426e2531c9Paul Duffin    private final ParameterTypesDifferent delegate;
3607dd252788645e940eada959bdde927426e2531c9Paul Duffin
3617dd252788645e940eada959bdde927426e2531c9Paul Duffin    public ParameterTypesDifferentForwarder(ParameterTypesDifferent delegate) {
3627dd252788645e940eada959bdde927426e2531c9Paul Duffin      this.delegate = delegate;
3637dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
3647dd252788645e940eada959bdde927426e2531c9Paul Duffin
3657dd252788645e940eada959bdde927426e2531c9Paul Duffin    @Override public void foo(
3667dd252788645e940eada959bdde927426e2531c9Paul Duffin        String s, Runnable r, Number n, Iterable<?> it, boolean b, Equivalence<String> eq,
3677dd252788645e940eada959bdde927426e2531c9Paul Duffin        Exception e, InputStream in, Comparable<?> c, Ordering<Integer> ord,
3687dd252788645e940eada959bdde927426e2531c9Paul Duffin        Charset charset, TimeUnit unit, Class<?> cls, Joiner joiner,
3697dd252788645e940eada959bdde927426e2531c9Paul Duffin        Pattern pattern, UnsignedInteger ui, UnsignedLong ul, StringBuilder sb,
3707dd252788645e940eada959bdde927426e2531c9Paul Duffin        Predicate<?> pred, Function<?, ?> func, Object obj) {
3717dd252788645e940eada959bdde927426e2531c9Paul Duffin      delegate.foo(s,
3727dd252788645e940eada959bdde927426e2531c9Paul Duffin          r, n, it, b, eq, e, in, c, ord, charset, unit, cls, joiner, pattern,
3737dd252788645e940eada959bdde927426e2531c9Paul Duffin          ui, ul, sb, pred, func, obj);
3747dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
3757dd252788645e940eada959bdde927426e2531c9Paul Duffin
3767dd252788645e940eada959bdde927426e2531c9Paul Duffin    @Override public String toString() {
3777dd252788645e940eada959bdde927426e2531c9Paul Duffin      return delegate.toString();
3787dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
3797dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
3807dd252788645e940eada959bdde927426e2531c9Paul Duffin
3817dd252788645e940eada959bdde927426e2531c9Paul Duffin  public void testCovariantReturn() {
3827dd252788645e940eada959bdde927426e2531c9Paul Duffin    new ForwardingWrapperTester().testForwarding(Sub.class, new Function<Sub, Sub>() {
3837dd252788645e940eada959bdde927426e2531c9Paul Duffin      @Override public Sub apply(Sub sub) {
3847dd252788645e940eada959bdde927426e2531c9Paul Duffin        return new ForwardingSub(sub);
3857dd252788645e940eada959bdde927426e2531c9Paul Duffin      }
3867dd252788645e940eada959bdde927426e2531c9Paul Duffin    });
3877dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
3887dd252788645e940eada959bdde927426e2531c9Paul Duffin
3897dd252788645e940eada959bdde927426e2531c9Paul Duffin  interface Base {
3907dd252788645e940eada959bdde927426e2531c9Paul Duffin    CharSequence getId();
3917dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
3927dd252788645e940eada959bdde927426e2531c9Paul Duffin
3937dd252788645e940eada959bdde927426e2531c9Paul Duffin  interface Sub extends Base {
3947dd252788645e940eada959bdde927426e2531c9Paul Duffin    @Override String getId();
3957dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
3967dd252788645e940eada959bdde927426e2531c9Paul Duffin
3977dd252788645e940eada959bdde927426e2531c9Paul Duffin  private static class ForwardingSub implements Sub {
3987dd252788645e940eada959bdde927426e2531c9Paul Duffin    private final Sub delegate;
3997dd252788645e940eada959bdde927426e2531c9Paul Duffin
4007dd252788645e940eada959bdde927426e2531c9Paul Duffin    ForwardingSub(Sub delegate) {
4017dd252788645e940eada959bdde927426e2531c9Paul Duffin      this.delegate = delegate;
4027dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
4037dd252788645e940eada959bdde927426e2531c9Paul Duffin
4047dd252788645e940eada959bdde927426e2531c9Paul Duffin    @Override public String getId() {
4057dd252788645e940eada959bdde927426e2531c9Paul Duffin      return delegate.getId();
4067dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
4077dd252788645e940eada959bdde927426e2531c9Paul Duffin
4087dd252788645e940eada959bdde927426e2531c9Paul Duffin    @Override public String toString() {
4097dd252788645e940eada959bdde927426e2531c9Paul Duffin      return delegate.toString();
4107dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
4117dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
4127dd252788645e940eada959bdde927426e2531c9Paul Duffin
4137dd252788645e940eada959bdde927426e2531c9Paul Duffin  private interface Equals {
4147dd252788645e940eada959bdde927426e2531c9Paul Duffin    @Override boolean equals(Object obj);
4157dd252788645e940eada959bdde927426e2531c9Paul Duffin    @Override int hashCode();
4167dd252788645e940eada959bdde927426e2531c9Paul Duffin    @Override String toString();
4177dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
4187dd252788645e940eada959bdde927426e2531c9Paul Duffin
4197dd252788645e940eada959bdde927426e2531c9Paul Duffin  private static class NoDelegateToEquals implements Equals {
4207dd252788645e940eada959bdde927426e2531c9Paul Duffin
4217dd252788645e940eada959bdde927426e2531c9Paul Duffin    private static Function<Equals, Equals> WRAPPER = new Function<Equals, Equals>() {
4227dd252788645e940eada959bdde927426e2531c9Paul Duffin      @Override public NoDelegateToEquals apply(Equals delegate) {
4237dd252788645e940eada959bdde927426e2531c9Paul Duffin        return new NoDelegateToEquals(delegate);
4247dd252788645e940eada959bdde927426e2531c9Paul Duffin      }
4257dd252788645e940eada959bdde927426e2531c9Paul Duffin    };
4267dd252788645e940eada959bdde927426e2531c9Paul Duffin
4277dd252788645e940eada959bdde927426e2531c9Paul Duffin    private final Equals delegate;
4287dd252788645e940eada959bdde927426e2531c9Paul Duffin
4297dd252788645e940eada959bdde927426e2531c9Paul Duffin    NoDelegateToEquals(Equals delegate) {
4307dd252788645e940eada959bdde927426e2531c9Paul Duffin      this.delegate = delegate;
4317dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
4327dd252788645e940eada959bdde927426e2531c9Paul Duffin
4337dd252788645e940eada959bdde927426e2531c9Paul Duffin    @Override public String toString() {
4347dd252788645e940eada959bdde927426e2531c9Paul Duffin      return delegate.toString();
4357dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
4367dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
4377dd252788645e940eada959bdde927426e2531c9Paul Duffin
4387dd252788645e940eada959bdde927426e2531c9Paul Duffin  public void testExplicitEqualsAndHashCodeNotDelegatedByDefault() {
4397dd252788645e940eada959bdde927426e2531c9Paul Duffin    new ForwardingWrapperTester()
4407dd252788645e940eada959bdde927426e2531c9Paul Duffin        .testForwarding(Equals.class, NoDelegateToEquals.WRAPPER);
4417dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
4427dd252788645e940eada959bdde927426e2531c9Paul Duffin
4437dd252788645e940eada959bdde927426e2531c9Paul Duffin  public void testExplicitEqualsAndHashCodeDelegatedWhenExplicitlyAsked() {
4447dd252788645e940eada959bdde927426e2531c9Paul Duffin    try {
4457dd252788645e940eada959bdde927426e2531c9Paul Duffin      new ForwardingWrapperTester()
4467dd252788645e940eada959bdde927426e2531c9Paul Duffin          .includingEquals()
4477dd252788645e940eada959bdde927426e2531c9Paul Duffin          .testForwarding(Equals.class, NoDelegateToEquals.WRAPPER);
4487dd252788645e940eada959bdde927426e2531c9Paul Duffin    } catch (AssertionError expected) {
4497dd252788645e940eada959bdde927426e2531c9Paul Duffin      return;
4507dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
4517dd252788645e940eada959bdde927426e2531c9Paul Duffin    fail("Should have failed");
4527dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
4530888a09821a98ac0680fad765217302858e70fa4Paul Duffin
4540888a09821a98ac0680fad765217302858e70fa4Paul Duffin  /**
4550888a09821a98ac0680fad765217302858e70fa4Paul Duffin   * An interface for the 2 ways that a chaining call might be defined.
4560888a09821a98ac0680fad765217302858e70fa4Paul Duffin   */
4570888a09821a98ac0680fad765217302858e70fa4Paul Duffin  private interface ChainingCalls {
4580888a09821a98ac0680fad765217302858e70fa4Paul Duffin    // A method that is defined to 'return this'
4590888a09821a98ac0680fad765217302858e70fa4Paul Duffin    ChainingCalls chainingCall();
4600888a09821a98ac0680fad765217302858e70fa4Paul Duffin    // A method that just happens to return a ChainingCalls object
4610888a09821a98ac0680fad765217302858e70fa4Paul Duffin    ChainingCalls nonChainingCall();
4620888a09821a98ac0680fad765217302858e70fa4Paul Duffin  }
4630888a09821a98ac0680fad765217302858e70fa4Paul Duffin
4640888a09821a98ac0680fad765217302858e70fa4Paul Duffin  private static class ForwardingChainingCalls implements ChainingCalls {
4650888a09821a98ac0680fad765217302858e70fa4Paul Duffin    final ChainingCalls delegate;
4660888a09821a98ac0680fad765217302858e70fa4Paul Duffin
4670888a09821a98ac0680fad765217302858e70fa4Paul Duffin    ForwardingChainingCalls(ChainingCalls delegate) {
4680888a09821a98ac0680fad765217302858e70fa4Paul Duffin      this.delegate = delegate;
4690888a09821a98ac0680fad765217302858e70fa4Paul Duffin    }
4700888a09821a98ac0680fad765217302858e70fa4Paul Duffin
4710888a09821a98ac0680fad765217302858e70fa4Paul Duffin    @Override public ForwardingChainingCalls chainingCall() {
4720888a09821a98ac0680fad765217302858e70fa4Paul Duffin      delegate.chainingCall();
4730888a09821a98ac0680fad765217302858e70fa4Paul Duffin      return this;
4740888a09821a98ac0680fad765217302858e70fa4Paul Duffin    }
4750888a09821a98ac0680fad765217302858e70fa4Paul Duffin
4760888a09821a98ac0680fad765217302858e70fa4Paul Duffin    @Override public ChainingCalls nonChainingCall() {
4770888a09821a98ac0680fad765217302858e70fa4Paul Duffin      return delegate.nonChainingCall();
4780888a09821a98ac0680fad765217302858e70fa4Paul Duffin    }
4790888a09821a98ac0680fad765217302858e70fa4Paul Duffin
4800888a09821a98ac0680fad765217302858e70fa4Paul Duffin    @Override public String toString() {
4810888a09821a98ac0680fad765217302858e70fa4Paul Duffin      return delegate.toString();
4820888a09821a98ac0680fad765217302858e70fa4Paul Duffin    }
4830888a09821a98ac0680fad765217302858e70fa4Paul Duffin  }
4840888a09821a98ac0680fad765217302858e70fa4Paul Duffin
4850888a09821a98ac0680fad765217302858e70fa4Paul Duffin  public void testChainingCalls() {
4860888a09821a98ac0680fad765217302858e70fa4Paul Duffin    tester.testForwarding(ChainingCalls.class,
4870888a09821a98ac0680fad765217302858e70fa4Paul Duffin        new Function<ChainingCalls, ChainingCalls>() {
4880888a09821a98ac0680fad765217302858e70fa4Paul Duffin          @Override public ChainingCalls apply(ChainingCalls delegate) {
4890888a09821a98ac0680fad765217302858e70fa4Paul Duffin            return new ForwardingChainingCalls(delegate);
4900888a09821a98ac0680fad765217302858e70fa4Paul Duffin          }
4910888a09821a98ac0680fad765217302858e70fa4Paul Duffin        });
4920888a09821a98ac0680fad765217302858e70fa4Paul Duffin  }
4937dd252788645e940eada959bdde927426e2531c9Paul Duffin}
494