package org.fishwife.jrugged; import static org.junit.Assert.*; import static org.easymock.EasyMock.*; import java.util.ArrayList; import java.util.Arrays; import java.util.concurrent.Callable; import org.junit.Test; public class TestServiceWrapperChain { private ServiceWrapperChain impl; @Test public void callableJustGetsInvokedWithNoWrappers() throws Exception { impl = new ServiceWrapperChain(new ArrayList<ServiceWrapper>()); final Object out = new Object(); Callable<Object> c = new Callable<Object>() { public Object call() throws Exception { return out; } }; assertSame(out, impl.invoke(c)); } @Test public void runnableJustGetsRunWithNoWrappers() throws Exception { Runnable r = createMock(Runnable.class); impl = new ServiceWrapperChain(new ArrayList<ServiceWrapper>()); r.run(); replay(r); impl.invoke(r); verify(r); } @Test public void runnableWithResultJustGetsRunWithNoWrappers() throws Exception { Runnable r = createMock(Runnable.class); impl = new ServiceWrapperChain(new ArrayList<ServiceWrapper>()); final Object out = new Object(); r.run(); replay(r); Object result = impl.invoke(r, out); verify(r); assertSame(out, result); } @Test public void callableWithOneWrapperRunsThroughWrapper() throws Exception { final Object out = new Object(); Callable<Object> c = new Callable<Object>() { public Object call() throws Exception { return null; } }; ServiceWrapper wrapper = createMock(ServiceWrapper.class); impl = new ServiceWrapperChain(Arrays.asList(wrapper)); expect(wrapper.invoke(c)).andReturn(out); replay(wrapper); Object result = impl.invoke(c); verify(wrapper); assertSame(out, result); } @Test public void runnableWithOneWrapperRunsThroughWrapper() throws Exception { Runnable r = createMock(Runnable.class); ServiceWrapper wrapper = createMock(ServiceWrapper.class); impl = new ServiceWrapperChain(Arrays.asList(wrapper)); wrapper.invoke(r); replay(wrapper); replay(r); impl.invoke(r); verify(wrapper); verify(r); } @Test public void runnableWithReturnWithOneWrapperRunsThroughWrapper() throws Exception { final Object out = new Object(); Runnable r = createMock(Runnable.class); ServiceWrapper wrapper = createMock(ServiceWrapper.class); impl = new ServiceWrapperChain(Arrays.asList(wrapper)); wrapper.invoke(r); replay(wrapper); replay(r); Object result = impl.invoke(r, out); verify(wrapper); verify(r); assertSame(out, result); } @Test public void callableWithTwoWrappersRunsThroughFirstWrapperFirst() throws Exception { final Object out1 = new Object(); final Object out2 = new Object(); Callable<Object> c = new NullCallable(); ServiceWrapper wrapper1 = new NullWrapper() { @SuppressWarnings("unchecked") @Override public <T> T invoke(Callable<T> c) throws Exception { return (T)out1; } }; ServiceWrapper wrapper2 = new NullWrapper() { @SuppressWarnings("unchecked") @Override public <T> T invoke(Callable<T> c) throws Exception { return (T)out2; } }; impl = new ServiceWrapperChain(Arrays.asList(wrapper1, wrapper2)); assertSame(out1, impl.invoke(c)); } @Test public void runnableWithTwoWrappersRunsThroughFirstWrapperFirst() throws Exception { Runnable r = new NullRunnable(); final Flag f1 = new Flag(); final Flag f2 = new Flag(); ServiceWrapper wrapper1 = new NullWrapper() { @Override public void invoke(Runnable r) throws Exception { f1.set = true; } }; ServiceWrapper wrapper2 = new NullWrapper() { @Override public void invoke(Runnable r) throws Exception { f2.set = false; } }; impl = new ServiceWrapperChain(Arrays.asList(wrapper1, wrapper2)); impl.invoke(r); assertTrue(f1.set); assertFalse(f2.set); } @Test public void runnableWithReturnWithTwoWrappersRunsThroughFirstWrapperFirst() throws Exception { final Object out = new Object(); Runnable r = new NullRunnable(); final Flag f1 = new Flag(); final Flag f2 = new Flag(); ServiceWrapper wrapper1 = new NullWrapper() { @Override public void invoke(Runnable r) throws Exception { f1.set = true; } }; ServiceWrapper wrapper2 = new NullWrapper() { @Override public void invoke(Runnable r) throws Exception { f2.set = false; } }; impl = new ServiceWrapperChain(Arrays.asList(wrapper1, wrapper2)); Object result = impl.invoke(r, out); assertTrue(f1.set); assertFalse(f2.set); assertSame(out, result); } @Test public void callableWithTwoNullWrappersThreadsProperly() throws Exception { final Object out = new Object(); Callable<Object> c = new Callable<Object>() { public Object call() throws Exception { return out; } }; NullWrapper wrapper1 = new NullWrapper(); NullWrapper wrapper2 = new NullWrapper(); impl = new ServiceWrapperChain(Arrays.asList((ServiceWrapper)wrapper1, (ServiceWrapper)wrapper2)); Object result = impl.invoke(c); assertTrue(wrapper1.invokedCallable); assertTrue(wrapper2.invokedCallable); assertSame(out, result); } @Test public void runnableWithTwoNullWrappersThreadsProperly() throws Exception { final Flag f = new Flag(); Runnable r = new Runnable() { public void run() { f.set = true; } }; NullWrapper wrapper1 = new NullWrapper(); NullWrapper wrapper2 = new NullWrapper(); impl = new ServiceWrapperChain(Arrays.asList((ServiceWrapper)wrapper1, (ServiceWrapper)wrapper2)); impl.invoke(r); assertTrue(wrapper1.invokedRunnable); assertTrue(wrapper2.invokedRunnable); assertTrue(f.set); } @Test public void runnableWithReturnWithTwoNullWrappersThreadsProperly() throws Exception { final Object out = new Object(); final Flag f = new Flag(); Runnable r = new Runnable() { public void run() { f.set = true; } }; NullWrapper wrapper1 = new NullWrapper(); NullWrapper wrapper2 = new NullWrapper(); impl = new ServiceWrapperChain(Arrays.asList((ServiceWrapper)wrapper1, (ServiceWrapper)wrapper2)); Object result = impl.invoke(r, out); assertTrue(wrapper1.invokedRunnable); assertTrue(wrapper2.invokedRunnable); assertTrue(f.set); assertSame(out, result); } private static class Flag { public boolean set = false; } private static class NullRunnable implements Runnable { public void run() { } } private static class NullCallable implements Callable<Object> { public Object call() throws Exception { return null; } } private static class NullWrapper implements ServiceWrapper { public boolean invokedCallable; public boolean invokedRunnable; public <T> T invoke(Callable<T> c) throws Exception { invokedCallable = true; return c.call(); } public void invoke(Runnable r) throws Exception { invokedRunnable = true; r.run(); } public <T> T invoke(Runnable r, T result) throws Exception { return null; } } }