1 package com.atlassian.plugin.event.impl;
2
3 import com.atlassian.event.api.EventListener;
4 import com.atlassian.event.api.EventPublisher;
5 import com.atlassian.plugin.event.PluginEventListener;
6 import org.junit.After;
7 import org.junit.Before;
8 import org.junit.Test;
9 import org.junit.runner.RunWith;
10 import org.mockito.Mock;
11 import org.mockito.runners.MockitoJUnitRunner;
12
13 import java.lang.reflect.Method;
14
15 import static org.hamcrest.core.IsNull.notNullValue;
16 import static org.junit.Assert.assertEquals;
17 import static org.junit.Assert.assertThat;
18 import static org.junit.Assert.fail;
19 import static org.mockito.Matchers.anyObject;
20 import static org.mockito.Matchers.anyString;
21 import static org.mockito.Mockito.mock;
22 import static org.mockito.Mockito.never;
23 import static org.mockito.Mockito.times;
24 import static org.mockito.Mockito.verify;
25
26 @RunWith(MockitoJUnitRunner.class)
27 public class TestDefaultPluginEventManager {
28 private final Object someObject = new Object();
29 private final String someString = "string";
30
31 @Mock
32 private MethodTestListener methodTestListener;
33
34 private DefaultPluginEventManager defaultPluginEventManager;
35
36 @Before
37 public void createDefaultPluginEventManager() {
38 defaultPluginEventManager = new DefaultPluginEventManager();
39 assertThat(defaultPluginEventManager.getEventPublisher(), notNullValue(EventPublisher.class));
40 }
41
42 @After
43 public void discardDefaultPluginEventManager() {
44 defaultPluginEventManager = null;
45 }
46
47 @Test
48 public void broadcastCallsListenerChannelForType() {
49 defaultPluginEventManager.register(methodTestListener);
50 defaultPluginEventManager.broadcast(someObject);
51 verify(methodTestListener).channel(someObject);
52 verify(methodTestListener, never()).channel(anyString());
53 }
54
55 @Test
56 public void broadcastCallsListenerChannelForSupertype() {
57 final Integer someInteger = 0;
58 defaultPluginEventManager.register(methodTestListener);
59 defaultPluginEventManager.broadcast(someInteger);
60 verify(methodTestListener).channel(someInteger);
61 verify(methodTestListener, never()).channel(anyString());
62 }
63
64 @Test
65 public void broadcastCallsListenerChannelForTypeAndSupertype() {
66 defaultPluginEventManager.register(methodTestListener);
67 defaultPluginEventManager.broadcast(someString);
68
69 verify(methodTestListener).channel((Object) someString);
70 verify(methodTestListener).channel(someString);
71 }
72
73 @Test
74 public void listenerCalledOnceEvenIfRegisteredTwice() {
75 defaultPluginEventManager.register(methodTestListener);
76 defaultPluginEventManager.register(methodTestListener);
77 defaultPluginEventManager.broadcast(someObject);
78 verify(methodTestListener).channel(someObject);
79 verify(methodTestListener, never()).channel(anyString());
80 }
81
82 @Test
83 public void registerUnmatchingListenerThrows() {
84 BadListener badListener = mock(BadListener.class);
85 try {
86 defaultPluginEventManager.register(badListener);
87 fail();
88 } catch (IllegalArgumentException ex) {
89
90 }
91 verify(badListener, never()).someMethod();
92 }
93
94 @Test
95 public void customSelectorMatchesAndOverridesDefault() {
96 ListenerMethodSelector onEventSelector = new ListenerMethodSelector() {
97 public boolean isListenerMethod(Method method) {
98 return "onEvent".equals(method.getName());
99 }
100 };
101 defaultPluginEventManager = new DefaultPluginEventManager(onEventSelector);
102 defaultPluginEventManager.register(methodTestListener);
103 defaultPluginEventManager.broadcast(someString);
104 verify(methodTestListener).onEvent(someString);
105 verify(methodTestListener, never()).channel(anyObject());
106 verify(methodTestListener, never()).channel(anyString());
107 }
108
109 @Test
110 public void overlappingSelectorsBothMatch() {
111 ListenerMethodSelector firstSelector = new MethodNameListenerMethodSelector();
112 ListenerMethodSelector secondSelector = new MethodNameListenerMethodSelector();
113 defaultPluginEventManager = new DefaultPluginEventManager(firstSelector, secondSelector);
114 defaultPluginEventManager.register(methodTestListener);
115 defaultPluginEventManager.broadcast(someObject);
116 verify(methodTestListener, times(2)).channel(someObject);
117 }
118
119 @Test
120 public void broadcastCallsAnnotatedMethods() {
121
122
123 AnnotationTestListener listener = new AnnotationTestListener();
124 defaultPluginEventManager.register(listener);
125 defaultPluginEventManager.broadcast(someObject);
126 assertEquals(1, listener.eventListenerCalled);
127 assertEquals(1, listener.pluginEventListenerCalled);
128 }
129
130 @Test
131 public void unregisterStopsBroadcastSendingEvents() {
132 defaultPluginEventManager.register(methodTestListener);
133 defaultPluginEventManager.broadcast(someObject);
134 verify(methodTestListener).channel(someObject);
135 defaultPluginEventManager.unregister(methodTestListener);
136 defaultPluginEventManager.broadcast(someObject);
137
138 verify(methodTestListener).channel(someObject);
139 }
140
141 @Test(expected = IllegalArgumentException.class)
142 public void registerNullThrows() {
143 defaultPluginEventManager.register(null);
144 }
145
146 @Test(expected = IllegalArgumentException.class)
147 public void unregisterNullThrows() {
148 defaultPluginEventManager.unregister(null);
149 }
150
151 public static class AnnotationTestListener {
152 int pluginEventListenerCalled = 0;
153 int eventListenerCalled = 0;
154
155 @PluginEventListener
156 public void doEventOld(Object obj) {
157 ++pluginEventListenerCalled;
158 }
159
160 @EventListener
161 public void doEventNew(Object obj) {
162 ++eventListenerCalled;
163 }
164 }
165
166 public static class MethodTestListener {
167 public void channel(Object object) {
168 }
169
170 public void channel(String string) {
171 }
172
173 public void onEvent(String string) {
174 }
175 }
176
177 public static class BadListener {
178 public void someMethod() {
179 }
180 }
181 }