View Javadoc

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