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
17package com.google.common.eventbus.outside;
18
19import static com.google.common.truth.Truth.assertThat;
20
21import com.google.common.collect.Lists;
22import com.google.common.eventbus.EventBus;
23import com.google.common.eventbus.Subscribe;
24
25import junit.framework.TestCase;
26
27import 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 */
35public class AnnotatedSubscriberFinderTests {
36
37  private static final Object EVENT = new Object();
38
39  abstract static class AbstractEventBusTest<H> extends TestCase {
40    abstract H createSubscriber();
41
42    private H subscriber;
43
44    H getSubscriber() {
45      return subscriber;
46    }
47
48    @Override
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
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
71      public void notASubscriber(Object o) {
72        nonSubscriberEvents.add(o);
73      }
74
75      @Subscribe
76      public void subscriber(Object o) {
77        subscriberEvents.add(o);
78      }
79    }
80
81    public void testNonSubscriber() {
82      assertThat(getSubscriber().nonSubscriberEvents).isEmpty();
83    }
84
85    public void testSubscriber() {
86      assertThat(getSubscriber().subscriberEvents).has().item(EVENT);
87    }
88
89    @Override
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
99      public abstract void overriddenAndAnnotatedInSubclass(Object o);
100
101      @Subscribe
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
111      public void overriddenAndAnnotatedInSubclass(Object o) {
112        overriddenAndAnnotatedInSubclassEvents.add(o);
113      }
114
115      @Override
116      public void overriddenInSubclass(Object o) {
117        overriddenInSubclassEvents.add(o);
118      }
119    }
120
121    public void testOverriddenAndAnnotatedInSubclass() {
122      assertThat(getSubscriber().overriddenAndAnnotatedInSubclassEvents).has().item(EVENT);
123    }
124
125    public void testOverriddenNotAnnotatedInSubclass() {
126      assertThat(getSubscriber().overriddenInSubclassEvents).has().item(EVENT);
127    }
128
129    @Override
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
146      public void notOverriddenInSubclass(Object o) {
147        notOverriddenInSubclassEvents.add(o);
148      }
149
150      @Subscribe
151      public void overriddenNotAnnotatedInSubclass(Object o) {
152        overriddenNotAnnotatedInSubclassEvents.add(o);
153      }
154
155      @Subscribe
156      public void overriddenAndAnnotatedInSubclass(Object o) {
157        overriddenAndAnnotatedInSubclassEvents.add(o);
158      }
159
160      @Subscribe
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
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
179      public void overriddenNotAnnotatedInSubclass(Object o) {
180        super.overriddenNotAnnotatedInSubclass(o);
181      }
182
183      @Subscribe
184      @Override
185      public void overriddenAndAnnotatedInSubclass(Object o) {
186        super.overriddenAndAnnotatedInSubclass(o);
187      }
188
189      @Override
190      public void differentlyOverriddenNotAnnotatedInSubclass(Object o) {
191        differentlyOverriddenNotAnnotatedInSubclassGoodEvents.add(o);
192      }
193
194      @Subscribe
195      @Override
196      public void differentlyOverriddenAnnotatedInSubclass(Object o) {
197        differentlyOverriddenAnnotatedInSubclassGoodEvents.add(o);
198      }
199    }
200
201    public void testNotOverriddenInSubclass() {
202      assertThat(getSubscriber().notOverriddenInSubclassEvents).has().item(EVENT);
203    }
204
205    public void testOverriddenNotAnnotatedInSubclass() {
206      assertThat(getSubscriber().overriddenNotAnnotatedInSubclassEvents).has().item(EVENT);
207    }
208
209    public void testDifferentlyOverriddenNotAnnotatedInSubclass() {
210      assertThat(getSubscriber().differentlyOverriddenNotAnnotatedInSubclassGoodEvents)
211          .has().item(EVENT);
212      assertThat(getSubscriber().differentlyOverriddenNotAnnotatedInSubclassBadEvents).isEmpty();
213    }
214
215    public void testOverriddenAndAnnotatedInSubclass() {
216      assertThat(getSubscriber().overriddenAndAnnotatedInSubclassEvents).has().item(EVENT);
217    }
218
219    public void testDifferentlyOverriddenAndAnnotatedInSubclass() {
220      assertThat(getSubscriber().differentlyOverriddenAnnotatedInSubclassGoodEvents)
221          .has().item(EVENT);
222      assertThat(getSubscriber().differentlyOverriddenAnnotatedInSubclassBadEvents).isEmpty();
223    }
224
225    @Override
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 {
234      public abstract void overriddenInSubclassNowhereAnnotated(Object o);
235
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
244      public void overriddenInSubclassNowhereAnnotated(Object o) {
245        overriddenInSubclassNowhereAnnotatedEvents.add(o);
246      }
247
248      @Subscribe
249      @Override
250      public void overriddenAndAnnotatedInSubclass(Object o) {
251        overriddenAndAnnotatedInSubclassEvents.add(o);
252      }
253    }
254
255    public void testOverriddenAndAnnotatedInSubclass() {
256      assertThat(getSubscriber().overriddenAndAnnotatedInSubclassEvents).has().item(EVENT);
257    }
258
259    public void testOverriddenInSubclassNowhereAnnotated() {
260      assertThat(getSubscriber().overriddenInSubclassNowhereAnnotatedEvents).isEmpty();
261    }
262
263    @Override
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
276      public void neitherOverriddenNorAnnotated(Object o) {
277        neitherOverriddenNorAnnotatedEvents.add(o);
278      }
279
280      public void overriddenInSubclassNowhereAnnotated(Object o) {
281        overriddenInSubclassNowhereAnnotatedEvents.add(o);
282      }
283
284      public void overriddenAndAnnotatedInSubclass(Object o) {
285        overriddenAndAnnotatedInSubclassEvents.add(o);
286      }
287    }
288
289    static class SubClass extends SuperClass {
290      @Override
291      public void overriddenInSubclassNowhereAnnotated(Object o) {
292        super.overriddenInSubclassNowhereAnnotated(o);
293      }
294
295      @Subscribe
296      @Override
297      public void overriddenAndAnnotatedInSubclass(Object o) {
298        super.overriddenAndAnnotatedInSubclass(o);
299      }
300    }
301
302    public void testNeitherOverriddenNorAnnotated() {
303      assertThat(getSubscriber().neitherOverriddenNorAnnotatedEvents).isEmpty();
304    }
305
306    public void testOverriddenInSubclassNowhereAnnotated() {
307      assertThat(getSubscriber().overriddenInSubclassNowhereAnnotatedEvents).isEmpty();
308    }
309
310    public void testOverriddenAndAnnotatedInSubclass() {
311      assertThat(getSubscriber().overriddenAndAnnotatedInSubclassEvents).has().item(EVENT);
312    }
313
314    @Override
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
324      void annotatedIn1(Object o);
325
326      @Subscribe
327      void annotatedIn1And2(Object o);
328
329      @Subscribe
330      void annotatedIn1And2AndClass(Object o);
331
332      void declaredIn1AnnotatedIn2(Object o);
333
334      void declaredIn1AnnotatedInClass(Object o);
335
336      void nowhereAnnotated(Object o);
337    }
338
339    interface Interface2 extends Interface1 {
340      @Override
341      @Subscribe
342      void declaredIn1AnnotatedIn2(Object o);
343
344      @Override
345      @Subscribe
346      void annotatedIn1And2(Object o);
347
348      @Override
349      @Subscribe
350      void annotatedIn1And2AndClass(Object o);
351
352      void declaredIn2AnnotatedInClass(Object o);
353
354      @Subscribe
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
369      public void annotatedIn1(Object o) {
370        annotatedIn1Events.add(o);
371      }
372
373      @Subscribe
374      @Override
375      public void declaredIn1AnnotatedInClass(Object o) {
376        declaredIn1AnnotatedInClassEvents.add(o);
377      }
378
379      @Override
380      public void declaredIn1AnnotatedIn2(Object o) {
381        declaredIn1AnnotatedIn2Events.add(o);
382      }
383
384      @Override
385      public void annotatedIn1And2(Object o) {
386        annotatedIn1And2Events.add(o);
387      }
388
389      @Subscribe
390      @Override
391      public void annotatedIn1And2AndClass(Object o) {
392        annotatedIn1And2AndClassEvents.add(o);
393      }
394
395      @Subscribe
396      @Override
397      public void declaredIn2AnnotatedInClass(Object o) {
398        declaredIn2AnnotatedInClassEvents.add(o);
399      }
400
401      @Override
402      public void annotatedIn2(Object o) {
403        annotatedIn2Events.add(o);
404      }
405
406      @Override
407      public void nowhereAnnotated(Object o) {
408        nowhereAnnotatedEvents.add(o);
409      }
410    }
411
412    public void testAnnotatedIn1() {
413      assertThat(getSubscriber().annotatedIn1Events).has().item(EVENT);
414    }
415
416    public void testAnnotatedIn2() {
417      assertThat(getSubscriber().annotatedIn2Events).has().item(EVENT);
418    }
419
420    public void testAnnotatedIn1And2() {
421      assertThat(getSubscriber().annotatedIn1And2Events).has().item(EVENT);
422    }
423
424    public void testAnnotatedIn1And2AndClass() {
425      assertThat(getSubscriber().annotatedIn1And2AndClassEvents).has().item(EVENT);
426    }
427
428    public void testDeclaredIn1AnnotatedIn2() {
429      assertThat(getSubscriber().declaredIn1AnnotatedIn2Events).has().item(EVENT);
430    }
431
432    public void testDeclaredIn1AnnotatedInClass() {
433      assertThat(getSubscriber().declaredIn1AnnotatedInClassEvents).has().item(EVENT);
434    }
435
436    public void testDeclaredIn2AnnotatedInClass() {
437      assertThat(getSubscriber().declaredIn2AnnotatedInClassEvents).has().item(EVENT);
438    }
439
440    public void testNowhereAnnotated() {
441      assertThat(getSubscriber().nowhereAnnotatedEvents).isEmpty();
442    }
443
444    @Override
445    SubscriberClass createSubscriber() {
446      return new SubscriberClass();
447    }
448  }
449}
450