/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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 org.apache.openejb.observer;
import org.apache.openejb.observer.event.AfterEvent;
import org.apache.openejb.observer.event.BeforeEvent;
import org.apache.openejb.observer.event.ObserverFailed;
import org.junit.Before;
import org.junit.Test;
import java.lang.reflect.Method;
import java.net.URI;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import static org.apache.openejb.observer.Util.caller;
import static org.apache.openejb.observer.Util.description;
public class ObserverFeaturesTest {
@Test
public void observeAll() {
a(new Object() {
public void observe(final @Observes Object event) {
pass();
}
}, new Date());
}
@Test
public void noFalsePositive() {
a(new Object() {
public void observe(final @Observes Integer event) {
fail();
}
public void observe(final @Observes Date event) {
pass();
}
}, new Date());
}
@Test
public void inheritance() {
a(new Object() {
public void observe(final @Observes Number event) {
pass();
}
}, 42);
}
@Test
public void overloaded() {
a(new Object() {
public void number(final @Observes Number event) {
fail();
}
public void integer(final @Observes Integer event) {
pass();
}
}, 42);
}
@Test
@Assert({"before", "observe"})
public void beforeEvent() {
a(new Object() {
public void before(final @Observes BeforeEvent<Integer> event) {
invoked();
}
public void observe(final @Observes Integer event) {
invoked();
}
}, 42);
}
@Test
@Assert({"observe", "after"})
public void afterEvent() {
a(new Object() {
public void after(final @Observes AfterEvent<Integer> event) {
invoked();
}
public void observe(final @Observes Integer event) {
invoked();
}
}, 42);
}
@Test
@Assert({"before", "after"})
public void beforeInvokeAfter() {
a(new Object() {
public void after(final @Observes AfterEvent<Integer> event) {
invoked();
}
public void before(final @Observes BeforeEvent<Integer> event) {
invoked();
}
}, 42);
}
@Test
public void noFalseBeforePositive() {
a(new Object() {
public void integer(final @Observes BeforeEvent<Integer> event) {
pass();
}
public void date(final @Observes BeforeEvent<Date> event) {
fail();
}
}, 42);
}
@Test
@Assert("integer")
public void noFalseAfterPositive() {
a(new Object() {
public void integer(final @Observes AfterEvent<Integer> event) {
invoked();
}
public void date(final @Observes AfterEvent<Date> event) {
invoked();
}
}, 42);
}
@Test
public void beforeInheritance() {
a(new Object() {
public void number(final @Observes AfterEvent<Number> event) {
pass();
}
}, 42);
}
@Test
public void beforeObject() {
a(new Object() {
public void integer(final @Observes AfterEvent<Object> event) {
pass();
}
}, 42);
}
@Test
public void beforeInheritanceOverloaded() {
a(new Object() {
public void integer(final @Observes AfterEvent<Integer> event) {
pass();
}
public void number(final @Observes AfterEvent<Number> event) {
fail();
}
}, 42);
}
@Test
public void afterInheritance() {
a(new Object() {
public void number(final @Observes AfterEvent<Number> event) {
pass();
}
}, 42);
}
@Test
public void afterObject() {
a(new Object() {
public void integer(final @Observes AfterEvent<Object> event) {
pass();
}
}, 42);
}
@Test
public void afterInheritanceOverloaded() {
a(new Object() {
public void integer(final @Observes AfterEvent<Integer> event) {
pass();
}
public void number(final @Observes AfterEvent<Number> event) {
fail();
}
}, 42);
}
@Test
@Assert({"number", "afterInteger", "beforeDate", "object", "afterObject", "object", "afterObject"})
public void sequence() {
a(new Object() {
public void object(final @Observes Object event) {
invoked();
}
public void number(final @Observes Number event) {
invoked();
}
public void afterInteger(final @Observes AfterEvent<Integer> event) {
invoked();
}
public void afterObject(final @Observes AfterEvent<Object> event) {
invoked();
}
public void beforeDate(final @Observes BeforeEvent<Date> event) {
invoked();
}
}, 42, new Date(), URI.create("foo:bar"));
}
@Test
@Assert({"number", "failed"})
public void failure() {
a(new Object() {
public void number(final @Observes Integer event) {
invoked();
throw new RuntimeException("testing exceptions");
}
public void failed(final @Observes ObserverFailed event) {
invoked();
}
}, 42);
}
@Test
@Assert({"number", "failed"})
public void circularFailureDirect() {
a(new Object() {
public void number(final @Observes Integer event) {
invoked();
throw new RuntimeException("testing exceptions");
}
public void failed(final @Observes ObserverFailed event) {
invoked();
throw new RuntimeException("testing exceptions");
}
}, 42);
}
@Test
@Assert({
"number.Integer",
"afterObject.AfterEvent<ObserverFailed{number}>",
"afterObject.AfterEvent<ObserverFailed{afterObject}>",
"afterObject.AfterEvent<Integer>",
})
public void circularFailureAfterObject() {
a(new Object() {
public void number(final @Observes Integer event) {
invoked(description(event));
throw new RuntimeException("testing exceptions");
}
public void afterObject(final @Observes AfterEvent<Object> event) {
invoked(description(event));
throw new RuntimeException("testing exceptions");
}
}, 42);
}
@Test
@Assert({
"number.Integer",
"afterObject.AfterEvent<Integer>",
"failed.ObserverFailed{afterObject}",
"afterObject.AfterEvent<ObserverFailed{afterObject}>",
})
public void circluarFailureProtection() {
a(new Object() {
public void number(final @Observes Integer event) {
invoked(description(event));
}
public void afterObject(final @Observes AfterEvent<Object> event) {
invoked(description(event));
throw new RuntimeException("testing exceptions");
}
public void failed(final @Observes ObserverFailed event) {
invoked(description(event));
throw new RuntimeException("testing exceptions");
}
}, 42);
}
private final List<Boolean> conditions = new ArrayList<Boolean>();
private final List<String> invocations = new ArrayList<String>();
@Before
public void init() {
conditions.clear();
}
public void pass() {
conditions.add(true);
}
public void fail() {
conditions.add(false);
}
public void invoked() {
final Method method = caller(2);
invocations.add(method.getName());
}
public void invoked(final String suffix) {
final Method method = caller(2);
invocations.add(method.getName() + "." + suffix);
}
private void a(final Object observer, final Object... events) {
final ObserverManager observers = new ObserverManager();
observers.addObserver(observer);
conditions.clear();
invocations.clear();
for (final Object event : events) {
observers.fireEvent(event);
}
final Method testMethod = caller(2);
final Assert annotation = testMethod.getAnnotation(Assert.class);
if (annotation != null) {
Util.assertEvent(invocations, annotation.value());
} else {
org.junit.Assert.assertNotEquals(0, conditions.size());
for (final Boolean condition : conditions) {
org.junit.Assert.assertTrue(condition);
}
}
}
}