package org.fotap.heysync;
import org.jetlang.core.SynchronousDisposingExecutor;
import org.jetlang.fibers.FiberStub;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import java.util.Collection;
import static org.junit.Assert.assertNotNull;
import static org.mockito.Mockito.*;
/**
* @author <a href="mailto:peter.royal@pobox.com">peter royal</a>
*/
public class ProtocolTest {
@Rule
public ExpectedException expectedException = ExpectedException.none();
@Test
public void shouldSendAsyncMessage() {
FiberStub executor = new FiberStub();
Protocol<Mouse> protocol = Protocol.create(Mouse.class);
Mouse receiver = mock(Mouse.class);
protocol.subscribe(executor, receiver);
protocol.publisher().eatCheese("cheddar");
verifyZeroInteractions(receiver);
executor.executeAllPending();
verify(receiver).eatCheese("cheddar");
}
@Test
public void shouldSendAsyncMessageWithPrimitive() {
FiberStub executor = new FiberStub();
Protocol<Mouse> protocol = Protocol.create(Mouse.class);
Mouse receiver = mock(Mouse.class);
protocol.subscribe(executor, receiver);
protocol.publisher().provokeCats(4);
verifyZeroInteractions(receiver);
executor.executeAllPending();
verify(receiver).provokeCats(4);
}
@Test
public void shouldSendAsyncMessageWithArrays() {
FiberStub executor = new FiberStub();
Protocol<Mouse> protocol = Protocol.create(Mouse.class);
Mouse receiver = mock(Mouse.class);
protocol.subscribe(executor, receiver);
protocol.publisher().shoutWords("hello", "world");
verifyZeroInteractions(receiver);
executor.executeAllPending();
verify(receiver).shoutWords("hello", "world");
}
@Test
public void shouldSendAsyncMessageWithPrimitiveArrays() {
FiberStub executor = new FiberStub();
Protocol<Mouse> protocol = Protocol.create(Mouse.class);
Mouse receiver = mock(Mouse.class);
protocol.subscribe(executor, receiver);
protocol.publisher().reciteNumbers(2, 4, 6, 8);
verifyZeroInteractions(receiver);
executor.executeAllPending();
verify(receiver).reciteNumbers(2, 4, 6, 8);
}
@Test
public void shouldSendAsyncMessageWithMultipleParameters() {
FiberStub executor = new FiberStub();
Protocol<Mouse> protocol = Protocol.create(Mouse.class);
Mouse receiver = mock(Mouse.class);
protocol.subscribe(executor, receiver);
protocol.publisher().provokeCatsWithTaunt(4, "mice are clever");
verifyZeroInteractions(receiver);
executor.executeAllPending();
verify(receiver).provokeCatsWithTaunt(4, "mice are clever");
}
@Test
public void shouldBeAbleToCreateMultipleProxiesFromFactory() {
Protocol.Factory<Mouse> factory = Protocol.Factory.create(Mouse.class);
factory.create();
factory.create();
}
@Test
public void shouldHandleMultipleSubscribers() {
FiberStub executor = new FiberStub();
Protocol<Mouse> protocol = Protocol.create(Mouse.class);
protocol.subscribe(executor, mock(Mouse.class, "one"));
protocol.subscribe(executor, mock(Mouse.class, "two"));
}
@Test
public void shouldSendAsyncSignal() {
FiberStub executor = new FiberStub();
Protocol<Pinger> protocol = Protocol.create(Pinger.class);
Pinger receiver = mock(Pinger.class);
protocol.subscribe(executor, receiver);
protocol.publisher().ping();
verifyZeroInteractions(receiver);
executor.executeAllPending();
verify(receiver).ping();
}
@Test
public void shouldFailWhenTryingToGetDispatcherForNotAtAsynchronousInterface() {
expectedException.expect(IllegalArgumentException.class);
expectedException.expectMessage("Cannot create a protocol for " + Collection.class.getName() + ". It must be an interface that is marked with the " + Asynchronous.class
.getName() + " annotation");
Protocol.create(Collection.class);
}
@Test
public void shouldFailWhenTryingToGetDispatcherForClass() {
expectedException.expect(IllegalArgumentException.class);
expectedException.expectMessage("Cannot create a protocol for " + Object.class.getName() + ". It must be an interface that is marked with the " + Asynchronous.class
.getName() + " annotation");
Protocol.create(Object.class);
}
@Test
public void shouldGetChannelForMethod() throws NoSuchMethodException {
Protocol<Mouse> protocol = Protocol.create(Mouse.class);
assertNotNull(protocol.channelFor(Mouse.class.getMethod("eatCheese", String.class), String.class));
assertNotNull(protocol.channelFor(Mouse.class.getMethod("provokeCats", Integer.TYPE), Integer.TYPE));
assertNotNull(protocol.channelFor(Mouse.class.getMethod("provokeCatsWithTaunt", Integer.TYPE, String.class), Object[].class));
assertNotNull(protocol.channelFor(Mouse.class.getMethod("shoutWords", String[].class), String[].class));
}
@Test
public void shouldFailWhenSpecifyingInvalidParameterType() throws NoSuchMethodException {
expectedException.expect(IllegalArgumentException.class);
expectedException.expectMessage(
"Specified parameter type java.lang.Object is not what the method requires: public abstract void org.fotap.heysync.Mouse.eatCheese(java.lang.String)");
Protocol<Mouse> protocol = Protocol.create(Mouse.class);
assertNotNull(protocol.channelFor(Mouse.class.getMethod("eatCheese", String.class), Object.class));
}
@Test
public void shouldFailWhenTryingToGetChannelForInvalidMethod() throws NoSuchMethodException {
expectedException.expect(IllegalArgumentException.class);
expectedException.expectMessage(
"public java.lang.String java.lang.Object.toString() is not a method on org.fotap.heysync.Mouse");
Protocol<Mouse> protocol = Protocol.create(Mouse.class);
protocol.channelFor(Object.class.getMethod("toString"), Object.class);
}
@Test
public void shouldHandleExtendedInterfaces() {
LabMouse subscription = mock(LabMouse.class);
Protocol<LabMouse> protocol = Protocol.create(LabMouse.class);
protocol.subscribe(new SynchronousDisposingExecutor(), subscription);
protocol.publisher().runThroughMaze();
protocol.publisher().eatCheese("reward");
verify(subscription).runThroughMaze();
verify(subscription).eatCheese("reward");
}
@Test
public void shouldCreatePublisherForInterfaceThatHasSuperInterfacesWithClashingSignatures() throws Exception {
Protocol<AB> protocol = Protocol.create(AB.class);
AB mock = mock(AB.class);
protocol.subscribe(new SynchronousDisposingExecutor(), mock);
protocol.publisher().something("cheddar");
verify(mock).something("cheddar");
}
@Test
public void shouldCreatePublisherForClassesWithMethodOverloading() throws Exception {
Protocol<Overloaded> protocol = Protocol.create(Overloaded.class);
Overloaded mock = mock(Overloaded.class);
protocol.subscribe(new SynchronousDisposingExecutor(), mock);
protocol.publisher().doSomething("cheddar");
verify(mock).doSomething("cheddar");
protocol.publisher().doSomething("cheddar", "beer");
verify(mock).doSomething("cheddar", "beer");
verifyNoMoreInteractions(mock);
}
}