• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2007 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;
18 
19 import static com.google.common.truth.Truth.assertThat;
20 import static org.junit.Assert.assertThrows;
21 
22 import com.google.common.testing.EqualsTester;
23 import java.lang.reflect.InvocationTargetException;
24 import java.lang.reflect.Method;
25 import junit.framework.TestCase;
26 import org.checkerframework.checker.nullness.qual.Nullable;
27 
28 /**
29  * Tests for {@link Subscriber}.
30  *
31  * @author Cliff Biffle
32  * @author Colin Decker
33  */
34 public class SubscriberTest extends TestCase {
35 
36   private static final Object FIXTURE_ARGUMENT = new Object();
37 
38   private EventBus bus;
39   private boolean methodCalled;
40   private @Nullable Object methodArgument;
41 
42   @Override
setUp()43   protected void setUp() throws Exception {
44     bus = new EventBus();
45     methodCalled = false;
46     methodArgument = null;
47   }
48 
testCreate()49   public void testCreate() {
50     Subscriber s1 = Subscriber.create(bus, this, getTestSubscriberMethod("recordingMethod"));
51     assertThat(s1).isInstanceOf(Subscriber.SynchronizedSubscriber.class);
52 
53     // a thread-safe method should not create a synchronized subscriber
54     Subscriber s2 = Subscriber.create(bus, this, getTestSubscriberMethod("threadSafeMethod"));
55     assertThat(s2).isNotInstanceOf(Subscriber.SynchronizedSubscriber.class);
56   }
57 
testInvokeSubscriberMethod_basicMethodCall()58   public void testInvokeSubscriberMethod_basicMethodCall() throws Throwable {
59     Method method = getTestSubscriberMethod("recordingMethod");
60     Subscriber subscriber = Subscriber.create(bus, this, method);
61 
62     subscriber.invokeSubscriberMethod(FIXTURE_ARGUMENT);
63 
64     assertTrue("Subscriber must call provided method", methodCalled);
65     assertTrue(
66         "Subscriber argument must be exactly the provided object.",
67         methodArgument == FIXTURE_ARGUMENT);
68   }
69 
testInvokeSubscriberMethod_exceptionWrapping()70   public void testInvokeSubscriberMethod_exceptionWrapping() throws Throwable {
71     Method method = getTestSubscriberMethod("exceptionThrowingMethod");
72     Subscriber subscriber = Subscriber.create(bus, this, method);
73 
74     InvocationTargetException expected =
75         assertThrows(
76             InvocationTargetException.class,
77             () -> subscriber.invokeSubscriberMethod(FIXTURE_ARGUMENT));
78     assertThat(expected).hasCauseThat().isInstanceOf(IntentionalException.class);
79   }
80 
testInvokeSubscriberMethod_errorPassthrough()81   public void testInvokeSubscriberMethod_errorPassthrough() throws Throwable {
82     Method method = getTestSubscriberMethod("errorThrowingMethod");
83     Subscriber subscriber = Subscriber.create(bus, this, method);
84 
85     assertThrows(JudgmentError.class, () -> subscriber.invokeSubscriberMethod(FIXTURE_ARGUMENT));
86   }
87 
testEquals()88   public void testEquals() throws Exception {
89     Method charAt = String.class.getMethod("charAt", int.class);
90     Method concat = String.class.getMethod("concat", String.class);
91     new EqualsTester()
92         .addEqualityGroup(
93             Subscriber.create(bus, "foo", charAt), Subscriber.create(bus, "foo", charAt))
94         .addEqualityGroup(Subscriber.create(bus, "bar", charAt))
95         .addEqualityGroup(Subscriber.create(bus, "foo", concat))
96         .testEquals();
97   }
98 
getTestSubscriberMethod(String name)99   private Method getTestSubscriberMethod(String name) {
100     try {
101       return getClass().getDeclaredMethod(name, Object.class);
102     } catch (NoSuchMethodException e) {
103       throw new AssertionError();
104     }
105   }
106 
107   /**
108    * Records the provided object in {@link #methodArgument} and sets {@link #methodCalled}. This
109    * method is called reflectively by Subscriber during tests, and must remain public.
110    *
111    * @param arg argument to record.
112    */
113   @Subscribe
recordingMethod(Object arg)114   public void recordingMethod(Object arg) {
115     assertFalse(methodCalled);
116     methodCalled = true;
117     methodArgument = arg;
118   }
119 
120   @Subscribe
exceptionThrowingMethod(Object arg)121   public void exceptionThrowingMethod(Object arg) throws Exception {
122     throw new IntentionalException();
123   }
124 
125   /** Local exception subclass to check variety of exception thrown. */
126   class IntentionalException extends Exception {
127 
128     private static final long serialVersionUID = -2500191180248181379L;
129   }
130 
131   @Subscribe
errorThrowingMethod(Object arg)132   public void errorThrowingMethod(Object arg) {
133     throw new JudgmentError();
134   }
135 
136   @Subscribe
137   @AllowConcurrentEvents
threadSafeMethod(Object arg)138   public void threadSafeMethod(Object arg) {}
139 
140   /** Local Error subclass to check variety of error thrown. */
141   class JudgmentError extends Error {
142 
143     private static final long serialVersionUID = 634248373797713373L;
144   }
145 }
146