1 /*
2  * Copyright (C) 2012 The Guava Authors
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.google.common.eventbus.outside;
18 
19 import static com.google.common.truth.Truth.assertThat;
20 
21 import com.google.common.collect.Lists;
22 import com.google.common.eventbus.EventBus;
23 import com.google.common.eventbus.Subscribe;
24 
25 import junit.framework.TestCase;
26 
27 import java.util.List;
28 
29 /**
30  * Test that EventBus finds the correct subscribers.
31  *
32  * This test must be outside the c.g.c.eventbus package to test correctly.
33  * @author Louis Wasserman
34  */
35 public class AnnotatedSubscriberFinderTests {
36 
37   private static final Object EVENT = new Object();
38 
39   abstract static class AbstractEventBusTest<H> extends TestCase {
createSubscriber()40     abstract H createSubscriber();
41 
42     private H subscriber;
43 
getSubscriber()44     H getSubscriber() {
45       return subscriber;
46     }
47 
48     @Override
setUp()49     protected void setUp() throws Exception {
50       subscriber = createSubscriber();
51       EventBus bus = new EventBus();
52       bus.register(subscriber);
53       bus.post(EVENT);
54     }
55 
56     @Override
tearDown()57     protected void tearDown() throws Exception {
58       subscriber = null;
59     }
60   }
61 
62   /*
63    * We break the tests up based on whether they are annotated or abstract in the superclass.
64    */
65   public static class BaseSubscriberFinderTest extends
66       AbstractEventBusTest<BaseSubscriberFinderTest.Subscriber> {
67     static class Subscriber {
68       final List<Object> nonSubscriberEvents = Lists.newArrayList();
69       final List<Object> subscriberEvents = Lists.newArrayList();
70 
notASubscriber(Object o)71       public void notASubscriber(Object o) {
72         nonSubscriberEvents.add(o);
73       }
74 
75       @Subscribe
subscriber(Object o)76       public void subscriber(Object o) {
77         subscriberEvents.add(o);
78       }
79     }
80 
testNonSubscriber()81     public void testNonSubscriber() {
82       assertThat(getSubscriber().nonSubscriberEvents).isEmpty();
83     }
84 
testSubscriber()85     public void testSubscriber() {
86       assertThat(getSubscriber().subscriberEvents).has().item(EVENT);
87     }
88 
89     @Override
createSubscriber()90     Subscriber createSubscriber() {
91       return new Subscriber();
92     }
93   }
94 
95   public static class AnnotatedAndAbstractInSuperclassTest extends
96       AbstractEventBusTest<AnnotatedAndAbstractInSuperclassTest.SubClass> {
97     abstract static class SuperClass {
98       @Subscribe
overriddenAndAnnotatedInSubclass(Object o)99       public abstract void overriddenAndAnnotatedInSubclass(Object o);
100 
101       @Subscribe
overriddenInSubclass(Object o)102       public abstract void overriddenInSubclass(Object o);
103     }
104 
105     static class SubClass extends SuperClass {
106       final List<Object> overriddenAndAnnotatedInSubclassEvents = Lists.newArrayList();
107       final List<Object> overriddenInSubclassEvents = Lists.newArrayList();
108 
109       @Subscribe
110       @Override
overriddenAndAnnotatedInSubclass(Object o)111       public void overriddenAndAnnotatedInSubclass(Object o) {
112         overriddenAndAnnotatedInSubclassEvents.add(o);
113       }
114 
115       @Override
overriddenInSubclass(Object o)116       public void overriddenInSubclass(Object o) {
117         overriddenInSubclassEvents.add(o);
118       }
119     }
120 
testOverriddenAndAnnotatedInSubclass()121     public void testOverriddenAndAnnotatedInSubclass() {
122       assertThat(getSubscriber().overriddenAndAnnotatedInSubclassEvents).has().item(EVENT);
123     }
124 
testOverriddenNotAnnotatedInSubclass()125     public void testOverriddenNotAnnotatedInSubclass() {
126       assertThat(getSubscriber().overriddenInSubclassEvents).has().item(EVENT);
127     }
128 
129     @Override
createSubscriber()130     SubClass createSubscriber() {
131       return new SubClass();
132     }
133   }
134 
135   public static class AnnotatedNotAbstractInSuperclassTest extends
136       AbstractEventBusTest<AnnotatedNotAbstractInSuperclassTest.SubClass> {
137     static class SuperClass {
138       final List<Object> notOverriddenInSubclassEvents = Lists.newArrayList();
139       final List<Object> overriddenNotAnnotatedInSubclassEvents = Lists.newArrayList();
140       final List<Object> overriddenAndAnnotatedInSubclassEvents = Lists.newArrayList();
141       final List<Object> differentlyOverriddenNotAnnotatedInSubclassBadEvents = Lists
142           .newArrayList();
143       final List<Object> differentlyOverriddenAnnotatedInSubclassBadEvents = Lists.newArrayList();
144 
145       @Subscribe
notOverriddenInSubclass(Object o)146       public void notOverriddenInSubclass(Object o) {
147         notOverriddenInSubclassEvents.add(o);
148       }
149 
150       @Subscribe
overriddenNotAnnotatedInSubclass(Object o)151       public void overriddenNotAnnotatedInSubclass(Object o) {
152         overriddenNotAnnotatedInSubclassEvents.add(o);
153       }
154 
155       @Subscribe
overriddenAndAnnotatedInSubclass(Object o)156       public void overriddenAndAnnotatedInSubclass(Object o) {
157         overriddenAndAnnotatedInSubclassEvents.add(o);
158       }
159 
160       @Subscribe
differentlyOverriddenNotAnnotatedInSubclass(Object o)161       public void differentlyOverriddenNotAnnotatedInSubclass(Object o) {
162         // the subclass overrides this and does *not* call super.dONAIS(o)
163         differentlyOverriddenNotAnnotatedInSubclassBadEvents.add(o);
164       }
165 
166       @Subscribe
differentlyOverriddenAnnotatedInSubclass(Object o)167       public void differentlyOverriddenAnnotatedInSubclass(Object o) {
168         // the subclass overrides this and does *not* call super.dOAIS(o)
169         differentlyOverriddenAnnotatedInSubclassBadEvents.add(o);
170       }
171     }
172 
173     static class SubClass extends SuperClass {
174       final List<Object> differentlyOverriddenNotAnnotatedInSubclassGoodEvents = Lists
175           .newArrayList();
176       final List<Object> differentlyOverriddenAnnotatedInSubclassGoodEvents = Lists.newArrayList();
177 
178       @Override
overriddenNotAnnotatedInSubclass(Object o)179       public void overriddenNotAnnotatedInSubclass(Object o) {
180         super.overriddenNotAnnotatedInSubclass(o);
181       }
182 
183       @Subscribe
184       @Override
overriddenAndAnnotatedInSubclass(Object o)185       public void overriddenAndAnnotatedInSubclass(Object o) {
186         super.overriddenAndAnnotatedInSubclass(o);
187       }
188 
189       @Override
differentlyOverriddenNotAnnotatedInSubclass(Object o)190       public void differentlyOverriddenNotAnnotatedInSubclass(Object o) {
191         differentlyOverriddenNotAnnotatedInSubclassGoodEvents.add(o);
192       }
193 
194       @Subscribe
195       @Override
differentlyOverriddenAnnotatedInSubclass(Object o)196       public void differentlyOverriddenAnnotatedInSubclass(Object o) {
197         differentlyOverriddenAnnotatedInSubclassGoodEvents.add(o);
198       }
199     }
200 
testNotOverriddenInSubclass()201     public void testNotOverriddenInSubclass() {
202       assertThat(getSubscriber().notOverriddenInSubclassEvents).has().item(EVENT);
203     }
204 
testOverriddenNotAnnotatedInSubclass()205     public void testOverriddenNotAnnotatedInSubclass() {
206       assertThat(getSubscriber().overriddenNotAnnotatedInSubclassEvents).has().item(EVENT);
207     }
208 
testDifferentlyOverriddenNotAnnotatedInSubclass()209     public void testDifferentlyOverriddenNotAnnotatedInSubclass() {
210       assertThat(getSubscriber().differentlyOverriddenNotAnnotatedInSubclassGoodEvents)
211           .has().item(EVENT);
212       assertThat(getSubscriber().differentlyOverriddenNotAnnotatedInSubclassBadEvents).isEmpty();
213     }
214 
testOverriddenAndAnnotatedInSubclass()215     public void testOverriddenAndAnnotatedInSubclass() {
216       assertThat(getSubscriber().overriddenAndAnnotatedInSubclassEvents).has().item(EVENT);
217     }
218 
testDifferentlyOverriddenAndAnnotatedInSubclass()219     public void testDifferentlyOverriddenAndAnnotatedInSubclass() {
220       assertThat(getSubscriber().differentlyOverriddenAnnotatedInSubclassGoodEvents)
221           .has().item(EVENT);
222       assertThat(getSubscriber().differentlyOverriddenAnnotatedInSubclassBadEvents).isEmpty();
223     }
224 
225     @Override
createSubscriber()226     SubClass createSubscriber() {
227       return new SubClass();
228     }
229   }
230 
231   public static class AbstractNotAnnotatedInSuperclassTest extends
232       AbstractEventBusTest<AbstractNotAnnotatedInSuperclassTest.SubClass> {
233     abstract static class SuperClass {
overriddenInSubclassNowhereAnnotated(Object o)234       public abstract void overriddenInSubclassNowhereAnnotated(Object o);
235 
overriddenAndAnnotatedInSubclass(Object o)236       public abstract void overriddenAndAnnotatedInSubclass(Object o);
237     }
238 
239     static class SubClass extends SuperClass {
240       final List<Object> overriddenInSubclassNowhereAnnotatedEvents = Lists.newArrayList();
241       final List<Object> overriddenAndAnnotatedInSubclassEvents = Lists.newArrayList();
242 
243       @Override
overriddenInSubclassNowhereAnnotated(Object o)244       public void overriddenInSubclassNowhereAnnotated(Object o) {
245         overriddenInSubclassNowhereAnnotatedEvents.add(o);
246       }
247 
248       @Subscribe
249       @Override
overriddenAndAnnotatedInSubclass(Object o)250       public void overriddenAndAnnotatedInSubclass(Object o) {
251         overriddenAndAnnotatedInSubclassEvents.add(o);
252       }
253     }
254 
testOverriddenAndAnnotatedInSubclass()255     public void testOverriddenAndAnnotatedInSubclass() {
256       assertThat(getSubscriber().overriddenAndAnnotatedInSubclassEvents).has().item(EVENT);
257     }
258 
testOverriddenInSubclassNowhereAnnotated()259     public void testOverriddenInSubclassNowhereAnnotated() {
260       assertThat(getSubscriber().overriddenInSubclassNowhereAnnotatedEvents).isEmpty();
261     }
262 
263     @Override
createSubscriber()264     SubClass createSubscriber() {
265       return new SubClass();
266     }
267   }
268 
269   public static class NeitherAbstractNorAnnotatedInSuperclassTest extends
270       AbstractEventBusTest<NeitherAbstractNorAnnotatedInSuperclassTest.SubClass> {
271     static class SuperClass {
272       final List<Object> neitherOverriddenNorAnnotatedEvents = Lists.newArrayList();
273       final List<Object> overriddenInSubclassNowhereAnnotatedEvents = Lists.newArrayList();
274       final List<Object> overriddenAndAnnotatedInSubclassEvents = Lists.newArrayList();
275 
neitherOverriddenNorAnnotated(Object o)276       public void neitherOverriddenNorAnnotated(Object o) {
277         neitherOverriddenNorAnnotatedEvents.add(o);
278       }
279 
overriddenInSubclassNowhereAnnotated(Object o)280       public void overriddenInSubclassNowhereAnnotated(Object o) {
281         overriddenInSubclassNowhereAnnotatedEvents.add(o);
282       }
283 
overriddenAndAnnotatedInSubclass(Object o)284       public void overriddenAndAnnotatedInSubclass(Object o) {
285         overriddenAndAnnotatedInSubclassEvents.add(o);
286       }
287     }
288 
289     static class SubClass extends SuperClass {
290       @Override
overriddenInSubclassNowhereAnnotated(Object o)291       public void overriddenInSubclassNowhereAnnotated(Object o) {
292         super.overriddenInSubclassNowhereAnnotated(o);
293       }
294 
295       @Subscribe
296       @Override
overriddenAndAnnotatedInSubclass(Object o)297       public void overriddenAndAnnotatedInSubclass(Object o) {
298         super.overriddenAndAnnotatedInSubclass(o);
299       }
300     }
301 
testNeitherOverriddenNorAnnotated()302     public void testNeitherOverriddenNorAnnotated() {
303       assertThat(getSubscriber().neitherOverriddenNorAnnotatedEvents).isEmpty();
304     }
305 
testOverriddenInSubclassNowhereAnnotated()306     public void testOverriddenInSubclassNowhereAnnotated() {
307       assertThat(getSubscriber().overriddenInSubclassNowhereAnnotatedEvents).isEmpty();
308     }
309 
testOverriddenAndAnnotatedInSubclass()310     public void testOverriddenAndAnnotatedInSubclass() {
311       assertThat(getSubscriber().overriddenAndAnnotatedInSubclassEvents).has().item(EVENT);
312     }
313 
314     @Override
createSubscriber()315     SubClass createSubscriber() {
316       return new SubClass();
317     }
318   }
319 
320   public static class DeepInterfaceTest extends
321       AbstractEventBusTest<DeepInterfaceTest.SubscriberClass> {
322     interface Interface1 {
323       @Subscribe
annotatedIn1(Object o)324       void annotatedIn1(Object o);
325 
326       @Subscribe
annotatedIn1And2(Object o)327       void annotatedIn1And2(Object o);
328 
329       @Subscribe
annotatedIn1And2AndClass(Object o)330       void annotatedIn1And2AndClass(Object o);
331 
declaredIn1AnnotatedIn2(Object o)332       void declaredIn1AnnotatedIn2(Object o);
333 
declaredIn1AnnotatedInClass(Object o)334       void declaredIn1AnnotatedInClass(Object o);
335 
nowhereAnnotated(Object o)336       void nowhereAnnotated(Object o);
337     }
338 
339     interface Interface2 extends Interface1 {
340       @Override
341       @Subscribe
declaredIn1AnnotatedIn2(Object o)342       void declaredIn1AnnotatedIn2(Object o);
343 
344       @Override
345       @Subscribe
annotatedIn1And2(Object o)346       void annotatedIn1And2(Object o);
347 
348       @Override
349       @Subscribe
annotatedIn1And2AndClass(Object o)350       void annotatedIn1And2AndClass(Object o);
351 
declaredIn2AnnotatedInClass(Object o)352       void declaredIn2AnnotatedInClass(Object o);
353 
354       @Subscribe
annotatedIn2(Object o)355       void annotatedIn2(Object o);
356     }
357 
358     static class SubscriberClass implements Interface2 {
359       final List<Object> annotatedIn1Events = Lists.newArrayList();
360       final List<Object> annotatedIn1And2Events = Lists.newArrayList();
361       final List<Object> annotatedIn1And2AndClassEvents = Lists.newArrayList();
362       final List<Object> declaredIn1AnnotatedIn2Events = Lists.newArrayList();
363       final List<Object> declaredIn1AnnotatedInClassEvents = Lists.newArrayList();
364       final List<Object> declaredIn2AnnotatedInClassEvents = Lists.newArrayList();
365       final List<Object> annotatedIn2Events = Lists.newArrayList();
366       final List<Object> nowhereAnnotatedEvents = Lists.newArrayList();
367 
368       @Override
annotatedIn1(Object o)369       public void annotatedIn1(Object o) {
370         annotatedIn1Events.add(o);
371       }
372 
373       @Subscribe
374       @Override
declaredIn1AnnotatedInClass(Object o)375       public void declaredIn1AnnotatedInClass(Object o) {
376         declaredIn1AnnotatedInClassEvents.add(o);
377       }
378 
379       @Override
declaredIn1AnnotatedIn2(Object o)380       public void declaredIn1AnnotatedIn2(Object o) {
381         declaredIn1AnnotatedIn2Events.add(o);
382       }
383 
384       @Override
annotatedIn1And2(Object o)385       public void annotatedIn1And2(Object o) {
386         annotatedIn1And2Events.add(o);
387       }
388 
389       @Subscribe
390       @Override
annotatedIn1And2AndClass(Object o)391       public void annotatedIn1And2AndClass(Object o) {
392         annotatedIn1And2AndClassEvents.add(o);
393       }
394 
395       @Subscribe
396       @Override
declaredIn2AnnotatedInClass(Object o)397       public void declaredIn2AnnotatedInClass(Object o) {
398         declaredIn2AnnotatedInClassEvents.add(o);
399       }
400 
401       @Override
annotatedIn2(Object o)402       public void annotatedIn2(Object o) {
403         annotatedIn2Events.add(o);
404       }
405 
406       @Override
nowhereAnnotated(Object o)407       public void nowhereAnnotated(Object o) {
408         nowhereAnnotatedEvents.add(o);
409       }
410     }
411 
testAnnotatedIn1()412     public void testAnnotatedIn1() {
413       assertThat(getSubscriber().annotatedIn1Events).has().item(EVENT);
414     }
415 
testAnnotatedIn2()416     public void testAnnotatedIn2() {
417       assertThat(getSubscriber().annotatedIn2Events).has().item(EVENT);
418     }
419 
testAnnotatedIn1And2()420     public void testAnnotatedIn1And2() {
421       assertThat(getSubscriber().annotatedIn1And2Events).has().item(EVENT);
422     }
423 
testAnnotatedIn1And2AndClass()424     public void testAnnotatedIn1And2AndClass() {
425       assertThat(getSubscriber().annotatedIn1And2AndClassEvents).has().item(EVENT);
426     }
427 
testDeclaredIn1AnnotatedIn2()428     public void testDeclaredIn1AnnotatedIn2() {
429       assertThat(getSubscriber().declaredIn1AnnotatedIn2Events).has().item(EVENT);
430     }
431 
testDeclaredIn1AnnotatedInClass()432     public void testDeclaredIn1AnnotatedInClass() {
433       assertThat(getSubscriber().declaredIn1AnnotatedInClassEvents).has().item(EVENT);
434     }
435 
testDeclaredIn2AnnotatedInClass()436     public void testDeclaredIn2AnnotatedInClass() {
437       assertThat(getSubscriber().declaredIn2AnnotatedInClassEvents).has().item(EVENT);
438     }
439 
testNowhereAnnotated()440     public void testNowhereAnnotated() {
441       assertThat(getSubscriber().nowhereAnnotatedEvents).isEmpty();
442     }
443 
444     @Override
createSubscriber()445     SubscriberClass createSubscriber() {
446       return new SubscriberClass();
447     }
448   }
449 }
450