ProxyBuilderTest.java revision 579d7739c53a2707ad711a2d2cae46d7d782f06
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 17579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilsonpackage com.google.dexmaker; 18579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 19579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilsonimport junit.framework.AssertionFailedError; 20579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilsonimport junit.framework.TestCase; 21579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 22579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilsonimport java.io.File; 23579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilsonimport java.io.IOException; 24579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilsonimport java.lang.reflect.InvocationHandler; 25579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilsonimport java.lang.reflect.Method; 26579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilsonimport java.lang.reflect.UndeclaredThrowableException; 27579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilsonimport java.util.Random; 28579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 29579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilsonpublic class ProxyBuilderTest extends TestCase { 30579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson private FakeInvocationHandler fakeHandler = new FakeInvocationHandler(); 31579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 32579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public static class SimpleClass { 33579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public String simpleMethod() { 34579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson throw new AssertionFailedError(); 35579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 36579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 37579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 38579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public void testExampleOperation() throws Throwable { 39579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson fakeHandler.setFakeResult("expected"); 40579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson SimpleClass proxy = proxyFor(SimpleClass.class).build(); 41579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson assertEquals("expected", proxy.simpleMethod()); 42579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 43579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 44579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public static class ConstructorTakesArguments { 45579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson private final String argument; 46579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 47579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public ConstructorTakesArguments(String arg) { 48579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson argument = arg; 49579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 50579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 51579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public String method() { 52579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson throw new AssertionFailedError(); 53579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 54579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 55579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 56579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public void testConstruction_SucceedsIfCorrectArgumentsProvided() throws Throwable { 57579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson ConstructorTakesArguments proxy = proxyFor(ConstructorTakesArguments.class) 58579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson .constructorArgTypes(String.class) 59579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson .constructorArgValues("hello") 60579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson .build(); 61579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson assertEquals("hello", proxy.argument); 62579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson proxy.method(); 63579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 64579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 65579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public void testConstruction_FailsWithWrongNumberOfArguments() throws Throwable { 66579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson try { 67579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson proxyFor(ConstructorTakesArguments.class).build(); 68579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson fail(); 69579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } catch (IllegalArgumentException expected) {} 70579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 71579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 72579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public void testClassIsNotAccessbile_FailsWithUnsupportedOperationException() throws Exception { 73579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson class MethodVisibilityClass { 74579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 75579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson try { 76579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson proxyFor(MethodVisibilityClass.class).build(); 77579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson fail(); 78579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } catch (UnsupportedOperationException expected) {} 79579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 80579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 81579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson private static class PrivateVisibilityClass { 82579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 83579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 84579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public void testPrivateClass_FailsWithUnsupportedOperationException() throws Exception { 85579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson try { 86579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson proxyFor(PrivateVisibilityClass.class).build(); 87579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson fail(); 88579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } catch (UnsupportedOperationException expected) {} 89579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 90579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 91579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson protected static class ProtectedVisibilityClass { 92579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public String foo() { 93579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson throw new AssertionFailedError(); 94579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 95579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 96579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 97579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public void testProtectedVisibility_WorksFine() throws Exception { 98579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson assertEquals("fake result", proxyFor(ProtectedVisibilityClass.class).build().foo()); 99579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 100579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 101579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public static class HasFinalMethod { 102579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public String nonFinalMethod() { 103579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return "non-final method"; 104579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 105579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 106579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public final String finalMethod() { 107579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return "final method"; 108579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 109579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 110579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 111579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public void testCanProxyClassesWithFinalMethods_WillNotCallTheFinalMethod() throws Throwable { 112579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson HasFinalMethod proxy = proxyFor(HasFinalMethod.class).build(); 113579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson assertEquals("final method", proxy.finalMethod()); 114579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson assertEquals("fake result", proxy.nonFinalMethod()); 115579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 116579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 117579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public static class HasPrivateMethod { 118579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson private String result() { 119579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return "expected"; 120579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 121579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 122579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 123579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public void testProxyingPrivateMethods_NotIntercepted() throws Throwable { 124579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson assertEquals("expected", proxyFor(HasPrivateMethod.class).build().result()); 125579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 126579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 127579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public static class HasPackagePrivateMethod { 128579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson String result() { 129579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson throw new AssertionFailedError(); 130579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 131579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 132579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 133579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public void testProxyingPackagePrivateMethods_AreIntercepted() throws Throwable { 134579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson assertEquals("fake result", proxyFor(HasPackagePrivateMethod.class).build().result()); 135579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 136579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 137579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public static class HasProtectedMethod { 138579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson protected String result() { 139579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson throw new AssertionFailedError(); 140579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 141579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 142579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 143579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public void testProxyingProtectedMethods_AreIntercepted() throws Throwable { 144579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson assertEquals("fake result", proxyFor(HasProtectedMethod.class).build().result()); 145579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 146579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 147579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public static class HasVoidMethod { 148579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public void dangerousMethod() { 149579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson fail(); 150579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 151579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 152579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 153579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public void testVoidMethod_ShouldNotThrowRuntimeException() throws Throwable { 154579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson proxyFor(HasVoidMethod.class).build().dangerousMethod(); 155579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 156579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 157579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public void testObjectMethodsAreAlsoProxied() throws Throwable { 158579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson Object proxy = proxyFor(Object.class).build(); 159579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson fakeHandler.setFakeResult("mystring"); 160579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson assertEquals("mystring", proxy.toString()); 161579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson fakeHandler.setFakeResult(-1); 162579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson assertEquals(-1, proxy.hashCode()); 163579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson fakeHandler.setFakeResult(false); 164579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson assertEquals(false, proxy.equals(proxy)); 165579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 166579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 167579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public static class AllPrimitiveMethods { 168579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public boolean getBoolean() { return true; } 169579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public int getInt() { return 1; } 170579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public byte getByte() { return 2; } 171579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public long getLong() { return 3L; } 172579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public short getShort() { return 4; } 173579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public float getFloat() { return 5f; } 174579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public double getDouble() { return 6.0; } 175579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public char getChar() { return 'c'; } 176579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 177579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 178579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public void testAllPrimitiveReturnTypes() throws Throwable { 179579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson AllPrimitiveMethods proxy = proxyFor(AllPrimitiveMethods.class).build(); 180579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson fakeHandler.setFakeResult(false); 181579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson assertEquals(false, proxy.getBoolean()); 182579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson fakeHandler.setFakeResult(8); 183579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson assertEquals(8, proxy.getInt()); 184579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson fakeHandler.setFakeResult((byte) 9); 185579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson assertEquals(9, proxy.getByte()); 186579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson fakeHandler.setFakeResult(10L); 187579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson assertEquals(10, proxy.getLong()); 188579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson fakeHandler.setFakeResult((short) 11); 189579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson assertEquals(11, proxy.getShort()); 190579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson fakeHandler.setFakeResult(12f); 191579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson assertEquals(12f, proxy.getFloat()); 192579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson fakeHandler.setFakeResult(13.0); 193579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson assertEquals(13.0, proxy.getDouble()); 194579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson fakeHandler.setFakeResult('z'); 195579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson assertEquals('z', proxy.getChar()); 196579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 197579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 198579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public static class PassThroughAllPrimitives { 199579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public boolean getBoolean(boolean input) { return input; } 200579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public int getInt(int input) { return input; } 201579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public byte getByte(byte input) { return input; } 202579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public long getLong(long input) { return input; } 203579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public short getShort(short input) { return input; } 204579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public float getFloat(float input) { return input; } 205579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public double getDouble(double input) { return input; } 206579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public char getChar(char input) { return input; } 207579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public String getString(String input) { return input; } 208579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public Object getObject(Object input) { return input; } 209579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public void getNothing() {} 210579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 211579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 212579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public static class InvokeSuperHandler implements InvocationHandler { 213579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { 214579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return ProxyBuilder.callSuper(proxy, method, args); 215579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 216579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 217579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 218579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public void testPassThroughWorksForAllPrimitives() throws Exception { 219579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson PassThroughAllPrimitives proxy = proxyFor(PassThroughAllPrimitives.class) 220579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson .handler(new InvokeSuperHandler()) 221579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson .build(); 222579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson assertEquals(false, proxy.getBoolean(false)); 223579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson assertEquals(true, proxy.getBoolean(true)); 224579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson assertEquals(0, proxy.getInt(0)); 225579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson assertEquals(1, proxy.getInt(1)); 226579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson assertEquals((byte) 2, proxy.getByte((byte) 2)); 227579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson assertEquals((byte) 3, proxy.getByte((byte) 3)); 228579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson assertEquals(4L, proxy.getLong(4L)); 229579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson assertEquals(5L, proxy.getLong(5L)); 230579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson assertEquals((short) 6, proxy.getShort((short) 6)); 231579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson assertEquals((short) 7, proxy.getShort((short) 7)); 232579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson assertEquals(8f, proxy.getFloat(8f)); 233579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson assertEquals(9f, proxy.getFloat(9f)); 234579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson assertEquals(10.0, proxy.getDouble(10.0)); 235579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson assertEquals(11.0, proxy.getDouble(11.0)); 236579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson assertEquals('a', proxy.getChar('a')); 237579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson assertEquals('b', proxy.getChar('b')); 238579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson assertEquals("asdf", proxy.getString("asdf")); 239579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson assertEquals("qwer", proxy.getString("qwer")); 240579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson assertEquals(null, proxy.getString(null)); 241579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson Object a = new Object(); 242579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson assertEquals(a, proxy.getObject(a)); 243579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson assertEquals(null, proxy.getObject(null)); 244579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson proxy.getNothing(); 245579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 246579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 247579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public static class ExtendsAllPrimitiveMethods extends AllPrimitiveMethods { 248579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public int example() { return 0; } 249579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 250579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 251579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public void testProxyWorksForSuperclassMethodsAlso() throws Throwable { 252579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson ExtendsAllPrimitiveMethods proxy = proxyFor(ExtendsAllPrimitiveMethods.class).build(); 253579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson fakeHandler.setFakeResult(99); 254579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson assertEquals(99, proxy.example()); 255579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson assertEquals(99, proxy.getInt()); 256579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson assertEquals(99, proxy.hashCode()); 257579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 258579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 259579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public static class HasOddParams { 260579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public long method(int first, Integer second) { 261579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson throw new AssertionFailedError(); 262579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 263579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 264579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 265579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public void testMixingBoxedAndUnboxedParams() throws Throwable { 266579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson HasOddParams proxy = proxyFor(HasOddParams.class).build(); 267579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson fakeHandler.setFakeResult(99L); 268579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson assertEquals(99L, proxy.method(1, Integer.valueOf(2))); 269579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 270579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 271579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public static class SingleInt { 272579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public String getString(int value) { 273579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson throw new AssertionFailedError(); 274579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 275579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 276579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 277579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public void testSinglePrimitiveParameter() throws Throwable { 278579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson InvocationHandler handler = new InvocationHandler() { 279579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { 280579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return "asdf" + ((Integer) args[0]).intValue(); 281579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 282579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson }; 283579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson assertEquals("asdf1", proxyFor(SingleInt.class).handler(handler).build().getString(1)); 284579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 285579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 286579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public static class TwoConstructors { 287579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson private final String string; 288579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 289579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public TwoConstructors() { 290579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson string = "no-arg"; 291579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 292579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 293579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public TwoConstructors(boolean unused) { 294579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson string = "one-arg"; 295579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 296579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 297579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 298579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public void testNoConstructorArguments_CallsNoArgConstructor() throws Throwable { 299579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson TwoConstructors twoConstructors = proxyFor(TwoConstructors.class).build(); 300579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson assertEquals("no-arg", twoConstructors.string); 301579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 302579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 303579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public void testWithoutInvocationHandler_ThrowsIllegalArgumentException() throws Throwable { 304579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson try { 305579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson ProxyBuilder.forClass(TwoConstructors.class) 306579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson .dexCache(DexGeneratorTest.getDataDirectory()) 307579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson .build(); 308579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson fail(); 309579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } catch (IllegalArgumentException expected) {} 310579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 311579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 312579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public static class HardToConstructCorrectly { 313579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public HardToConstructCorrectly() { fail(); } 314579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public HardToConstructCorrectly(Runnable ignored) { fail(); } 315579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public HardToConstructCorrectly(Exception ignored) { fail(); } 316579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public HardToConstructCorrectly(Boolean ignored) { /* safe */ } 317579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public HardToConstructCorrectly(Integer ignored) { fail(); } 318579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 319579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 320579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public void testHardToConstruct_WorksIfYouSpecifyTheConstructorCorrectly() throws Throwable { 321579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson proxyFor(HardToConstructCorrectly.class) 322579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson .constructorArgTypes(Boolean.class) 323579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson .constructorArgValues(true) 324579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson .build(); 325579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 326579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 327579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public void testHardToConstruct_EvenWorksWhenArgsAreAmbiguous() throws Throwable { 328579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson proxyFor(HardToConstructCorrectly.class) 329579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson .constructorArgTypes(Boolean.class) 330579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson .constructorArgValues(new Object[] { null }) 331579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson .build(); 332579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 333579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 334579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public void testHardToConstruct_DoesNotInferTypesFromValues() throws Throwable { 335579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson try { 336579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson proxyFor(HardToConstructCorrectly.class) 337579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson .constructorArgValues(true) 338579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson .build(); 339579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson fail(); 340579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } catch (IllegalArgumentException expected) {} 341579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 342579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 343579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public void testDefaultProxyHasSuperMethodToAccessOriginal() throws Exception { 344579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson Object objectProxy = proxyFor(Object.class).build(); 345579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson assertNotNull(objectProxy.getClass().getMethod("super_hashCode")); 346579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 347579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 348579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public static class PrintsOddAndValue { 349579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public String method(int value) { 350579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return "odd " + value; 351579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 352579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 353579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 354579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public void testSometimesDelegateToSuper() throws Exception { 355579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson InvocationHandler delegatesOddValues = new InvocationHandler() { 356579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { 357579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (method.getName().equals("method")) { 358579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson int intValue = ((Integer) args[0]).intValue(); 359579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (intValue % 2 == 0) { 360579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return "even " + intValue; 361579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 362579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 363579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return ProxyBuilder.callSuper(proxy, method, args); 364579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 365579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson }; 366579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson PrintsOddAndValue proxy = proxyFor(PrintsOddAndValue.class) 367579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson .handler(delegatesOddValues) 368579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson .build(); 369579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson assertEquals("even 0", proxy.method(0)); 370579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson assertEquals("odd 1", proxy.method(1)); 371579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson assertEquals("even 2", proxy.method(2)); 372579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson assertEquals("odd 3", proxy.method(3)); 373579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 374579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 375579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public static class DoubleReturn { 376579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public double getValue() { 377579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return 2.0; 378579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 379579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 380579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 381579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public void testUnboxedResult() throws Exception { 382579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson fakeHandler.fakeResult = 2.0; 383579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson assertEquals(2.0, proxyFor(DoubleReturn.class).build().getValue()); 384579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 385579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 386579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public static void staticMethod() { 387579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 388579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 389579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public void testDoesNotOverrideStaticMethods() throws Exception { 390579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson // Method should exist on this test class itself. 391579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson ProxyBuilderTest.class.getDeclaredMethod("staticMethod"); 392579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson // Method should not exist on the subclass. 393579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson try { 394579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson proxyFor(ProxyBuilderTest.class).build().getClass().getDeclaredMethod("staticMethod"); 395579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson fail(); 396579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } catch (NoSuchMethodException expected) {} 397579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 398579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 399579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public void testIllegalCacheDirectory() throws Exception { 400579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson try { 401579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson proxyFor(Object.class).dexCache(new File("//////")).build(); 402579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson fail(); 403579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } catch (DexCacheException expected) {} 404579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 405579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 406579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public void testInvalidConstructorSpecification() throws Exception { 407579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson try { 408579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson proxyFor(Object.class) 409579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson .constructorArgTypes(String.class, Boolean.class) 410579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson .constructorArgValues("asdf", true) 411579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson .build(); 412579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson fail(); 413579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } catch (IllegalArgumentException expected) {} 414579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 415579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 416579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public static abstract class AbstractClass { 417579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public abstract Object getValue(); 418579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 419579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 420579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public void testAbstractClassBehaviour() throws Exception { 421579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson assertEquals("fake result", proxyFor(AbstractClass.class).build().getValue()); 422579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 423579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 424579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public static class CtorHasDeclaredException { 425579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public CtorHasDeclaredException() throws IOException { 426579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson throw new IOException(); 427579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 428579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 429579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 430579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public static class CtorHasRuntimeException { 431579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public CtorHasRuntimeException() { 432579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson throw new RuntimeException("my message"); 433579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 434579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 435579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 436579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public static class CtorHasError { 437579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public CtorHasError() { 438579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson throw new Error("my message again"); 439579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 440579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 441579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 442579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public void testParentConstructorThrowsDeclaredException() throws Exception { 443579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson try { 444579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson proxyFor(CtorHasDeclaredException.class).build(); 445579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson fail(); 446579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } catch (UndeclaredThrowableException expected) { 447579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson assertTrue(expected.getCause() instanceof IOException); 448579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 449579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson try { 450579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson proxyFor(CtorHasRuntimeException.class).build(); 451579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson fail(); 452579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } catch (RuntimeException expected) { 453579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson assertEquals("my message", expected.getMessage()); 454579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 455579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson try { 456579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson proxyFor(CtorHasError.class).build(); 457579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson fail(); 458579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } catch (Error expected) { 459579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson assertEquals("my message again", expected.getMessage()); 460579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 461579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 462579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 463579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public void testGetInvocationHandler_NormalOperation() throws Exception { 464579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson Object proxy = proxyFor(Object.class).build(); 465579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson assertSame(fakeHandler, ProxyBuilder.getInvocationHandler(proxy)); 466579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 467579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 468579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public void testGetInvocationHandler_NotAProxy() { 469579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson try { 470579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson ProxyBuilder.getInvocationHandler(new Object()); 471579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson fail(); 472579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } catch (IllegalArgumentException expected) {} 473579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 474579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 475579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public static class ReturnsObject { 476579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public Object getValue() { 477579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return new Object(); 478579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 479579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 480579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 481579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public static class ReturnsString extends ReturnsObject { 482579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson @Override 483579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public String getValue() { 484579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return "a string"; 485579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 486579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 487579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 488579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public void testCovariantReturnTypes_NormalBehaviour() throws Exception { 489579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson String expected = "some string"; 490579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson fakeHandler.setFakeResult(expected); 491579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson assertSame(expected, proxyFor(ReturnsObject.class).build().getValue()); 492579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson assertSame(expected, proxyFor(ReturnsString.class).build().getValue()); 493579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 494579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 495579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public void testCovariantReturnTypes_WrongReturnType() throws Exception { 496579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson try { 497579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson fakeHandler.setFakeResult(new Object()); 498579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson proxyFor(ReturnsString.class).build().getValue(); 499579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson fail(); 500579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } catch (ClassCastException expected) {} 501579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 502579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 503579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public void testCaching_ShouldWork() { 504579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson // TODO: We're not supporting caching yet. But we should as soon as possible. 505579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson fail(); 506579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 507579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 508579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public void testSubclassOfRandom() throws Exception { 509579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson proxyFor(Random.class) 510579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson .handler(new InvokeSuperHandler()) 511579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson .build(); 512579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 513579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 514579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** Simple helper to add the most common args for this test to the proxy builder. */ 515579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson private <T> ProxyBuilder<T> proxyFor(Class<T> clazz) throws Exception { 516579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return ProxyBuilder.forClass(clazz) 517579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson .handler(fakeHandler) 518579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson .dexCache(DexGeneratorTest.getDataDirectory()); 519579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 520579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 521579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson private static class FakeInvocationHandler implements InvocationHandler { 522579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson private Object fakeResult = "fake result"; 523579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 524579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { 525579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return fakeResult; 526579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 527579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 528579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public void setFakeResult(Object result) { 529579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson fakeResult = result; 530579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 531579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 532579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson} 533