package org.netbeans.gradle.project.others;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import org.junit.Test;
import static org.junit.Assert.*;
import static org.mockito.Matchers.*;
import static org.mockito.Mockito.*;
public class PluginClassImplementationTest {
private static ClassFinder classFinder(final Class<?> type) {
return ReflectionHelper.constClassFinder(type);
}
private static void verifyRunForwarded(Runnable instance, Runnable wrapped) {
assertNotNull(instance);
verifyZeroInteractions(wrapped);
instance.run();
verify(wrapped).run();
}
@Test
public void testDelegateToInterface() {
Runnable wrapped = mock(Runnable.class);
PluginClassImplementation impl
= new PluginClassImplementation(classFinder(Runnable.class), new MyRunnable(wrapped));
Runnable instance = (Runnable)impl.tryGetAsPluginClass();
verifyRunForwarded(instance, wrapped);
}
@Test
public void testDelegateToInterfaceWithException() throws Throwable {
Runnable2 wrapped = mock(Runnable2.class);
final InvocationHandler run2Handler = mock(InvocationHandler.class);
InvocationHandlerFactory exceptionalCase = new InvocationHandlerFactory() {
@Override
public InvocationHandler tryGetInvocationHandler(Object proxy, Method method, Object[] args) {
return "run2".equals(method.getName()) ? run2Handler : null;
}
};
PluginClassImplementation impl = new PluginClassImplementation(
classFinder(Runnable2.class),
new MyRunnable(wrapped),
exceptionalCase);
Runnable2 instance = (Runnable2)impl.tryGetAsPluginClass();
verifyRunForwarded(instance, wrapped);
verifyZeroInteractions(run2Handler);
instance.run2();
verify(wrapped, never()).run2();
verify(run2Handler).invoke(same(instance), any(Method.class), any(Object[].class));
}
// Do not implement Runnable, must be a public class
public static final class MyRunnable {
private final Runnable wrapped;
public MyRunnable(Runnable wrapped) {
this.wrapped = wrapped;
}
public void run() {
wrapped.run();
}
}
public interface Runnable2 extends Runnable {
public void run2();
}
}