summaryrefslogtreecommitdiffstats
path: root/luni/src/test/java/libcore/java/lang/reflect/ProxyTest.java
diff options
context:
space:
mode:
Diffstat (limited to 'luni/src/test/java/libcore/java/lang/reflect/ProxyTest.java')
-rw-r--r--luni/src/test/java/libcore/java/lang/reflect/ProxyTest.java334
1 files changed, 333 insertions, 1 deletions
diff --git a/luni/src/test/java/libcore/java/lang/reflect/ProxyTest.java b/luni/src/test/java/libcore/java/lang/reflect/ProxyTest.java
index 30d47fb..abd5851 100644
--- a/luni/src/test/java/libcore/java/lang/reflect/ProxyTest.java
+++ b/luni/src/test/java/libcore/java/lang/reflect/ProxyTest.java
@@ -16,14 +16,25 @@
package libcore.java.lang.reflect;
+import java.io.EOFException;
+import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
+import java.lang.reflect.UndeclaredThrowableException;
+import java.net.SocketException;
import junit.framework.TestCase;
import tests.util.ClassLoaderBuilder;
public final class ProxyTest extends TestCase {
+ private final ClassLoader loader = getClass().getClassLoader();
+ private final InvocationHandler returnHandler = new TestInvocationHandler();
+ private final InvocationHandler throwHandler = new InvocationHandler() {
+ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
+ throw (Throwable) args[0];
+ }
+ };
/**
* Make sure the proxy's class loader fails if it cannot see the class
@@ -36,7 +47,7 @@ public final class ProxyTest extends TestCase {
Class[] interfacesA = { loaderA.loadClass(prefix + "$Echo") };
try {
- Proxy.newProxyInstance(loaderB, interfacesA, new TestInvocationHandler());
+ Proxy.newProxyInstance(loaderB, interfacesA, returnHandler);
fail();
} catch (IllegalArgumentException expected) {
}
@@ -55,10 +66,331 @@ public final class ProxyTest extends TestCase {
assertEquals("foo", proxy.getClass().getMethod("echo", String.class).invoke(proxy, "foo"));
}
+ public void testIncompatibleReturnTypesPrimitiveAndPrimitive() {
+ try {
+ Proxy.newProxyInstance(loader, new Class[] {ReturnsInt.class, ReturnsFloat.class},
+ returnHandler);
+ fail();
+ } catch (IllegalArgumentException expected) {
+ }
+ }
+
+ public void testIncompatibleReturnTypesPrimitiveAndWrapper() {
+ try {
+ Proxy.newProxyInstance(loader, new Class[] {ReturnsInt.class, ReturnsInteger.class},
+ returnHandler);
+ fail();
+ } catch (IllegalArgumentException expected) {
+ }
+ }
+
+ public void testIncompatibleReturnTypesPrimitiveAndVoid() {
+ try {
+ Proxy.newProxyInstance(loader, new Class[] {ReturnsInt.class, ReturnsVoid.class},
+ returnHandler);
+ fail();
+ } catch (IllegalArgumentException expected) {
+ }
+ }
+
+ public void testIncompatibleReturnTypesIncompatibleObjects() {
+ try {
+ Proxy.newProxyInstance(loader, new Class[] {ReturnsInteger.class, ReturnsString.class },
+ returnHandler);
+ fail();
+ } catch (IllegalArgumentException expected) {
+ }
+ }
+
+ public void testCompatibleReturnTypesImplementedInterface() {
+ Proxy.newProxyInstance(loader, new Class[] {ReturnsString.class, ReturnsCharSequence.class},
+ returnHandler);
+ Proxy.newProxyInstance(loader, new Class[]{ReturnsObject.class, ReturnsCharSequence.class,
+ ReturnsString.class}, returnHandler);
+ Proxy.newProxyInstance(loader, new Class[]{ReturnsObject.class, ReturnsCharSequence.class,
+ ReturnsString.class, ReturnsSerializable.class, ReturnsComparable.class},
+ returnHandler);
+ }
+
+
+ public void testCompatibleReturnTypesSuperclass() {
+ Proxy.newProxyInstance(loader, new Class[] {ReturnsString.class, ReturnsObject.class},
+ returnHandler);
+ }
+
+ public void testDeclaredExceptionIntersectionIsSubtype() throws Exception {
+ ThrowsIOException instance = (ThrowsIOException) Proxy.newProxyInstance(loader,
+ new Class[] {ThrowsIOException.class, ThrowsEOFException.class},
+ throwHandler);
+ try {
+ instance.run(new EOFException());
+ fail();
+ } catch (EOFException expected) {
+ }
+ try {
+ instance.run(new IOException());
+ fail();
+ } catch (UndeclaredThrowableException expected) {
+ }
+ try {
+ instance.run(new Exception());
+ fail();
+ } catch (UndeclaredThrowableException expected) {
+ }
+ }
+
+ public void testDeclaredExceptionIntersectionIsEmpty() throws Exception {
+ ThrowsEOFException instance = (ThrowsEOFException) Proxy.newProxyInstance(loader,
+ new Class[] {ThrowsSocketException.class, ThrowsEOFException.class},
+ throwHandler);
+ try {
+ instance.run(new EOFException());
+ fail();
+ } catch (UndeclaredThrowableException expected) {
+ }
+ try {
+ instance.run(new SocketException());
+ fail();
+ } catch (UndeclaredThrowableException expected) {
+ }
+ }
+
+ public void testDeclaredExceptionIntersectionIsSubset() throws Exception {
+ ThrowsEOFException instance = (ThrowsEOFException) Proxy.newProxyInstance(loader,
+ new Class[] {ThrowsEOFException.class, ThrowsSocketExceptionAndEOFException.class},
+ throwHandler);
+ try {
+ instance.run(new EOFException());
+ fail();
+ } catch (EOFException expected) {
+ }
+ try {
+ instance.run(new SocketException());
+ fail();
+ } catch (UndeclaredThrowableException expected) {
+ }
+ try {
+ instance.run(new IOException());
+ fail();
+ } catch (UndeclaredThrowableException expected) {
+ }
+ }
+
+ public void testDeclaredExceptionIntersectedByExactReturnTypes() throws Exception {
+ ThrowsIOException instance = (ThrowsIOException) Proxy.newProxyInstance(loader,
+ new Class[] {ThrowsIOException.class, ThrowsEOFExceptionReturnsString.class},
+ throwHandler);
+ try {
+ instance.run(new EOFException());
+ fail();
+ } catch (EOFException expected) {
+ }
+ try {
+ instance.run(new IOException());
+ fail();
+ } catch (IOException expected) {
+ }
+ try {
+ ((ThrowsEOFExceptionReturnsString) instance).run(new EOFException());
+ fail();
+ } catch (EOFException expected) {
+ }
+ try {
+ ((ThrowsEOFExceptionReturnsString) instance).run(new IOException());
+ fail();
+ } catch (UndeclaredThrowableException expected) {
+ }
+ }
+
+ public void test_getProxyClass_nullInterfaces() {
+ try {
+ Proxy.getProxyClass(loader, new Class<?>[] { null });
+ fail();
+ } catch (NullPointerException expected) {
+ }
+
+ try {
+ Proxy.getProxyClass(loader, Echo.class, null);
+ fail();
+ } catch (NullPointerException expected) {
+ }
+ }
+
+ public void test_getProxyClass_duplicateInterfaces() {
+ try {
+ Proxy.getProxyClass(loader, Echo.class, Echo.class);
+ fail();
+ } catch (IllegalArgumentException expected) {
+ }
+ }
+
+ public void test_getProxyClass_caching() throws Exception {
+ Class<?> proxy1 = Proxy.getProxyClass(loader, Echo.class, ReturnsInt.class);
+ Class<?> proxy2 = Proxy.getProxyClass(loader, Echo.class, ReturnsInt.class);
+ Class<?> proxy3 = Proxy.getProxyClass(loader, ReturnsInt.class, Echo.class);
+
+ assertSame(proxy1, proxy2);
+ assertTrue(!proxy2.equals(proxy3));
+ }
+
+ public void testMethodsImplementedByFarIndirectInterface() {
+ ExtendsExtendsDeclaresFiveMethods instance = (ExtendsExtendsDeclaresFiveMethods)
+ Proxy.newProxyInstance(loader, new Class[]{ExtendsExtendsDeclaresFiveMethods.class},
+ returnHandler);
+ assertEquals("foo", instance.a("foo"));
+ assertEquals(0x12345678, instance.b(0x12345678));
+ assertEquals(Double.MIN_VALUE, instance.c(Double.MIN_VALUE));
+ assertEquals(null, instance.d(null));
+ assertEquals(0x1234567890abcdefL, instance.e(0x1234567890abcdefL));
+ }
+
+ public void testEquals() {
+ InvocationHandler handler = new InvocationHandler() {
+ @Override public Object invoke(Object proxy, Method method, Object[] args) {
+ return args[0] == ProxyTest.class; // bogus as equals(), but good for testing
+ }
+ };
+ Echo instance = (Echo) Proxy.newProxyInstance(loader, new Class[]{Echo.class}, handler);
+ assertTrue(instance.equals(ProxyTest.class));
+ assertFalse(instance.equals(new Object()));
+ assertFalse(instance.equals(instance));
+ assertFalse(instance.equals(null));
+ }
+
+ public void testHashCode() {
+ InvocationHandler handler = new InvocationHandler() {
+ @Override public Object invoke(Object proxy, Method method, Object[] args) {
+ return 0x12345678;
+ }
+ };
+ Echo instance = (Echo) Proxy.newProxyInstance(loader, new Class[]{Echo.class}, handler);
+ assertEquals(0x12345678, instance.hashCode());
+ }
+
+ public void testToString() {
+ InvocationHandler handler = new InvocationHandler() {
+ @Override public Object invoke(Object proxy, Method method, Object[] args) {
+ return "foo";
+ }
+ };
+ Echo instance = (Echo) Proxy.newProxyInstance(loader, new Class[]{Echo.class}, handler);
+ assertEquals("foo", instance.toString());
+ }
+
+ public void testReturnTypeDoesNotSatisfyAllConstraintsWithLenientCaller() {
+ InvocationHandler handler = new InvocationHandler() {
+ @Override public Object invoke(Object proxy, Method method, Object[] args) {
+ assertEquals(Object.class, method.getReturnType());
+ return Boolean.TRUE; // not the right type for 'ReturnsString' callers
+ }
+ };
+ ReturnsObject returnsObject = (ReturnsObject) Proxy.newProxyInstance(loader,
+ new Class[] {ReturnsString.class, ReturnsObject.class}, handler);
+ assertEquals(true, returnsObject.foo());
+ }
+
+ public void testReturnTypeDoesNotSatisfyAllConstraintsWithStrictCaller() {
+ InvocationHandler handler = new InvocationHandler() {
+ @Override public Object invoke(Object proxy, Method method, Object[] args) {
+ assertEquals(String.class, method.getReturnType());
+ return Boolean.TRUE; // not the right type for 'ReturnsString' callers
+ }
+ };
+ ReturnsString returnsString = (ReturnsString) Proxy.newProxyInstance(loader,
+ new Class[] {ReturnsString.class, ReturnsObject.class}, handler);
+ try {
+ returnsString.foo();
+ fail();
+ } catch (ClassCastException expected) {
+ }
+ }
+
+ public void testReturnsTypeAndInterfaceNotImplementedByThatType() {
+ try {
+ Proxy.newProxyInstance(loader, new Class[] {ReturnsString.class, ReturnsEcho.class},
+ returnHandler);
+ fail();
+ } catch (IllegalArgumentException expected) {
+ }
+ }
+
public interface Echo {
String echo(String s);
}
+ public interface ReturnsInt {
+ int foo();
+ }
+
+ public interface ReturnsFloat {
+ float foo();
+ }
+
+ public interface ReturnsInteger {
+ Integer foo();
+ }
+
+ public interface ReturnsString {
+ String foo();
+ }
+
+ public interface ReturnsCharSequence {
+ CharSequence foo();
+ }
+
+ public interface ReturnsSerializable {
+ CharSequence foo();
+ }
+
+ public interface ReturnsComparable {
+ CharSequence foo();
+ }
+
+ public interface ReturnsObject {
+ Object foo();
+ }
+
+ public interface ReturnsVoid {
+ void foo();
+ }
+
+ public interface ReturnsEcho {
+ Echo foo();
+ }
+
+ public interface ThrowsIOException {
+ Object run(Throwable toThrow) throws IOException;
+ }
+
+ public interface ThrowsEOFException {
+ Object run(Throwable toThrow) throws EOFException;
+ }
+
+ public interface ThrowsEOFExceptionReturnsString {
+ String run(Throwable toThrow) throws EOFException;
+ }
+
+ public interface ThrowsSocketException {
+ Object run(Throwable toThrow) throws SocketException;
+
+ }
+ public interface ThrowsSocketExceptionAndEOFException {
+ Object run(Throwable toThrow) throws SocketException, EOFException;
+
+ }
+
+ public interface DeclaresFiveMethods {
+ String a(String a);
+ int b(int b);
+ double c(double c);
+ Object d(Object d);
+ long e(long e);
+ }
+ public interface ExtendsDeclaresFiveMethods extends DeclaresFiveMethods {
+ }
+ public interface ExtendsExtendsDeclaresFiveMethods extends ExtendsDeclaresFiveMethods {
+ }
+
public static class TestInvocationHandler implements InvocationHandler {
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
return args[0];