1579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson/* 2579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Copyright (C) 2011 The Android Open Source Project 3579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 4579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Licensed under the Apache License, Version 2.0 (the "License"); 5579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * you may not use this file except in compliance with the License. 6579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * You may obtain a copy of the License at 7579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 8579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * http://www.apache.org/licenses/LICENSE-2.0 9579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 10579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Unless required by applicable law or agreed to in writing, software 11579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * distributed under the License is distributed on an "AS IS" BASIS, 12579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * See the License for the specific language governing permissions and 14579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * limitations under the License. 15579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 16579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 17b8a5896885d4da2b798888b688a46df1adbf5b89Paul Duffinpackage com.android.dx.stock; 18b8a5896885d4da2b798888b688a46df1adbf5b89Paul Duffin 19b8a5896885d4da2b798888b688a46df1adbf5b89Paul Duffinimport com.android.dx.DexMakerTest; 20b8a5896885d4da2b798888b688a46df1adbf5b89Paul Duffinimport junit.framework.AssertionFailedError; 21b8a5896885d4da2b798888b688a46df1adbf5b89Paul Duffinimport org.junit.After; 22b8a5896885d4da2b798888b688a46df1adbf5b89Paul Duffinimport org.junit.Before; 23b8a5896885d4da2b798888b688a46df1adbf5b89Paul Duffinimport org.junit.Test; 24579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 25579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilsonimport java.io.File; 26579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilsonimport java.io.IOException; 278d53a06d10c6e2b96be6857aede5e4661804611eAndrew Yousefimport java.lang.reflect.Field; 28579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilsonimport java.lang.reflect.InvocationHandler; 29579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilsonimport java.lang.reflect.Method; 30579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilsonimport java.lang.reflect.UndeclaredThrowableException; 311af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilsonimport java.util.Arrays; 328d53a06d10c6e2b96be6857aede5e4661804611eAndrew Yousefimport java.util.Map; 33579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilsonimport java.util.Random; 341af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilsonimport java.util.concurrent.Callable; 351af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilsonimport java.util.concurrent.atomic.AtomicInteger; 36579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 37b8a5896885d4da2b798888b688a46df1adbf5b89Paul Duffinimport static com.android.dx.util.TestUtil.DELTA_DOUBLE; 38b8a5896885d4da2b798888b688a46df1adbf5b89Paul Duffinimport static com.android.dx.util.TestUtil.DELTA_FLOAT; 39b8a5896885d4da2b798888b688a46df1adbf5b89Paul Duffinimport static junit.framework.Assert.assertFalse; 40b8a5896885d4da2b798888b688a46df1adbf5b89Paul Duffinimport static junit.framework.Assert.assertNotNull; 41b8a5896885d4da2b798888b688a46df1adbf5b89Paul Duffinimport static junit.framework.Assert.assertSame; 42b8a5896885d4da2b798888b688a46df1adbf5b89Paul Duffinimport static junit.framework.Assert.assertTrue; 43b8a5896885d4da2b798888b688a46df1adbf5b89Paul Duffinimport static junit.framework.Assert.fail; 44b8a5896885d4da2b798888b688a46df1adbf5b89Paul Duffinimport static org.junit.Assert.assertEquals; 45b8a5896885d4da2b798888b688a46df1adbf5b89Paul Duffin 46b8a5896885d4da2b798888b688a46df1adbf5b89Paul Duffinpublic class ProxyBuilderTest { 47579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson private FakeInvocationHandler fakeHandler = new FakeInvocationHandler(); 48054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef private File versionedDxDir = new File(DexMakerTest.getDataDirectory(), "v1"); 49054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef 50b8a5896885d4da2b798888b688a46df1adbf5b89Paul Duffin @Before 51054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef public void setUp() throws Exception { 52b8a5896885d4da2b798888b688a46df1adbf5b89Paul Duffin versionedDxDir.mkdirs(); 53054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef clearVersionedDxDir(); 54054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef getGeneratedProxyClasses().clear(); 55054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef } 56054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef 57b8a5896885d4da2b798888b688a46df1adbf5b89Paul Duffin @After 58054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef public void tearDown() throws Exception { 59054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef getGeneratedProxyClasses().clear(); 60054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef clearVersionedDxDir(); 61054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef } 62054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef 63054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef private void clearVersionedDxDir() { 64b8a5896885d4da2b798888b688a46df1adbf5b89Paul Duffin for (File file : versionedDxDir.listFiles()) { 65b8a5896885d4da2b798888b688a46df1adbf5b89Paul Duffin file.delete(); 66054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef } 67054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef } 68579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 69579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public static class SimpleClass { 70579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public String simpleMethod() { 71579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson throw new AssertionFailedError(); 72579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 73579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 74579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 75b8a5896885d4da2b798888b688a46df1adbf5b89Paul Duffin public static class ExampleClass { 76b8a5896885d4da2b798888b688a46df1adbf5b89Paul Duffin public String exampleMethod() { 77b8a5896885d4da2b798888b688a46df1adbf5b89Paul Duffin throw new AssertionFailedError(); 78b8a5896885d4da2b798888b688a46df1adbf5b89Paul Duffin } 79b8a5896885d4da2b798888b688a46df1adbf5b89Paul Duffin } 80b8a5896885d4da2b798888b688a46df1adbf5b89Paul Duffin 81b8a5896885d4da2b798888b688a46df1adbf5b89Paul Duffin public static class ExampleOperationClass { 82b8a5896885d4da2b798888b688a46df1adbf5b89Paul Duffin public String exampleMethod() { 83b8a5896885d4da2b798888b688a46df1adbf5b89Paul Duffin throw new AssertionFailedError(); 84b8a5896885d4da2b798888b688a46df1adbf5b89Paul Duffin } 85b8a5896885d4da2b798888b688a46df1adbf5b89Paul Duffin } 86b8a5896885d4da2b798888b688a46df1adbf5b89Paul Duffin 87b8a5896885d4da2b798888b688a46df1adbf5b89Paul Duffin @Test 88579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public void testExampleOperation() throws Throwable { 89579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson fakeHandler.setFakeResult("expected"); 90b8a5896885d4da2b798888b688a46df1adbf5b89Paul Duffin ExampleClass proxy = proxyFor(ExampleClass.class).build(); 91b8a5896885d4da2b798888b688a46df1adbf5b89Paul Duffin assertEquals("expected", proxy.exampleMethod()); 92054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef assertEquals(2, versionedDxDir.listFiles().length); 93054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef } 94054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef 95b8a5896885d4da2b798888b688a46df1adbf5b89Paul Duffin @Test 96054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef public void testExampleOperation_DexMakerCaching() throws Throwable { 97054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef fakeHandler.setFakeResult("expected"); 98b8a5896885d4da2b798888b688a46df1adbf5b89Paul Duffin ExampleOperationClass proxy = proxyFor(ExampleOperationClass.class).build(); 99054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef assertEquals(2, versionedDxDir.listFiles().length); 100b8a5896885d4da2b798888b688a46df1adbf5b89Paul Duffin assertEquals("expected", proxy.exampleMethod()); 101054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef 102054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef // Force ProxyBuilder to create a DexMaker generator and call DexMaker.generateAndLoad(). 103054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef getGeneratedProxyClasses().clear(); 104054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef 105b8a5896885d4da2b798888b688a46df1adbf5b89Paul Duffin proxy = proxyFor(ExampleOperationClass.class).build(); 106054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef assertEquals(2, versionedDxDir.listFiles().length); 107b8a5896885d4da2b798888b688a46df1adbf5b89Paul Duffin assertEquals("expected", proxy.exampleMethod()); 108579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 109579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 110579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public static class ConstructorTakesArguments { 111579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson private final String argument; 112579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 113579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public ConstructorTakesArguments(String arg) { 114579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson argument = arg; 115579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 116579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 117579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public String method() { 118579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson throw new AssertionFailedError(); 119579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 120579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 121579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 122b8a5896885d4da2b798888b688a46df1adbf5b89Paul Duffin @Test 123579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public void testConstruction_SucceedsIfCorrectArgumentsProvided() throws Throwable { 124579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson ConstructorTakesArguments proxy = proxyFor(ConstructorTakesArguments.class) 125579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson .constructorArgTypes(String.class) 126579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson .constructorArgValues("hello") 127579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson .build(); 128579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson assertEquals("hello", proxy.argument); 129579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson proxy.method(); 130579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 131579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 132b8a5896885d4da2b798888b688a46df1adbf5b89Paul Duffin @Test(expected = IllegalArgumentException.class) 133579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public void testConstruction_FailsWithWrongNumberOfArguments() throws Throwable { 134b8a5896885d4da2b798888b688a46df1adbf5b89Paul Duffin proxyFor(ConstructorTakesArguments.class).build(); 135579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 136579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 137b8a5896885d4da2b798888b688a46df1adbf5b89Paul Duffin @Test(expected = UnsupportedOperationException.class) 138579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public void testClassIsNotAccessbile_FailsWithUnsupportedOperationException() throws Exception { 139b8a5896885d4da2b798888b688a46df1adbf5b89Paul Duffin class MethodVisibilityClass {} 140b8a5896885d4da2b798888b688a46df1adbf5b89Paul Duffin proxyFor(MethodVisibilityClass.class).build(); 141579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 142579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 143b8a5896885d4da2b798888b688a46df1adbf5b89Paul Duffin private static class PrivateVisibilityClass {} 144579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 145b8a5896885d4da2b798888b688a46df1adbf5b89Paul Duffin @Test(expected = UnsupportedOperationException.class) 146579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public void testPrivateClass_FailsWithUnsupportedOperationException() throws Exception { 147b8a5896885d4da2b798888b688a46df1adbf5b89Paul Duffin proxyFor(PrivateVisibilityClass.class).build(); 148579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 149579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 150579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson protected static class ProtectedVisibilityClass { 151579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public String foo() { 152579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson throw new AssertionFailedError(); 153579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 154579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 155579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 156b8a5896885d4da2b798888b688a46df1adbf5b89Paul Duffin @Test 157579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public void testProtectedVisibility_WorksFine() throws Exception { 158579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson assertEquals("fake result", proxyFor(ProtectedVisibilityClass.class).build().foo()); 159579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 160579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 161579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public static class HasFinalMethod { 162579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public String nonFinalMethod() { 163579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return "non-final method"; 164579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 165579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 166579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public final String finalMethod() { 167579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return "final method"; 168579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 169579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 170579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 171b8a5896885d4da2b798888b688a46df1adbf5b89Paul Duffin @Test 172579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public void testCanProxyClassesWithFinalMethods_WillNotCallTheFinalMethod() throws Throwable { 173579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson HasFinalMethod proxy = proxyFor(HasFinalMethod.class).build(); 174579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson assertEquals("final method", proxy.finalMethod()); 175579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson assertEquals("fake result", proxy.nonFinalMethod()); 176579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 177579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 178579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public static class HasPrivateMethod { 179579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson private String result() { 180579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return "expected"; 181579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 182579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 183579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 184b8a5896885d4da2b798888b688a46df1adbf5b89Paul Duffin @Test 185579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public void testProxyingPrivateMethods_NotIntercepted() throws Throwable { 186a13e8e98b64e3f5271759dac44967f1c24c76995Paul Duffin HasPrivateMethod proxy = proxyFor(HasPrivateMethod.class).build(); 187a13e8e98b64e3f5271759dac44967f1c24c76995Paul Duffin try { 188a13e8e98b64e3f5271759dac44967f1c24c76995Paul Duffin proxy.getClass().getDeclaredMethod("result"); 189a13e8e98b64e3f5271759dac44967f1c24c76995Paul Duffin fail(); 190a13e8e98b64e3f5271759dac44967f1c24c76995Paul Duffin } catch (NoSuchMethodException expected) { 191a13e8e98b64e3f5271759dac44967f1c24c76995Paul Duffin 192a13e8e98b64e3f5271759dac44967f1c24c76995Paul Duffin } 193a13e8e98b64e3f5271759dac44967f1c24c76995Paul Duffin 194a13e8e98b64e3f5271759dac44967f1c24c76995Paul Duffin assertEquals("expected", proxy.result()); 195579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 196579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 197579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public static class HasPackagePrivateMethod { 198579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson String result() { 199579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson throw new AssertionFailedError(); 200579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 201579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 202579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 203a13e8e98b64e3f5271759dac44967f1c24c76995Paul Duffin public void testProxyingPackagePrivateMethods_NotIntercepted() 204a13e8e98b64e3f5271759dac44967f1c24c76995Paul Duffin throws Throwable { 205a13e8e98b64e3f5271759dac44967f1c24c76995Paul Duffin HasPackagePrivateMethod proxy = proxyFor(HasPackagePrivateMethod.class) 206a13e8e98b64e3f5271759dac44967f1c24c76995Paul Duffin .build(); 207a13e8e98b64e3f5271759dac44967f1c24c76995Paul Duffin try { 208a13e8e98b64e3f5271759dac44967f1c24c76995Paul Duffin proxy.getClass().getDeclaredMethod("result"); 209a13e8e98b64e3f5271759dac44967f1c24c76995Paul Duffin fail(); 210a13e8e98b64e3f5271759dac44967f1c24c76995Paul Duffin } catch (NoSuchMethodException expected) { 211a13e8e98b64e3f5271759dac44967f1c24c76995Paul Duffin 212a13e8e98b64e3f5271759dac44967f1c24c76995Paul Duffin } 213a13e8e98b64e3f5271759dac44967f1c24c76995Paul Duffin 214a13e8e98b64e3f5271759dac44967f1c24c76995Paul Duffin try { 215a13e8e98b64e3f5271759dac44967f1c24c76995Paul Duffin proxy.result(); 216a13e8e98b64e3f5271759dac44967f1c24c76995Paul Duffin fail(); 217a13e8e98b64e3f5271759dac44967f1c24c76995Paul Duffin } catch (AssertionFailedError expected) { 218a13e8e98b64e3f5271759dac44967f1c24c76995Paul Duffin 219a13e8e98b64e3f5271759dac44967f1c24c76995Paul Duffin } 220579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 221579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 222579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public static class HasProtectedMethod { 223579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson protected String result() { 224579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson throw new AssertionFailedError(); 225579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 226579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 227579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 228b8a5896885d4da2b798888b688a46df1adbf5b89Paul Duffin @Test 229579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public void testProxyingProtectedMethods_AreIntercepted() throws Throwable { 230579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson assertEquals("fake result", proxyFor(HasProtectedMethod.class).build().result()); 231579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 232579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 233a13e8e98b64e3f5271759dac44967f1c24c76995Paul Duffin public static class MyParentClass { 234a13e8e98b64e3f5271759dac44967f1c24c76995Paul Duffin String someMethod() { 235a13e8e98b64e3f5271759dac44967f1c24c76995Paul Duffin return "package"; 236a13e8e98b64e3f5271759dac44967f1c24c76995Paul Duffin } 237a13e8e98b64e3f5271759dac44967f1c24c76995Paul Duffin } 238a13e8e98b64e3f5271759dac44967f1c24c76995Paul Duffin 239a13e8e98b64e3f5271759dac44967f1c24c76995Paul Duffin public static class MyChildClassWithProtectedMethod extends MyParentClass { 240a13e8e98b64e3f5271759dac44967f1c24c76995Paul Duffin @Override 241a13e8e98b64e3f5271759dac44967f1c24c76995Paul Duffin protected String someMethod() { 242a13e8e98b64e3f5271759dac44967f1c24c76995Paul Duffin return "protected"; 243a13e8e98b64e3f5271759dac44967f1c24c76995Paul Duffin } 244a13e8e98b64e3f5271759dac44967f1c24c76995Paul Duffin } 245a13e8e98b64e3f5271759dac44967f1c24c76995Paul Duffin 246a13e8e98b64e3f5271759dac44967f1c24c76995Paul Duffin public static class MyChildClassWithPublicMethod extends MyParentClass { 247a13e8e98b64e3f5271759dac44967f1c24c76995Paul Duffin @Override 248a13e8e98b64e3f5271759dac44967f1c24c76995Paul Duffin public String someMethod() { 249a13e8e98b64e3f5271759dac44967f1c24c76995Paul Duffin return "public"; 250a13e8e98b64e3f5271759dac44967f1c24c76995Paul Duffin } 251a13e8e98b64e3f5271759dac44967f1c24c76995Paul Duffin } 252a13e8e98b64e3f5271759dac44967f1c24c76995Paul Duffin 253b8a5896885d4da2b798888b688a46df1adbf5b89Paul Duffin @Test 254a13e8e98b64e3f5271759dac44967f1c24c76995Paul Duffin public void testProxying_ClassHierarchy() throws Throwable { 255a13e8e98b64e3f5271759dac44967f1c24c76995Paul Duffin assertEquals("package", proxyFor(MyParentClass.class).build().someMethod()); 256a13e8e98b64e3f5271759dac44967f1c24c76995Paul Duffin assertEquals("fake result", proxyFor(MyChildClassWithProtectedMethod.class).build().someMethod()); 257a13e8e98b64e3f5271759dac44967f1c24c76995Paul Duffin assertEquals("fake result", proxyFor(MyChildClassWithPublicMethod.class).build().someMethod()); 258a13e8e98b64e3f5271759dac44967f1c24c76995Paul Duffin } 259a13e8e98b64e3f5271759dac44967f1c24c76995Paul Duffin 260579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public static class HasVoidMethod { 261579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public void dangerousMethod() { 262579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson fail(); 263579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 264579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 265579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 266b8a5896885d4da2b798888b688a46df1adbf5b89Paul Duffin @Test 267579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public void testVoidMethod_ShouldNotThrowRuntimeException() throws Throwable { 268579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson proxyFor(HasVoidMethod.class).build().dangerousMethod(); 269579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 270579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 271b8a5896885d4da2b798888b688a46df1adbf5b89Paul Duffin @Test 272b8a5896885d4da2b798888b688a46df1adbf5b89Paul Duffin @SuppressWarnings("EqualsWithItself") 273579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public void testObjectMethodsAreAlsoProxied() throws Throwable { 274579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson Object proxy = proxyFor(Object.class).build(); 275579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson fakeHandler.setFakeResult("mystring"); 276579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson assertEquals("mystring", proxy.toString()); 277579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson fakeHandler.setFakeResult(-1); 278579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson assertEquals(-1, proxy.hashCode()); 279579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson fakeHandler.setFakeResult(false); 280579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson assertEquals(false, proxy.equals(proxy)); 281579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 282579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 2831af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson public static class AllReturnTypes { 284579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public boolean getBoolean() { return true; } 285579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public int getInt() { return 1; } 286579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public byte getByte() { return 2; } 287579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public long getLong() { return 3L; } 288579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public short getShort() { return 4; } 289579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public float getFloat() { return 5f; } 290579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public double getDouble() { return 6.0; } 291579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public char getChar() { return 'c'; } 2921af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson public int[] getIntArray() { return new int[] { 8, 9 }; } 2931af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson public String[] getStringArray() { return new String[] { "d", "e" }; } 294579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 295579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 296b8a5896885d4da2b798888b688a46df1adbf5b89Paul Duffin @Test 2971af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson public void testAllReturnTypes() throws Throwable { 2981af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson AllReturnTypes proxy = proxyFor(AllReturnTypes.class).build(); 299579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson fakeHandler.setFakeResult(false); 300579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson assertEquals(false, proxy.getBoolean()); 301579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson fakeHandler.setFakeResult(8); 302579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson assertEquals(8, proxy.getInt()); 303579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson fakeHandler.setFakeResult((byte) 9); 304579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson assertEquals(9, proxy.getByte()); 305579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson fakeHandler.setFakeResult(10L); 306579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson assertEquals(10, proxy.getLong()); 307579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson fakeHandler.setFakeResult((short) 11); 308579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson assertEquals(11, proxy.getShort()); 309579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson fakeHandler.setFakeResult(12f); 310b8a5896885d4da2b798888b688a46df1adbf5b89Paul Duffin assertEquals(12f, proxy.getFloat(), DELTA_FLOAT); 311579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson fakeHandler.setFakeResult(13.0); 312b8a5896885d4da2b798888b688a46df1adbf5b89Paul Duffin assertEquals(13.0, proxy.getDouble(), DELTA_FLOAT); 313579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson fakeHandler.setFakeResult('z'); 314579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson assertEquals('z', proxy.getChar()); 3151af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson fakeHandler.setFakeResult(new int[] { -1, -2 }); 3161af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson assertEquals("[-1, -2]", Arrays.toString(proxy.getIntArray())); 3171af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson fakeHandler.setFakeResult(new String[] { "x", "y" }); 3181af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson assertEquals("[x, y]", Arrays.toString(proxy.getStringArray())); 319579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 320579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 3211af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson public static class PassThroughAllTypes { 322579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public boolean getBoolean(boolean input) { return input; } 323579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public int getInt(int input) { return input; } 324579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public byte getByte(byte input) { return input; } 325579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public long getLong(long input) { return input; } 326579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public short getShort(short input) { return input; } 327579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public float getFloat(float input) { return input; } 328579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public double getDouble(double input) { return input; } 329579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public char getChar(char input) { return input; } 330579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public String getString(String input) { return input; } 331579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public Object getObject(Object input) { return input; } 332579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public void getNothing() {} 333579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 334579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 335579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public static class InvokeSuperHandler implements InvocationHandler { 336579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { 337579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return ProxyBuilder.callSuper(proxy, method, args); 338579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 339579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 340579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 341b8a5896885d4da2b798888b688a46df1adbf5b89Paul Duffin @Test 3421af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson public void testPassThroughWorksForAllTypes() throws Exception { 3431af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson PassThroughAllTypes proxy = proxyFor(PassThroughAllTypes.class) 344579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson .handler(new InvokeSuperHandler()) 345579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson .build(); 346579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson assertEquals(false, proxy.getBoolean(false)); 347579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson assertEquals(true, proxy.getBoolean(true)); 348579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson assertEquals(0, proxy.getInt(0)); 349579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson assertEquals(1, proxy.getInt(1)); 350579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson assertEquals((byte) 2, proxy.getByte((byte) 2)); 351579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson assertEquals((byte) 3, proxy.getByte((byte) 3)); 352579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson assertEquals(4L, proxy.getLong(4L)); 353579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson assertEquals(5L, proxy.getLong(5L)); 354579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson assertEquals((short) 6, proxy.getShort((short) 6)); 355579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson assertEquals((short) 7, proxy.getShort((short) 7)); 356b8a5896885d4da2b798888b688a46df1adbf5b89Paul Duffin assertEquals(8f, proxy.getFloat(8f), DELTA_FLOAT); 357b8a5896885d4da2b798888b688a46df1adbf5b89Paul Duffin assertEquals(9f, proxy.getFloat(9f), DELTA_FLOAT); 358b8a5896885d4da2b798888b688a46df1adbf5b89Paul Duffin assertEquals(10.0, proxy.getDouble(10.0), DELTA_DOUBLE); 359b8a5896885d4da2b798888b688a46df1adbf5b89Paul Duffin assertEquals(11.0, proxy.getDouble(11.0), DELTA_DOUBLE); 360579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson assertEquals('a', proxy.getChar('a')); 361579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson assertEquals('b', proxy.getChar('b')); 362579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson assertEquals("asdf", proxy.getString("asdf")); 363579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson assertEquals("qwer", proxy.getString("qwer")); 364579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson assertEquals(null, proxy.getString(null)); 365579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson Object a = new Object(); 366579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson assertEquals(a, proxy.getObject(a)); 367579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson assertEquals(null, proxy.getObject(null)); 368579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson proxy.getNothing(); 369579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 370579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 3711af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson public static class ExtendsAllReturnTypes extends AllReturnTypes { 372579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public int example() { return 0; } 373579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 374579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 375b8a5896885d4da2b798888b688a46df1adbf5b89Paul Duffin @Test 376579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public void testProxyWorksForSuperclassMethodsAlso() throws Throwable { 3771af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson ExtendsAllReturnTypes proxy = proxyFor(ExtendsAllReturnTypes.class).build(); 378579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson fakeHandler.setFakeResult(99); 379579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson assertEquals(99, proxy.example()); 380579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson assertEquals(99, proxy.getInt()); 381579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson assertEquals(99, proxy.hashCode()); 382579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 383579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 384579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public static class HasOddParams { 385579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public long method(int first, Integer second) { 386579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson throw new AssertionFailedError(); 387579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 388579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 389579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 390b8a5896885d4da2b798888b688a46df1adbf5b89Paul Duffin @Test 391579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public void testMixingBoxedAndUnboxedParams() throws Throwable { 392579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson HasOddParams proxy = proxyFor(HasOddParams.class).build(); 393579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson fakeHandler.setFakeResult(99L); 394579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson assertEquals(99L, proxy.method(1, Integer.valueOf(2))); 395579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 396579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 397579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public static class SingleInt { 398579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public String getString(int value) { 399579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson throw new AssertionFailedError(); 400579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 401579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 402579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 403b8a5896885d4da2b798888b688a46df1adbf5b89Paul Duffin @Test 404579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public void testSinglePrimitiveParameter() throws Throwable { 405579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson InvocationHandler handler = new InvocationHandler() { 406579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { 407579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return "asdf" + ((Integer) args[0]).intValue(); 408579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 409579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson }; 410579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson assertEquals("asdf1", proxyFor(SingleInt.class).handler(handler).build().getString(1)); 411579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 412579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 413579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public static class TwoConstructors { 414579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson private final String string; 415579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 416579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public TwoConstructors() { 417579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson string = "no-arg"; 418579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 419579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 420579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public TwoConstructors(boolean unused) { 421579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson string = "one-arg"; 422579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 423579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 424579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 425b8a5896885d4da2b798888b688a46df1adbf5b89Paul Duffin @Test 426579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public void testNoConstructorArguments_CallsNoArgConstructor() throws Throwable { 427579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson TwoConstructors twoConstructors = proxyFor(TwoConstructors.class).build(); 428579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson assertEquals("no-arg", twoConstructors.string); 429579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 430579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 431b8a5896885d4da2b798888b688a46df1adbf5b89Paul Duffin @Test 432579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public void testWithoutInvocationHandler_ThrowsIllegalArgumentException() throws Throwable { 433579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson try { 434579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson ProxyBuilder.forClass(TwoConstructors.class) 435ab220f004db90fa94ef9349ca1adde5f89012e8dJesse Wilson .dexCache(DexMakerTest.getDataDirectory()) 436579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson .build(); 437579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson fail(); 438579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } catch (IllegalArgumentException expected) {} 439579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 440579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 441579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public static class HardToConstructCorrectly { 442579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public HardToConstructCorrectly() { fail(); } 443579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public HardToConstructCorrectly(Runnable ignored) { fail(); } 444579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public HardToConstructCorrectly(Exception ignored) { fail(); } 445579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public HardToConstructCorrectly(Boolean ignored) { /* safe */ } 446579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public HardToConstructCorrectly(Integer ignored) { fail(); } 447579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 448579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 449b8a5896885d4da2b798888b688a46df1adbf5b89Paul Duffin @Test 450579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public void testHardToConstruct_WorksIfYouSpecifyTheConstructorCorrectly() throws Throwable { 451579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson proxyFor(HardToConstructCorrectly.class) 452579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson .constructorArgTypes(Boolean.class) 453579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson .constructorArgValues(true) 454579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson .build(); 455579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 456579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 457b8a5896885d4da2b798888b688a46df1adbf5b89Paul Duffin @Test 458579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public void testHardToConstruct_EvenWorksWhenArgsAreAmbiguous() throws Throwable { 459579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson proxyFor(HardToConstructCorrectly.class) 460579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson .constructorArgTypes(Boolean.class) 461579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson .constructorArgValues(new Object[] { null }) 462579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson .build(); 463579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 464579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 465b8a5896885d4da2b798888b688a46df1adbf5b89Paul Duffin @Test(expected = IllegalArgumentException.class) 466579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public void testHardToConstruct_DoesNotInferTypesFromValues() throws Throwable { 467b8a5896885d4da2b798888b688a46df1adbf5b89Paul Duffin proxyFor(HardToConstructCorrectly.class) 468b8a5896885d4da2b798888b688a46df1adbf5b89Paul Duffin .constructorArgValues(true) 469b8a5896885d4da2b798888b688a46df1adbf5b89Paul Duffin .build(); 470579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 471579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 472b8a5896885d4da2b798888b688a46df1adbf5b89Paul Duffin @Test 473579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public void testDefaultProxyHasSuperMethodToAccessOriginal() throws Exception { 474579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson Object objectProxy = proxyFor(Object.class).build(); 4751af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson assertNotNull(objectProxy.getClass().getMethod("super$hashCode$int")); 476579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 477579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 478579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public static class PrintsOddAndValue { 479579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public String method(int value) { 480579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return "odd " + value; 481579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 482579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 483579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 484b8a5896885d4da2b798888b688a46df1adbf5b89Paul Duffin @Test 485579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public void testSometimesDelegateToSuper() throws Exception { 486579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson InvocationHandler delegatesOddValues = new InvocationHandler() { 487579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { 488579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (method.getName().equals("method")) { 489579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson int intValue = ((Integer) args[0]).intValue(); 490579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (intValue % 2 == 0) { 491579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return "even " + intValue; 492579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 493579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 494579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return ProxyBuilder.callSuper(proxy, method, args); 495579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 496579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson }; 497579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson PrintsOddAndValue proxy = proxyFor(PrintsOddAndValue.class) 498579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson .handler(delegatesOddValues) 499579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson .build(); 500579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson assertEquals("even 0", proxy.method(0)); 501579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson assertEquals("odd 1", proxy.method(1)); 502579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson assertEquals("even 2", proxy.method(2)); 503579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson assertEquals("odd 3", proxy.method(3)); 504579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 505b8a5896885d4da2b798888b688a46df1adbf5b89Paul Duffin 506b8a5896885d4da2b798888b688a46df1adbf5b89Paul Duffin @Test 5071af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson public void testCallSuperThrows() throws Exception { 5081af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson InvocationHandler handler = new InvocationHandler() { 5091af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson public Object invoke(Object o, Method method, Object[] objects) throws Throwable { 5101af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson return ProxyBuilder.callSuper(o, method, objects); 5111af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson } 5121af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson }; 5131af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson 5141af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson FooThrows fooThrows = proxyFor(FooThrows.class) 5151af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson .handler(handler) 5161af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson .build(); 5171af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson 5181af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson try { 5191af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson fooThrows.foo(); 5201af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson fail(); 5211af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson } catch (IllegalStateException expected) { 5221af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson assertEquals("boom!", expected.getMessage()); 5231af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson } 5241af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson } 525b8a5896885d4da2b798888b688a46df1adbf5b89Paul Duffin 5261af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson public static class FooThrows { 5271af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson public void foo() { 5281af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson throw new IllegalStateException("boom!"); 5291af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson } 5301af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson } 531579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 532579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public static class DoubleReturn { 533579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public double getValue() { 534579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return 2.0; 535579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 536579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 537579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 538b8a5896885d4da2b798888b688a46df1adbf5b89Paul Duffin @Test 539579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public void testUnboxedResult() throws Exception { 540579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson fakeHandler.fakeResult = 2.0; 541b8a5896885d4da2b798888b688a46df1adbf5b89Paul Duffin assertEquals(2.0, proxyFor(DoubleReturn.class).build().getValue(), DELTA_DOUBLE); 542579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 543579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 544b8a5896885d4da2b798888b688a46df1adbf5b89Paul Duffin public static void staticMethod() {} 545579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 546b8a5896885d4da2b798888b688a46df1adbf5b89Paul Duffin @Test 547579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public void testDoesNotOverrideStaticMethods() throws Exception { 548579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson // Method should exist on this test class itself. 549579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson ProxyBuilderTest.class.getDeclaredMethod("staticMethod"); 550579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson // Method should not exist on the subclass. 551579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson try { 552579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson proxyFor(ProxyBuilderTest.class).build().getClass().getDeclaredMethod("staticMethod"); 553579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson fail(); 554579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } catch (NoSuchMethodException expected) {} 555579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 556579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 557b8a5896885d4da2b798888b688a46df1adbf5b89Paul Duffin @Test(expected = IOException.class) 558579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public void testIllegalCacheDirectory() throws Exception { 559b8a5896885d4da2b798888b688a46df1adbf5b89Paul Duffin proxyFor(ProxyForIllegalCacheDirectory.class) 560b8a5896885d4da2b798888b688a46df1adbf5b89Paul Duffin .dexCache(new File("/poop/")) 561b8a5896885d4da2b798888b688a46df1adbf5b89Paul Duffin .build(); 562579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 563579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 564b8a5896885d4da2b798888b688a46df1adbf5b89Paul Duffin public static class ProxyForIllegalCacheDirectory {} 5652e28a229885e9ba7fec9ef42cbf30fdcf8a0c939Jesse Wilson 566b8a5896885d4da2b798888b688a46df1adbf5b89Paul Duffin @Test(expected = IllegalArgumentException.class) 567579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public void testInvalidConstructorSpecification() throws Exception { 568b8a5896885d4da2b798888b688a46df1adbf5b89Paul Duffin proxyFor(Object.class) 569b8a5896885d4da2b798888b688a46df1adbf5b89Paul Duffin .constructorArgTypes(String.class, Boolean.class) 570b8a5896885d4da2b798888b688a46df1adbf5b89Paul Duffin .constructorArgValues("asdf", true) 571b8a5896885d4da2b798888b688a46df1adbf5b89Paul Duffin .build(); 572579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 573579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 574579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public static abstract class AbstractClass { 575579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public abstract Object getValue(); 576579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 577579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 578b8a5896885d4da2b798888b688a46df1adbf5b89Paul Duffin @Test 579579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public void testAbstractClassBehaviour() throws Exception { 580579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson assertEquals("fake result", proxyFor(AbstractClass.class).build().getValue()); 581579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 582579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 583579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public static class CtorHasDeclaredException { 584579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public CtorHasDeclaredException() throws IOException { 585579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson throw new IOException(); 586579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 587579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 588579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 589579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public static class CtorHasRuntimeException { 590579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public CtorHasRuntimeException() { 591579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson throw new RuntimeException("my message"); 592579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 593579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 594579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 595579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public static class CtorHasError { 596579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public CtorHasError() { 597579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson throw new Error("my message again"); 598579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 599579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 600579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 601b8a5896885d4da2b798888b688a46df1adbf5b89Paul Duffin @Test 602579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public void testParentConstructorThrowsDeclaredException() throws Exception { 603579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson try { 604579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson proxyFor(CtorHasDeclaredException.class).build(); 605579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson fail(); 606579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } catch (UndeclaredThrowableException expected) { 607579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson assertTrue(expected.getCause() instanceof IOException); 608579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 609579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson try { 610579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson proxyFor(CtorHasRuntimeException.class).build(); 611579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson fail(); 612579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } catch (RuntimeException expected) { 613579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson assertEquals("my message", expected.getMessage()); 614579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 615579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson try { 616579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson proxyFor(CtorHasError.class).build(); 617579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson fail(); 618579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } catch (Error expected) { 619579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson assertEquals("my message again", expected.getMessage()); 620579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 621579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 622579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 623b8a5896885d4da2b798888b688a46df1adbf5b89Paul Duffin @Test 624579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public void testGetInvocationHandler_NormalOperation() throws Exception { 625579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson Object proxy = proxyFor(Object.class).build(); 626579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson assertSame(fakeHandler, ProxyBuilder.getInvocationHandler(proxy)); 627579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 628579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 629b8a5896885d4da2b798888b688a46df1adbf5b89Paul Duffin @Test(expected = IllegalArgumentException.class) 630579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public void testGetInvocationHandler_NotAProxy() { 631b8a5896885d4da2b798888b688a46df1adbf5b89Paul Duffin ProxyBuilder.getInvocationHandler(new Object()); 632579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 633579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 634579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public static class ReturnsObject { 635579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public Object getValue() { 636579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return new Object(); 637579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 638579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 639579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 640579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public static class ReturnsString extends ReturnsObject { 641579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson @Override 642579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public String getValue() { 643579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return "a string"; 644579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 645579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 646579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 647b8a5896885d4da2b798888b688a46df1adbf5b89Paul Duffin @Test 648579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public void testCovariantReturnTypes_NormalBehaviour() throws Exception { 649579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson String expected = "some string"; 650579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson fakeHandler.setFakeResult(expected); 651579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson assertSame(expected, proxyFor(ReturnsObject.class).build().getValue()); 652579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson assertSame(expected, proxyFor(ReturnsString.class).build().getValue()); 653579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 654579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 655b8a5896885d4da2b798888b688a46df1adbf5b89Paul Duffin @Test 656579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public void testCovariantReturnTypes_WrongReturnType() throws Exception { 657579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson try { 658579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson fakeHandler.setFakeResult(new Object()); 659579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson proxyFor(ReturnsString.class).build().getValue(); 660579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson fail(); 661579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } catch (ClassCastException expected) {} 662579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 663579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 664b8a5896885d4da2b798888b688a46df1adbf5b89Paul Duffin @Test 6652e28a229885e9ba7fec9ef42cbf30fdcf8a0c939Jesse Wilson public void testCaching() throws Exception { 66631c34ef392ca364c845f71b4cc8f84de2739426bJesse Wilson SimpleClass a = proxyFor(SimpleClass.class).build(); 66731c34ef392ca364c845f71b4cc8f84de2739426bJesse Wilson SimpleClass b = proxyFor(SimpleClass.class).build(); 66831c34ef392ca364c845f71b4cc8f84de2739426bJesse Wilson assertSame(a.getClass(), b.getClass()); 6692e28a229885e9ba7fec9ef42cbf30fdcf8a0c939Jesse Wilson } 6702e28a229885e9ba7fec9ef42cbf30fdcf8a0c939Jesse Wilson 671b8a5896885d4da2b798888b688a46df1adbf5b89Paul Duffin @Test 6722e28a229885e9ba7fec9ef42cbf30fdcf8a0c939Jesse Wilson public void testCachingWithMultipleConstructors() throws Exception { 67331c34ef392ca364c845f71b4cc8f84de2739426bJesse Wilson HasMultipleConstructors a = ProxyBuilder.forClass(HasMultipleConstructors.class) 67431c34ef392ca364c845f71b4cc8f84de2739426bJesse Wilson .constructorArgTypes() 67531c34ef392ca364c845f71b4cc8f84de2739426bJesse Wilson .constructorArgValues() 67631c34ef392ca364c845f71b4cc8f84de2739426bJesse Wilson .handler(fakeHandler) 67731c34ef392ca364c845f71b4cc8f84de2739426bJesse Wilson .dexCache(DexMakerTest.getDataDirectory()).build(); 67831c34ef392ca364c845f71b4cc8f84de2739426bJesse Wilson assertEquals("no args", a.calledConstructor); 67931c34ef392ca364c845f71b4cc8f84de2739426bJesse Wilson HasMultipleConstructors b = ProxyBuilder.forClass(HasMultipleConstructors.class) 68031c34ef392ca364c845f71b4cc8f84de2739426bJesse Wilson .constructorArgTypes(int.class) 68131c34ef392ca364c845f71b4cc8f84de2739426bJesse Wilson .constructorArgValues(2) 68231c34ef392ca364c845f71b4cc8f84de2739426bJesse Wilson .handler(fakeHandler) 68331c34ef392ca364c845f71b4cc8f84de2739426bJesse Wilson .dexCache(DexMakerTest.getDataDirectory()).build(); 68431c34ef392ca364c845f71b4cc8f84de2739426bJesse Wilson assertEquals("int 2", b.calledConstructor); 68531c34ef392ca364c845f71b4cc8f84de2739426bJesse Wilson assertEquals(a.getClass(), b.getClass()); 68631c34ef392ca364c845f71b4cc8f84de2739426bJesse Wilson 68731c34ef392ca364c845f71b4cc8f84de2739426bJesse Wilson HasMultipleConstructors c = ProxyBuilder.forClass(HasMultipleConstructors.class) 68831c34ef392ca364c845f71b4cc8f84de2739426bJesse Wilson .constructorArgTypes(Integer.class) 68931c34ef392ca364c845f71b4cc8f84de2739426bJesse Wilson .constructorArgValues(3) 69031c34ef392ca364c845f71b4cc8f84de2739426bJesse Wilson .handler(fakeHandler) 69131c34ef392ca364c845f71b4cc8f84de2739426bJesse Wilson .dexCache(DexMakerTest.getDataDirectory()).build(); 69231c34ef392ca364c845f71b4cc8f84de2739426bJesse Wilson assertEquals("Integer 3", c.calledConstructor); 69331c34ef392ca364c845f71b4cc8f84de2739426bJesse Wilson assertEquals(a.getClass(), c.getClass()); 6942e28a229885e9ba7fec9ef42cbf30fdcf8a0c939Jesse Wilson } 6952e28a229885e9ba7fec9ef42cbf30fdcf8a0c939Jesse Wilson 69631c34ef392ca364c845f71b4cc8f84de2739426bJesse Wilson public static class HasMultipleConstructors { 69731c34ef392ca364c845f71b4cc8f84de2739426bJesse Wilson private final String calledConstructor; 69831c34ef392ca364c845f71b4cc8f84de2739426bJesse Wilson public HasMultipleConstructors() { 69931c34ef392ca364c845f71b4cc8f84de2739426bJesse Wilson calledConstructor = "no args"; 70031c34ef392ca364c845f71b4cc8f84de2739426bJesse Wilson } 70131c34ef392ca364c845f71b4cc8f84de2739426bJesse Wilson public HasMultipleConstructors(int b) { 70231c34ef392ca364c845f71b4cc8f84de2739426bJesse Wilson calledConstructor = "int " + b; 70331c34ef392ca364c845f71b4cc8f84de2739426bJesse Wilson } 70431c34ef392ca364c845f71b4cc8f84de2739426bJesse Wilson public HasMultipleConstructors(Integer c) { 70531c34ef392ca364c845f71b4cc8f84de2739426bJesse Wilson calledConstructor = "Integer " + c; 70631c34ef392ca364c845f71b4cc8f84de2739426bJesse Wilson } 70731c34ef392ca364c845f71b4cc8f84de2739426bJesse Wilson } 70831c34ef392ca364c845f71b4cc8f84de2739426bJesse Wilson 709b8a5896885d4da2b798888b688a46df1adbf5b89Paul Duffin @Test 71031c34ef392ca364c845f71b4cc8f84de2739426bJesse Wilson public void testClassNotCachedWithDifferentParentClassLoaders() throws Exception { 711b4fdb175545f178c642194bc43a3fad31af3f0e9Jesse Wilson ClassLoader classLoaderA = newPathClassLoader(); 71231c34ef392ca364c845f71b4cc8f84de2739426bJesse Wilson SimpleClass a = proxyFor(SimpleClass.class) 71331c34ef392ca364c845f71b4cc8f84de2739426bJesse Wilson .parentClassLoader(classLoaderA) 71431c34ef392ca364c845f71b4cc8f84de2739426bJesse Wilson .build(); 71531c34ef392ca364c845f71b4cc8f84de2739426bJesse Wilson assertEquals(classLoaderA, a.getClass().getClassLoader().getParent()); 71631c34ef392ca364c845f71b4cc8f84de2739426bJesse Wilson 717b4fdb175545f178c642194bc43a3fad31af3f0e9Jesse Wilson ClassLoader classLoaderB = newPathClassLoader(); 71831c34ef392ca364c845f71b4cc8f84de2739426bJesse Wilson SimpleClass b = proxyFor(SimpleClass.class) 71931c34ef392ca364c845f71b4cc8f84de2739426bJesse Wilson .parentClassLoader(classLoaderB) 72031c34ef392ca364c845f71b4cc8f84de2739426bJesse Wilson .build(); 72131c34ef392ca364c845f71b4cc8f84de2739426bJesse Wilson assertEquals(classLoaderB, b.getClass().getClassLoader().getParent()); 72231c34ef392ca364c845f71b4cc8f84de2739426bJesse Wilson 72331c34ef392ca364c845f71b4cc8f84de2739426bJesse Wilson assertTrue(a.getClass() != b.getClass()); 724579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 725b8a5896885d4da2b798888b688a46df1adbf5b89Paul Duffin 726b8a5896885d4da2b798888b688a46df1adbf5b89Paul Duffin @Test 7271af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson public void testAbstractClassWithUndeclaredInterfaceMethod() throws Throwable { 7281af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson DeclaresInterface declaresInterface = proxyFor(DeclaresInterface.class) 7291af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson .build(); 7301af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson assertEquals("fake result", declaresInterface.call()); 7311af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson try { 7321af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson ProxyBuilder.callSuper(declaresInterface, Callable.class.getMethod("call")); 7331af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson fail(); 734b8a5896885d4da2b798888b688a46df1adbf5b89Paul Duffin } catch (IncompatibleClassChangeError expected) { 7351af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson } 7361af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson } 7371af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson 738b8a5896885d4da2b798888b688a46df1adbf5b89Paul Duffin public static abstract class DeclaresInterface implements Callable<String> {} 739b8a5896885d4da2b798888b688a46df1adbf5b89Paul Duffin 740b8a5896885d4da2b798888b688a46df1adbf5b89Paul Duffin @Test 7411af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson public void testImplementingInterfaces() throws Throwable { 7421af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson SimpleClass simpleClass = proxyFor(SimpleClass.class) 7431af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson .implementing(Callable.class) 7441af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson .implementing(Comparable.class) 7451af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson .build(); 7461af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson assertEquals("fake result", simpleClass.simpleMethod()); 7471af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson 7481af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson Callable<?> asCallable = (Callable<?>) simpleClass; 7491af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson assertEquals("fake result", asCallable.call()); 7501af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson 7511af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson Comparable<?> asComparable = (Comparable<?>) simpleClass; 7521af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson fakeHandler.fakeResult = 3; 7531af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson assertEquals(3, asComparable.compareTo(null)); 7541af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson } 7551af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson 756b8a5896885d4da2b798888b688a46df1adbf5b89Paul Duffin @Test 7571af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson public void testCallSuperWithInterfaceMethod() throws Throwable { 7581af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson SimpleClass simpleClass = proxyFor(SimpleClass.class) 7591af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson .implementing(Callable.class) 7601af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson .build(); 7611af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson try { 7621af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson ProxyBuilder.callSuper(simpleClass, Callable.class.getMethod("call")); 7631af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson fail(); 7641af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson } catch (AbstractMethodError expected) { 7651af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson } catch (NoSuchMethodError expected) { 7661af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson } 7671af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson } 768579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 769b8a5896885d4da2b798888b688a46df1adbf5b89Paul Duffin @Test 7701af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson public void testImplementInterfaceCallingThroughConcreteClass() throws Throwable { 7711af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson InvocationHandler invocationHandler = new InvocationHandler() { 7721af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson public Object invoke(Object o, Method method, Object[] objects) throws Throwable { 7731af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson assertEquals("a", ProxyBuilder.callSuper(o, method, objects)); 7741af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson return "b"; 7751af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson } 7761af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson }; 7771af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson ImplementsCallable proxy = proxyFor(ImplementsCallable.class) 7781af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson .implementing(Callable.class) 7791af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson .handler(invocationHandler) 7801af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson .build(); 7811af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson assertEquals("b", proxy.call()); 7821af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson assertEquals("a", ProxyBuilder.callSuper( 7831af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson proxy, ImplementsCallable.class.getMethod("call"))); 7841af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson } 785b8a5896885d4da2b798888b688a46df1adbf5b89Paul Duffin 7861af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson /** 7871af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson * This test is a bit unintuitive because it exercises the synthetic methods 7881af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson * that support covariant return types. Calling 'Object call()' on the 7891af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson * interface bridges to 'String call()', and so the super method appears to 7901af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson * also be proxied. 7911af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson */ 792b8a5896885d4da2b798888b688a46df1adbf5b89Paul Duffin @Test 7931af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson public void testImplementInterfaceCallingThroughInterface() throws Throwable { 7941af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson final AtomicInteger count = new AtomicInteger(); 7951af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson 7961af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson InvocationHandler invocationHandler = new InvocationHandler() { 7971af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson public Object invoke(Object o, Method method, Object[] objects) throws Throwable { 7981af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson count.incrementAndGet(); 7991af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson return ProxyBuilder.callSuper(o, method, objects); 8001af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson } 8011af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson }; 8021af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson 8031af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson Callable<?> proxy = proxyFor(ImplementsCallable.class) 8041af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson .implementing(Callable.class) 8051af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson .handler(invocationHandler) 8061af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson .build(); 8071af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson 8081af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson // the invocation handler is called twice! 8091af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson assertEquals("a", proxy.call()); 8101af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson assertEquals(2, count.get()); 8111af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson 8121af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson // the invocation handler is called, even though this is a callSuper() call! 8131af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson assertEquals("a", ProxyBuilder.callSuper(proxy, Callable.class.getMethod("call"))); 8141af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson assertEquals(3, count.get()); 8151af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson } 816b8a5896885d4da2b798888b688a46df1adbf5b89Paul Duffin 8171af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson public static class ImplementsCallable implements Callable<String> { 8181af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson public String call() throws Exception { 8191af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson return "a"; 8201af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson } 8211af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson } 8221af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson 8231af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson /** 8241af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson * This test shows that our generated proxies follow the bytecode convention 8251af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson * where methods can have the same name but unrelated return types. This is 8261af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson * different from javac's convention where return types must be assignable 8271af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson * in one direction or the other. 8281af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson */ 829b8a5896885d4da2b798888b688a46df1adbf5b89Paul Duffin @Test 8301af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson public void testInterfacesSameNamesDifferentReturnTypes() throws Throwable { 8311af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson InvocationHandler handler = new InvocationHandler() { 8321af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson public Object invoke(Object o, Method method, Object[] objects) throws Throwable { 8331af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson if (method.getReturnType() == void.class) { 8341af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson return null; 8351af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson } else if (method.getReturnType() == String.class) { 8361af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson return "X"; 8371af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson } else if (method.getReturnType() == int.class) { 8381af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson return 3; 8391af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson } else { 8401af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson throw new AssertionFailedError(); 8411af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson } 8421af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson } 8431af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson }; 844b8a5896885d4da2b798888b688a46df1adbf5b89Paul Duffin 8451af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson Object o = proxyFor(Object.class) 8461af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson .implementing(FooReturnsVoid.class, FooReturnsString.class, FooReturnsInt.class) 8471af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson .handler(handler) 8481af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson .build(); 849b8a5896885d4da2b798888b688a46df1adbf5b89Paul Duffin 8501af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson FooReturnsVoid a = (FooReturnsVoid) o; 8511af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson a.foo(); 852b8a5896885d4da2b798888b688a46df1adbf5b89Paul Duffin 8531af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson FooReturnsString b = (FooReturnsString) o; 8541af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson assertEquals("X", b.foo()); 855b8a5896885d4da2b798888b688a46df1adbf5b89Paul Duffin 8561af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson FooReturnsInt c = (FooReturnsInt) o; 8571af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson assertEquals(3, c.foo()); 8581af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson } 859b8a5896885d4da2b798888b688a46df1adbf5b89Paul Duffin 860b8a5896885d4da2b798888b688a46df1adbf5b89Paul Duffin @Test 8611af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson public void testInterfacesSameNamesSameReturnType() throws Throwable { 8621af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson Object o = proxyFor(Object.class) 8631af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson .implementing(FooReturnsInt.class, FooReturnsInt2.class) 8641af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson .build(); 865b8a5896885d4da2b798888b688a46df1adbf5b89Paul Duffin 8661af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson fakeHandler.setFakeResult(3); 8671af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson 8681af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson FooReturnsInt a = (FooReturnsInt) o; 8691af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson assertEquals(3, a.foo()); 8701af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson 8711af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson FooReturnsInt2 b = (FooReturnsInt2) o; 8721af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson assertEquals(3, b.foo()); 8731af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson } 874b8a5896885d4da2b798888b688a46df1adbf5b89Paul Duffin 8751af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson public interface FooReturnsVoid { 8761af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson void foo(); 8771af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson } 8781af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson 8791af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson public interface FooReturnsString { 8801af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson String foo(); 8811af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson } 8821af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson 8831af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson public interface FooReturnsInt { 8841af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson int foo(); 8851af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson } 886b8a5896885d4da2b798888b688a46df1adbf5b89Paul Duffin 8871af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson public interface FooReturnsInt2 { 8881af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson int foo(); 8891af1da6af1f59f0bc1f9d048f31279ce5e614c3dJesse Wilson } 890b8a5896885d4da2b798888b688a46df1adbf5b89Paul Duffin 891b4fdb175545f178c642194bc43a3fad31af3f0e9Jesse Wilson private ClassLoader newPathClassLoader() throws Exception { 892b4fdb175545f178c642194bc43a3fad31af3f0e9Jesse Wilson return (ClassLoader) Class.forName("dalvik.system.PathClassLoader") 893b4fdb175545f178c642194bc43a3fad31af3f0e9Jesse Wilson .getConstructor(String.class, ClassLoader.class) 894b4fdb175545f178c642194bc43a3fad31af3f0e9Jesse Wilson .newInstance("", getClass().getClassLoader()); 895b4fdb175545f178c642194bc43a3fad31af3f0e9Jesse Wilson 896b4fdb175545f178c642194bc43a3fad31af3f0e9Jesse Wilson } 897b4fdb175545f178c642194bc43a3fad31af3f0e9Jesse Wilson 898b8a5896885d4da2b798888b688a46df1adbf5b89Paul Duffin @Test 899579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public void testSubclassOfRandom() throws Exception { 900579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson proxyFor(Random.class) 901579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson .handler(new InvokeSuperHandler()) 902579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson .build(); 903579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 904579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 90595689a700bfea5e2d78380a442fc2903cc40a3f2Mark Brophy public static class FinalToString { 906b8a5896885d4da2b798888b688a46df1adbf5b89Paul Duffin @Override 907b8a5896885d4da2b798888b688a46df1adbf5b89Paul Duffin public final String toString() { 90895689a700bfea5e2d78380a442fc2903cc40a3f2Mark Brophy return "no proxy"; 90995689a700bfea5e2d78380a442fc2903cc40a3f2Mark Brophy } 91095689a700bfea5e2d78380a442fc2903cc40a3f2Mark Brophy } 91195689a700bfea5e2d78380a442fc2903cc40a3f2Mark Brophy 91295689a700bfea5e2d78380a442fc2903cc40a3f2Mark Brophy // https://code.google.com/p/dexmaker/issues/detail?id=12 913b8a5896885d4da2b798888b688a46df1adbf5b89Paul Duffin @Test 91495689a700bfea5e2d78380a442fc2903cc40a3f2Mark Brophy public void testFinalToString() throws Throwable { 91595689a700bfea5e2d78380a442fc2903cc40a3f2Mark Brophy assertEquals("no proxy", proxyFor(FinalToString.class).build().toString()); 91695689a700bfea5e2d78380a442fc2903cc40a3f2Mark Brophy } 91795689a700bfea5e2d78380a442fc2903cc40a3f2Mark Brophy 918ab38abdf175554643d40b889d58d283d358218c3Samuel Tan public static class FinalInterfaceImpl implements FooReturnsString { 919b8a5896885d4da2b798888b688a46df1adbf5b89Paul Duffin @Override 920b8a5896885d4da2b798888b688a46df1adbf5b89Paul Duffin public final String foo() { 921ab38abdf175554643d40b889d58d283d358218c3Samuel Tan return "no proxy"; 922ab38abdf175554643d40b889d58d283d358218c3Samuel Tan } 923ab38abdf175554643d40b889d58d283d358218c3Samuel Tan } 924ab38abdf175554643d40b889d58d283d358218c3Samuel Tan 925ab38abdf175554643d40b889d58d283d358218c3Samuel Tan public static class ExtenstionOfFinalInterfaceImpl extends FinalInterfaceImpl 926ab38abdf175554643d40b889d58d283d358218c3Samuel Tan implements FooReturnsString { 927ab38abdf175554643d40b889d58d283d358218c3Samuel Tan } 928ab38abdf175554643d40b889d58d283d358218c3Samuel Tan 929b8a5896885d4da2b798888b688a46df1adbf5b89Paul Duffin @Test 930ab38abdf175554643d40b889d58d283d358218c3Samuel Tan public void testFinalInterfaceImpl() throws Throwable { 931ab38abdf175554643d40b889d58d283d358218c3Samuel Tan assertEquals("no proxy", proxyFor(ExtenstionOfFinalInterfaceImpl.class).build().foo()); 932ab38abdf175554643d40b889d58d283d358218c3Samuel Tan } 933ab38abdf175554643d40b889d58d283d358218c3Samuel Tan 934cb6e5223823f9f9ad04da51c63548659062a4f43Paul Duffin // https://code.google.com/p/dexmaker/issues/detail?id=9 935cb6e5223823f9f9ad04da51c63548659062a4f43Paul Duffin public interface DeclaresMethodLate { 936cb6e5223823f9f9ad04da51c63548659062a4f43Paul Duffin void thisIsTheMethod(); 937cb6e5223823f9f9ad04da51c63548659062a4f43Paul Duffin } 938cb6e5223823f9f9ad04da51c63548659062a4f43Paul Duffin 939cb6e5223823f9f9ad04da51c63548659062a4f43Paul Duffin public static class MakesMethodFinalEarly { 940cb6e5223823f9f9ad04da51c63548659062a4f43Paul Duffin public final void thisIsTheMethod() {} 941cb6e5223823f9f9ad04da51c63548659062a4f43Paul Duffin } 942cb6e5223823f9f9ad04da51c63548659062a4f43Paul Duffin 943cb6e5223823f9f9ad04da51c63548659062a4f43Paul Duffin public static class YouDoNotChooseYourFamily 944cb6e5223823f9f9ad04da51c63548659062a4f43Paul Duffin extends MakesMethodFinalEarly implements DeclaresMethodLate {} 945cb6e5223823f9f9ad04da51c63548659062a4f43Paul Duffin 946b8a5896885d4da2b798888b688a46df1adbf5b89Paul Duffin @Test 947cb6e5223823f9f9ad04da51c63548659062a4f43Paul Duffin public void testInterfaceMethodMadeFinalBeforeActualInheritance() throws Exception { 948cb6e5223823f9f9ad04da51c63548659062a4f43Paul Duffin proxyFor(YouDoNotChooseYourFamily.class).build(); 949cb6e5223823f9f9ad04da51c63548659062a4f43Paul Duffin } 950cb6e5223823f9f9ad04da51c63548659062a4f43Paul Duffin 951309cc66e50aaac713a5c2c72e3ea6b236716b036Paul Duffin public interface ExtendsAnotherInterface extends FooReturnsString { 952309cc66e50aaac713a5c2c72e3ea6b236716b036Paul Duffin 953309cc66e50aaac713a5c2c72e3ea6b236716b036Paul Duffin } 954309cc66e50aaac713a5c2c72e3ea6b236716b036Paul Duffin 955309cc66e50aaac713a5c2c72e3ea6b236716b036Paul Duffin @Test 956309cc66e50aaac713a5c2c72e3ea6b236716b036Paul Duffin public void testExtraInterfaceExtendsInterface() throws Exception { 957309cc66e50aaac713a5c2c72e3ea6b236716b036Paul Duffin ExtendsAnotherInterface proxy = (ExtendsAnotherInterface) 958309cc66e50aaac713a5c2c72e3ea6b236716b036Paul Duffin proxyFor(SimpleClass.class) 959309cc66e50aaac713a5c2c72e3ea6b236716b036Paul Duffin .implementing(ExtendsAnotherInterface.class) 960309cc66e50aaac713a5c2c72e3ea6b236716b036Paul Duffin .build(); 961309cc66e50aaac713a5c2c72e3ea6b236716b036Paul Duffin fakeHandler.setFakeResult(ExtendsAnotherInterface.class.getName()); 962309cc66e50aaac713a5c2c72e3ea6b236716b036Paul Duffin assertEquals(ExtendsAnotherInterface.class.getName(), proxy.foo()); 963309cc66e50aaac713a5c2c72e3ea6b236716b036Paul Duffin } 964309cc66e50aaac713a5c2c72e3ea6b236716b036Paul Duffin 965579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** Simple helper to add the most common args for this test to the proxy builder. */ 966579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson private <T> ProxyBuilder<T> proxyFor(Class<T> clazz) throws Exception { 967579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return ProxyBuilder.forClass(clazz) 968579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson .handler(fakeHandler) 969ab220f004db90fa94ef9349ca1adde5f89012e8dJesse Wilson .dexCache(DexMakerTest.getDataDirectory()); 970579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 971579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 972579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson private static class FakeInvocationHandler implements InvocationHandler { 973579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson private Object fakeResult = "fake result"; 974579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 975579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { 976579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return fakeResult; 977579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 978579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 979579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public void setFakeResult(Object result) { 980579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson fakeResult = result; 981579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 982579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 983054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef 984054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef public static class TestOrderingClass { 985054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef public int returnsInt() { 986054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef return 0; 987054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef } 988054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef 989054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef public int returnsInt(int param1, int param2) { 990054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef return 1; 991054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef } 992054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef 993054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef public String returnsString() { 994054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef return "string"; 995054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef } 996054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef 997054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef public boolean returnsBoolean() { 998054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef return false; 999054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef } 1000054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef 1001054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef public double returnsDouble() { 1002054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef return 1.0; 1003054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef } 1004054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef 1005054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef public Object returnsObject() { 1006054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef return new Object(); 1007054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef } 1008054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef } 1009054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef 1010b8a5896885d4da2b798888b688a46df1adbf5b89Paul Duffin @Test 1011054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef @SuppressWarnings("unchecked") 1012054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef public void testMethodsGeneratedInDeterministicOrder() throws Exception { 1013054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef // Grab the static methods array from the original class. 1014054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef Method[] methods1 = getMethodsForProxyClass(TestOrderingClass.class); 1015054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef assertNotNull(methods1); 1016054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef 1017054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef // Clear ProxyBuilder's in-memory cache of classes. This will force 1018054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef // it to rebuild the class and reset the static methods field. 1019054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef Map<Class<?>, Class<?>> map = getGeneratedProxyClasses(); 1020054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef assertNotNull(map); 1021054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef map.clear(); 1022054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef 1023054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef // Grab the static methods array from the rebuilt class. 1024054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef Method[] methods2 = getMethodsForProxyClass(TestOrderingClass.class); 1025054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef assertNotNull(methods2); 1026054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef 1027054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef // Ensure that the two method arrays are equal. 1028054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef assertTrue(Arrays.equals(methods1, methods2)); 1029054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef } 1030054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef 1031b8a5896885d4da2b798888b688a46df1adbf5b89Paul Duffin @Test 1032054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef public void testOrderingClassWithDexMakerCaching() throws Exception { 1033054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef doTestOrderClassWithDexMakerCaching(); 1034054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef 1035054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef // Force ProxyBuilder to call DexMaker.generateAndLoad() 1036054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef getGeneratedProxyClasses().clear(); 1037054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef 1038054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef doTestOrderClassWithDexMakerCaching(); 1039054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef } 1040054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef 1041054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef private void doTestOrderClassWithDexMakerCaching() throws Exception { 1042054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef TestOrderingClass proxy = ProxyBuilder.forClass(TestOrderingClass.class) 1043054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef .handler(new InvokeSuperHandler()) 1044054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef .dexCache(DexMakerTest.getDataDirectory()) 1045054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef .build(); 1046054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef assertEquals(0, proxy.returnsInt()); 1047054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef assertEquals(1, proxy.returnsInt(1, 1)); 1048054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef assertEquals("string", proxy.returnsString()); 1049054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef assertFalse(proxy.returnsBoolean()); 1050b8a5896885d4da2b798888b688a46df1adbf5b89Paul Duffin assertEquals(1.0, proxy.returnsDouble(), DELTA_DOUBLE); 1051054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef assertNotNull(proxy.returnsObject()); 1052b8a5896885d4da2b798888b688a46df1adbf5b89Paul Duffin assertTrue(versionedDxDir.listFiles().length != 0); 1053054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef } 1054054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef 1055054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef // Returns static methods array from a proxy class. 1056054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef private Method[] getMethodsForProxyClass(Class<?> parentClass) throws Exception { 1057054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef Class<?> proxyClass = proxyFor(parentClass).buildProxyClass(); 1058054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef Method[] methods = null; 1059054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef for (Field f : proxyClass.getDeclaredFields()) { 1060054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef if (Method[].class.isAssignableFrom(f.getType())) { 1061054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef f.setAccessible(true); 1062054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef methods = (Method[]) f.get(null); 1063054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef break; 1064054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef } 1065054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef } 1066054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef 1067054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef return methods; 1068054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef } 1069054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef 1070054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef private Map<Class<?>, Class<?>> getGeneratedProxyClasses() throws Exception { 1071054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef Field mapField = ProxyBuilder.class 1072054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef .getDeclaredField("generatedProxyClasses"); 1073054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef mapField.setAccessible(true); 1074054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef return (Map<Class<?>, Class<?>>) mapField.get(null); 1075054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef } 1076054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef 1077054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef public static class ConcreteClassA implements FooReturnsInt { 1078054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef // from FooReturnsInt 1079054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef public int foo() { 1080054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef return 1; 1081054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef } 1082054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef 1083054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef // not from FooReturnsInt 1084054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef public String bar() { 1085054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef return "bar"; 1086054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef } 1087054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef } 1088054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef 1089054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef public static class ConcreteClassB implements FooReturnsInt { 1090054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef // from FooReturnsInt 1091054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef public int foo() { 1092054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef return 0; 1093054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef } 1094054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef 1095054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef // not from FooReturnsInt 1096054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef public String bar() { 1097054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef return "bahhr"; 1098054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef } 1099054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef } 1100054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef 1101b8a5896885d4da2b798888b688a46df1adbf5b89Paul Duffin @Test 1102054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef public void testTwoClassesWithIdenticalMethodSignatures_DexMakerCaching() throws Exception { 1103054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef ConcreteClassA proxyA = ProxyBuilder.forClass(ConcreteClassA.class) 1104054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef .handler(new InvokeSuperHandler()) 1105054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef .dexCache(DexMakerTest.getDataDirectory()) 1106054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef .build(); 1107054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef assertEquals(1, proxyA.foo()); 1108054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef assertEquals("bar", proxyA.bar()); 1109054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef assertEquals(2, versionedDxDir.listFiles().length); 1110054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef 1111054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef ConcreteClassB proxyB = ProxyBuilder.forClass(ConcreteClassB.class) 1112054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef .handler(new InvokeSuperHandler()) 1113054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef .dexCache(DexMakerTest.getDataDirectory()) 1114054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef .build(); 1115054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef assertEquals(0, proxyB.foo()); 1116054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef assertEquals("bahhr", proxyB.bar()); 1117054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef assertEquals(4, versionedDxDir.listFiles().length); 1118054604d4c95cb530bea955718d79dbe3dc0962cfAndrew Yousef } 1119579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson} 1120