From 5b91ca72c526926967a50f3c6a570dfe15e67892 Mon Sep 17 00:00:00 2001 From: DmitriyMX Date: Mon, 25 Mar 2019 14:09:13 +0300 Subject: [PATCH] update test EventBus --- .../main/java/mc/core/eventbus/EventBus.java | 31 +- core/src/test/java/mc/core/TestEventBus.java | 125 -------- .../java/mc/core/eventbus/EventBusTest.java | 274 ++++++++++++++++++ 3 files changed, 291 insertions(+), 139 deletions(-) delete mode 100644 core/src/test/java/mc/core/TestEventBus.java create mode 100644 core/src/test/java/mc/core/eventbus/EventBusTest.java diff --git a/core/src/main/java/mc/core/eventbus/EventBus.java b/core/src/main/java/mc/core/eventbus/EventBus.java index 1a14331..bb2e5b3 100644 --- a/core/src/main/java/mc/core/eventbus/EventBus.java +++ b/core/src/main/java/mc/core/eventbus/EventBus.java @@ -9,6 +9,7 @@ import org.slf4j.helpers.MessageFormatter; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; +import java.lang.reflect.Modifier; import java.util.*; import java.util.concurrent.ConcurrentLinkedQueue; import java.util.stream.Stream; @@ -25,9 +26,11 @@ public class EventBus { private Stream getMethods(Object subscriberObject) { return Stream.of(subscriberObject.getClass().getDeclaredMethods()) .filter(method -> method.isAnnotationPresent(Subscriber.class)) + .filter(method -> !Modifier.isPrivate(method.getModifiers())) .filter(method -> method.getReturnType().equals(Void.TYPE)) .filter(method -> method.getParameterCount() == 1) - .filter(method -> Event.class.isAssignableFrom(method.getParameterTypes()[0])); + .filter(method -> Event.class.isAssignableFrom(method.getParameterTypes()[0])) + .filter(method -> method.getParameterTypes()[0] != Event.class); } @SuppressWarnings("unchecked") @@ -63,25 +66,25 @@ public class EventBus { } public void post(Event event) { - eventQueue.add(event); + if (subscribes.containsKey(event.getClass())) { + eventQueue.add(event); + } } public void process() { Event event; while ((event = eventQueue.poll()) != null) { final Class type = event.getClass(); - if (subscribes.containsKey(type)) { - final List> pairs = subscribes.get(type); - for (Pair pair : pairs) { - try { - pair.getValue().invoke(pair.getKey(), event); - } catch (IllegalAccessException | InvocationTargetException e) { - log.error(MessageFormatter.format("Invoke method '{}#{}'", - pair.getKey().getClass().getSimpleName(), - pair.getValue().getName()).getMessage(), - e - ); - } + final List> pairs = subscribes.get(type); + for (Pair pair : pairs) { + try { + pair.getValue().invoke(pair.getKey(), event); + } catch (IllegalAccessException | InvocationTargetException e) { + log.error(MessageFormatter.format("Invoke method '{}#{}'", + pair.getKey().getClass().getSimpleName(), + pair.getValue().getName()).getMessage(), + e + ); } } } diff --git a/core/src/test/java/mc/core/TestEventBus.java b/core/src/test/java/mc/core/TestEventBus.java deleted file mode 100644 index beb19c8..0000000 --- a/core/src/test/java/mc/core/TestEventBus.java +++ /dev/null @@ -1,125 +0,0 @@ -package mc.core; - -import javafx.util.Pair; -import lombok.AllArgsConstructor; -import lombok.NoArgsConstructor; -import mc.core.eventbus.Event; -import mc.core.eventbus.EventBus; -import mc.core.eventbus.Subscriber; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.mockito.internal.util.reflection.Whitebox; - -import java.lang.reflect.Method; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.Queue; -import java.util.stream.Stream; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertSame; - -class TestEventBus { - private List resultList = new ArrayList<>(); - - @SuppressWarnings("unchecked") - private Map, List>> getEventBusFieldSubscribes() { - return (Map, List>>) - Whitebox.getInternalState(EventBus.getInstance(), "subscribes"); - } - - @BeforeEach - @SuppressWarnings("unchecked") - void before() { - getEventBusFieldSubscribes().clear(); - ((Queue) Whitebox.getInternalState(EventBus.getInstance(), "eventQueue")).clear(); - } - - - @Test - void testRegisterSubscribes() { - DumbEventHandler handler = new DumbEventHandler(); - EventBus.getInstance().registerSubscribes(handler); - - Map, List>> subscribes = getEventBusFieldSubscribes(); - assertEquals(1, subscribes.size()); - - List> pairs = subscribes.values().iterator().next(); - assertEquals(1, pairs.size()); - - Pair pair = pairs.get(0); - assertSame(handler, pair.getKey()); - assertEquals("corectSubscribe", pair.getValue().getName()); - } - - @Test - void testUnregisterSubscribes() { - DumbEventHandler handler = new DumbEventHandler(); - EventBus.getInstance().registerSubscribes(handler); - - EventBus.getInstance().unregisterSubscribes(handler); - - Map, List>> subscribes = getEventBusFieldSubscribes(); - assertEquals(0, subscribes.size()); - } - - @Test - @SuppressWarnings("unchecked") - void testPost() { - EventBus.getInstance().post(new DumbEvent()); - - Queue eventQueue = (Queue) Whitebox.getInternalState(EventBus.getInstance(), "eventQueue"); - assertEquals(1, eventQueue.size()); - } - - @Test - void testProcess() { - Stream.of(new DumbEventHandler("D1 "), new DumbEventHandler("D2 ")) - .forEach(handler -> EventBus.getInstance().registerSubscribes(handler)); - - Stream.of(new DumbEvent("message 1"), new DumbEvent("message 2")) - .forEach(event -> EventBus.getInstance().post(event)); - - EventBus.getInstance().process(); - - assertEquals(4, resultList.size()); - assertEquals("D1 message 1", resultList.get(0)); - assertEquals("D2 message 1", resultList.get(1)); - assertEquals("D1 message 2", resultList.get(2)); - assertEquals("D2 message 2", resultList.get(3)); - } - - @AllArgsConstructor - @NoArgsConstructor - private class DumbEvent implements Event { - String message; - } - - @AllArgsConstructor - @NoArgsConstructor - public class DumbEventHandler { - private String prefix = ""; - - @Subscriber - public void corectSubscribe(DumbEvent event) { - resultList.add(prefix + event.message); - } - - @Subscriber - public Object incorectSubscribeReturnType(DumbEvent event) { - return null; - } - - @Subscriber - public void incorrectSubscriberTypeParameter(Object object) { - } - - @Subscriber - public void incorrectSubscriberManyParameters(DumbEvent event, Object object) { - } - - public void someMethod() { - } - } -} diff --git a/core/src/test/java/mc/core/eventbus/EventBusTest.java b/core/src/test/java/mc/core/eventbus/EventBusTest.java new file mode 100644 index 0000000..4a12ece --- /dev/null +++ b/core/src/test/java/mc/core/eventbus/EventBusTest.java @@ -0,0 +1,274 @@ +package mc.core.eventbus; + +import javafx.util.Pair; +import lombok.AllArgsConstructor; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +import org.mockito.internal.util.reflection.Whitebox; + +import java.lang.reflect.Method; +import java.util.List; +import java.util.Map; +import java.util.Queue; +import java.util.stream.Stream; + +import static org.junit.jupiter.api.Assertions.*; + +class EventBusTest { + private EventBus eventBus = EventBus.getInstance(); + + @AfterEach + void after() { + getEventQueue().clear(); + getSubscribes().clear(); + } + + @Test + void testRegisterSubscribes() { + final AbstractDumpEventHandler handler = new AbstractDumpEventHandler() { + @SuppressWarnings("unused") + @Subscriber + public void corectSubscribe(DumbEvent event) { + } + }; + + eventBus.registerSubscribes(handler); + + assertEquals(1, getSubscribes().size()); + assertTrue(getSubscribes().containsKey(DumbEvent.class)); + assertNotNull(getSubscribes().get(DumbEvent.class)); + assertEquals(1, getSubscribes().get(DumbEvent.class).size()); + } + + @Test + void testRegisterSubscribesManyHandlers() { + final AbstractDumpEventHandler handler1 = new AbstractDumpEventHandler() { + @SuppressWarnings("unused") + @Subscriber + public void corectSubscribe(DumbEvent event) { + result += event.message; + } + }; + + final AbstractDumpEventHandler handler2 = new AbstractDumpEventHandler() { + @SuppressWarnings("unused") + @Subscriber + public void corectSubscribe(DumbEvent event) { + result += event.message; + } + }; + + eventBus.registerSubscribes(handler1); + eventBus.registerSubscribes(handler2); + + assertEquals(1, getSubscribes().size()); + assertTrue(getSubscribes().containsKey(DumbEvent.class)); + assertNotNull(getSubscribes().get(DumbEvent.class)); + assertEquals(2, getSubscribes().get(DumbEvent.class).size()); + } + + private static Stream streamIncorrectRegisterSubscribes() { + return Stream.of( + Arguments.of(new AbstractDumpEventHandler() { + @SuppressWarnings("unused") + public void incorectSubscribe(DumbEvent event) { + result += event.message; + } + }), + Arguments.of(new AbstractDumpEventHandler() { + @SuppressWarnings("unused") + @Subscriber + private void incorectSubscribe(DumbEvent event) { + result += event.message; + } + }), + Arguments.of(new AbstractDumpEventHandler() { + @SuppressWarnings("unused") + @Subscriber + public Object incorectSubscribe(DumbEvent event) { + result += event.message; + return null; + } + }), + Arguments.of(new AbstractDumpEventHandler() { + @SuppressWarnings("unused") + @Subscriber + public void incorectSubscribe(DumbEvent event, DumbEvent ev2) { + result += "Any"; + } + }), + Arguments.of(new AbstractDumpEventHandler() { + @SuppressWarnings("unused") + @Subscriber + public void incorectSubscribe(Object event) { + result += "Any"; + } + }), + Arguments.of(new AbstractDumpEventHandler() { + @SuppressWarnings("unused") + @Subscriber + public void incorectSubscribe(Event event) { + result += "Any"; + } + }) + ); + } + + @ParameterizedTest + @MethodSource("streamIncorrectRegisterSubscribes") + void testIncorrectRegisterSubscribes(AbstractDumpEventHandler incorrectHandler) { + eventBus.registerSubscribes(incorrectHandler); + + assertEquals(0, getSubscribes().size()); + } + + @Test + void testUnregisterSubscribes() { + final AbstractDumpEventHandler handler1 = new AbstractDumpEventHandler() { + @SuppressWarnings("unused") + @Subscriber + public void corectSubscribe1(DumbEvent event) { + result += event.message; + } + }; + + final AbstractDumpEventHandler handler2 = new AbstractDumpEventHandler() { + @SuppressWarnings("unused") + @Subscriber + public void corectSubscribe2(DumbEvent event) { + result += event.message; + } + }; + + eventBus.registerSubscribes(handler1); + eventBus.registerSubscribes(handler2); + + eventBus.unregisterSubscribes(handler1); + + assertEquals(1, getSubscribes().size()); + assertTrue(getSubscribes().containsKey(DumbEvent.class)); + assertNotNull(getSubscribes().get(DumbEvent.class)); + assertEquals(1, getSubscribes().get(DumbEvent.class).size()); + assertEquals("corectSubscribe2", getSubscribes().get(DumbEvent.class).get(0).getValue().getName()); + } + + @Test + void testUnregisterSubscribesNotExistsEvent() { + final AbstractDumpEventHandler handler1 = new AbstractDumpEventHandler() { + @SuppressWarnings("unused") + @Subscriber + public void corectSubscribe1(DumbEvent event) { + result += event.message; + } + }; + + eventBus.registerSubscribes(handler1); + + final AbstractDumpEventHandler handler2 = new AbstractDumpEventHandler() { + @SuppressWarnings("unused") + @Subscriber + public void corectSubscribe2(DumbEvent2 event) { + result += "Any"; + } + }; + + eventBus.unregisterSubscribes(handler2); + + assertEquals(1, getSubscribes().size()); + assertTrue(getSubscribes().containsKey(DumbEvent.class)); + assertNotNull(getSubscribes().get(DumbEvent.class)); + assertEquals(1, getSubscribes().get(DumbEvent.class).size()); + assertEquals("corectSubscribe1", getSubscribes().get(DumbEvent.class).get(0).getValue().getName()); + } + + @Test + void testUnregisterSubscribesLast() { + final AbstractDumpEventHandler handler = new AbstractDumpEventHandler() { + @SuppressWarnings("unused") + @Subscriber + public void corectSubscribe(DumbEvent event) { + result += event.message; + } + }; + + eventBus.registerSubscribes(handler); + eventBus.unregisterSubscribes(handler); + + assertEquals(0, getSubscribes().size()); + } + + @Test + void testPost() { + final AbstractDumpEventHandler handler = new AbstractDumpEventHandler() { + @SuppressWarnings("unused") + @Subscriber + public void corectSubscribe(DumbEvent event) { + result += event.message; + } + }; + + eventBus.registerSubscribes(handler); + final DumbEvent event = new DumbEvent("Hello?"); + eventBus.post(event); + eventBus.post(event); + eventBus.post(event); + + final Queue eventQueue = getEventQueue(); + assertEquals(3, eventQueue.size()); + assertEquals(event, eventQueue.peek()); + } + + @Test + void testPostNoHandlerEvent() { + final DumbEvent event = new DumbEvent("Hello?"); + eventBus.post(event); + + final Queue eventQueue = getEventQueue(); + assertTrue(eventQueue.isEmpty()); + } + + @Test + void testProcess() { + final AbstractDumpEventHandler handler = new AbstractDumpEventHandler() { + @SuppressWarnings("unused") + @Subscriber + public void corectSubscribe(DumbEvent event) { + result += event.message; + } + }; + + eventBus.registerSubscribes(handler); + eventBus.post(new DumbEvent("Hello?")); + eventBus.process(); + + assertTrue(getEventQueue().isEmpty()); + assertEquals("Hello?", handler.result); + } + + @SuppressWarnings("unchecked") + private Map, List>> getSubscribes() { + return (Map, List>>) + Whitebox.getInternalState(eventBus, "subscribes"); + } + + @SuppressWarnings("unchecked") + private Queue getEventQueue() { + return (Queue) + Whitebox.getInternalState(eventBus, "eventQueue"); + } + + @AllArgsConstructor + private class DumbEvent implements Event { + String message; + } + + private class DumbEvent2 implements Event { + } + + private static abstract class AbstractDumpEventHandler { + String result = ""; + } +} \ No newline at end of file