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