blob: cbe7b58bc2d079eec760fc4236feed1af92d0d15 [file] [log] [blame]
/*
* Copyright 2011 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.google.web.bindery.event.shared;
import com.google.web.bindery.event.shared.testing.CountingEventBus;
import junit.framework.AssertionFailedError;
import java.util.Set;
/**
* Eponymous unit test.
*/
public class SimpleEventBusTest extends EventBusTestBase {
interface Command {
void execute();
}
class ShyHandler implements FooEvent.Handler {
HandlerRegistration r;
public void onFoo(FooEvent event) {
add(this);
r.removeHandler();
}
}
class SourcedHandler implements FooEvent.Handler {
final String expectedSource;
SourcedHandler(String source) {
this.expectedSource = source;
}
public void onFoo(FooEvent event) {
add(this);
assertEquals(expectedSource, event.getSource());
}
}
static class ThrowingHandler implements FooEvent.Handler {
private final RuntimeException e;
public ThrowingHandler(RuntimeException e) {
this.e = e;
}
public void onFoo(FooEvent event) {
throw e;
}
}
public void testAddAndRemoveHandlers() {
CountingEventBus eventBus = new CountingEventBus(new SimpleEventBus());
FooEvent.register(eventBus, fooHandler1);
FooEvent.register(eventBus, fooHandler2);
HandlerRegistration reg1 = FooEvent.register(eventBus, adaptor1);
eventBus.fireEvent(new FooEvent());
assertEquals(3, eventBus.getCount(FooEvent.TYPE));
assertFired(fooHandler1, fooHandler2, adaptor1);
FooEvent.register(eventBus, fooHandler3);
assertEquals(4, eventBus.getCount(FooEvent.TYPE));
FooEvent.register(eventBus, fooHandler1);
FooEvent.register(eventBus, fooHandler2);
HandlerRegistration reg2 = FooEvent.register(eventBus, adaptor1);
/*
* You can indeed add handlers twice, they will only be removed one at a
* time though.
*/
assertEquals(7, eventBus.getCount(FooEvent.TYPE));
eventBus.addHandler(BarEvent.TYPE, adaptor1);
eventBus.addHandler(BarEvent.TYPE, barHandler1);
eventBus.addHandler(BarEvent.TYPE, barHandler2);
assertEquals(7, eventBus.getCount(FooEvent.TYPE));
assertEquals(3, eventBus.getCount(BarEvent.TYPE));
reset();
eventBus.fireEvent(new FooEvent());
assertFired(fooHandler1, fooHandler2, fooHandler3, adaptor1);
assertNotFired(barHandler1, barHandler2);
// Gets rid of first instance.
reg1.removeHandler();
eventBus.fireEvent(new FooEvent());
assertFired(fooHandler1, fooHandler2, fooHandler3, adaptor1);
assertNotFired(barHandler1, barHandler2);
// Gets rid of second instance.
reg2.removeHandler();
reset();
eventBus.fireEvent(new FooEvent());
assertFired(fooHandler1, fooHandler2, fooHandler3);
assertNotFired(adaptor1, barHandler1, barHandler2);
// Checks to see if barHandler events are still working.
reset();
eventBus.fireEvent(new BarEvent());
assertNotFired(fooHandler1, fooHandler2, fooHandler3);
assertFired(barHandler1, barHandler2, adaptor1);
}
public void testAssertThrowsNpe() {
final SimpleEventBus eventBus = new SimpleEventBus();
try {
assertThrowsNpe(new Command() {
public void execute() {
FooEvent.register(eventBus, fooHandler1);
}
});
fail("expected AssertionFailedError");
} catch (AssertionFailedError e) {
/* pass */
}
}
public void testConcurrentAdd() {
final SimpleEventBus eventBus = new SimpleEventBus();
final FooEvent.Handler two = new FooEvent.Handler() {
public void onFoo(FooEvent event) {
add(this);
}
};
FooEvent.Handler one = new FooEvent.Handler() {
public void onFoo(FooEvent event) {
FooEvent.register(eventBus, two);
add(this);
}
};
FooEvent.register(eventBus, one);
FooEvent.register(eventBus, fooHandler1);
FooEvent.register(eventBus, fooHandler2);
FooEvent.register(eventBus, fooHandler3);
eventBus.fireEvent(new FooEvent());
assertFired(one, fooHandler1, fooHandler2, fooHandler3);
assertNotFired(two);
reset();
eventBus.fireEvent(new FooEvent());
assertFired(one, two, fooHandler1, fooHandler2, fooHandler3);
}
public void testConcurrentAddAfterRemoveIsNotClobbered() {
final SimpleEventBus eventBus = new SimpleEventBus();
FooEvent.Handler one = new FooEvent.Handler() {
HandlerRegistration reg = addIt();
public void onFoo(FooEvent event) {
reg.removeHandler();
addIt();
add(this);
}
private HandlerRegistration addIt() {
return FooEvent.register(eventBus, fooHandler1);
}
};
FooEvent.register(eventBus, one);
eventBus.fireEvent(new FooEvent());
assertFired(one);
reset();
eventBus.fireEvent(new FooEvent());
assertFired(one, fooHandler1);
}
public void testConcurrentAddAndRemoveByNastyUsersTryingToHurtUs() {
final SimpleEventBus eventBus = new SimpleEventBus();
final FooEvent.Handler two = new FooEvent.Handler() {
public void onFoo(FooEvent event) {
add(this);
}
@Override
public String toString() {
return "two";
}
};
FooEvent.Handler one = new FooEvent.Handler() {
public void onFoo(FooEvent event) {
FooEvent.register(eventBus, two).removeHandler();
add(this);
}
@Override
public String toString() {
return "one";
}
};
FooEvent.register(eventBus, one);
FooEvent.register(eventBus, fooHandler1);
FooEvent.register(eventBus, fooHandler2);
FooEvent.register(eventBus, fooHandler3);
eventBus.fireEvent(new FooEvent());
assertFired(one, fooHandler1, fooHandler2, fooHandler3);
assertNotFired(two);
reset();
eventBus.fireEvent(new FooEvent());
assertFired(one, fooHandler1, fooHandler2, fooHandler3);
assertNotFired(two);
}
public void testConcurrentRemove() {
final SimpleEventBus eventBus = new SimpleEventBus();
ShyHandler h = new ShyHandler();
FooEvent.register(eventBus, fooHandler1);
h.r = FooEvent.register(eventBus, h);
FooEvent.register(eventBus, fooHandler2);
FooEvent.register(eventBus, fooHandler3);
eventBus.fireEvent(new FooEvent());
assertFired(h, fooHandler1, fooHandler2, fooHandler3);
reset();
eventBus.fireEvent(new FooEvent());
assertFired(fooHandler1, fooHandler2, fooHandler3);
assertNotFired(h);
}
public void testFromSource() {
final SimpleEventBus eventBus = new SimpleEventBus();
SourcedHandler global = new SourcedHandler("able");
SourcedHandler able = new SourcedHandler("able");
SourcedHandler baker = new SourcedHandler("baker");
FooEvent.register(eventBus, global);
FooEvent.register(eventBus, "able", able);
FooEvent.register(eventBus, "baker", baker);
eventBus.fireEventFromSource(new FooEvent(), "able");
assertFired(global, able);
assertNotFired(baker);
}
public void testHandlersThrow() {
RuntimeException exception1 = new RuntimeException("first exception");
RuntimeException exception2 = new RuntimeException("second exception");
final SimpleEventBus eventBus = new SimpleEventBus();
FooEvent.register(eventBus, fooHandler1);
FooEvent.register(eventBus, new ThrowingHandler(exception1));
FooEvent.register(eventBus, fooHandler2);
FooEvent.register(eventBus, new ThrowingHandler(exception2));
FooEvent.register(eventBus, fooHandler3);
FooEvent event = new FooEvent();
try {
eventBus.fireEvent(event);
fail("eventBus should have thrown");
} catch (UmbrellaException e) {
Set<Throwable> causes = e.getCauses();
assertEquals("Exception should wrap the two thrown exceptions", 2, causes.size());
assertTrue("First exception should be under the umbrella", causes.contains(exception1));
assertTrue("Second exception should be under the umbrella", causes.contains(exception2));
}
/*
* Exception should not have prevented all three mouse handlers from getting
* the event.
*/
assertFired(fooHandler1, fooHandler2, fooHandler3);
}
public void testNoDoubleRemove() {
final SimpleEventBus eventBus = new SimpleEventBus();
HandlerRegistration reg = FooEvent.register(eventBus, fooHandler1);
reg.removeHandler();
reg.removeHandler(); // should not throw
}
public void testNoSource() {
final SimpleEventBus eventBus = new SimpleEventBus();
SourcedHandler global = new SourcedHandler(null);
SourcedHandler able = new SourcedHandler("able");
SourcedHandler baker = new SourcedHandler("baker");
FooEvent.register(eventBus, global);
FooEvent.register(eventBus, "able", able);
FooEvent.register(eventBus, "baker", baker);
eventBus.fireEvent(new FooEvent());
assertFired(global);
assertNotFired(able, baker);
}
public void testNullChecks() {
final SimpleEventBus eventBus = new SimpleEventBus();
assertThrowsNpe(new Command() {
public void execute() {
eventBus.addHandler(null, fooHandler1);
}
});
assertThrowsNpe(new Command() {
public void execute() {
FooEvent.register(eventBus, "foo", null);
}
});
assertThrowsNpe(new Command() {
public void execute() {
FooEvent.register(eventBus, null, fooHandler1);
}
});
assertThrowsNpe(new Command() {
public void execute() {
eventBus.addHandlerToSource(null, "foo", fooHandler1);
}
});
assertThrowsNpe(new Command() {
public void execute() {
eventBus.fireEvent(null);
}
});
assertThrowsNpe(new Command() {
public void execute() {
eventBus.fireEventFromSource(null, "");
}
});
assertThrowsNpe(new Command() {
public void execute() {
eventBus.fireEventFromSource(new FooEvent() {
}, null);
}
});
assertThrowsNpe(new Command() {
public void execute() {
eventBus.fireEventFromSource(null, "baker");
}
});
}
public void testNullSourceOkay() {
SimpleEventBus reg = new SimpleEventBus();
FooEvent.Handler handler = new FooEvent.Handler() {
public void onFoo(FooEvent event) {
add(this);
assertNull(event.getSource());
}
};
reg.addHandler(FooEvent.TYPE, handler);
reg.fireEvent(new FooEvent());
assertFired(handler);
}
public void testRemoveSelf() {
final SimpleEventBus eventBus = new SimpleEventBus();
FooEvent.Handler h = new FooEvent.Handler() {
HandlerRegistration reg = FooEvent.register(eventBus, this);
public void onFoo(FooEvent event) {
add(this);
reg.removeHandler();
}
};
eventBus.fireEvent(new FooEvent());
assertFired(h);
reset();
eventBus.fireEvent(new FooEvent());
assertNotFired(h);
}
public void testReverseOrder() {
@SuppressWarnings("deprecation")
final SimpleEventBus eventBus = new SimpleEventBus(true);
final FooEvent.Handler handler0 = new FooEvent.Handler() {
public void onFoo(FooEvent event) {
add(this);
}
};
final FooEvent.Handler handler1 = new FooEvent.Handler() {
public void onFoo(FooEvent event) {
assertNotFired(handler0);
add(this);
}
};
final FooEvent.Handler handler2 = new FooEvent.Handler() {
public void onFoo(FooEvent event) {
assertNotFired(handler0, handler1);
add(this);
}
};
FooEvent.register(eventBus, handler0);
FooEvent.register(eventBus, handler1);
FooEvent.register(eventBus, handler2);
reset();
eventBus.fireEvent(new FooEvent());
assertFired(handler0, handler1, handler2);
}
private void assertThrowsNpe(Command command) {
try {
command.execute();
fail("expected NullPointerException");
} catch (NullPointerException e) {
/* pass */
}
}
}