View Javadoc

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