/*
* JBoss, Home of Professional Open Source
* Copyright 2010, Red Hat, Inc., and individual contributors
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* 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 org.jboss.cdi.tck.tests.context.dependent;
import static org.jboss.cdi.tck.cdi.Sections.BEAN;
import static org.jboss.cdi.tck.cdi.Sections.CONTEXT;
import static org.jboss.cdi.tck.cdi.Sections.CREATIONAL_CONTEXT;
import static org.jboss.cdi.tck.cdi.Sections.DEPENDENT_CONTEXT;
import static org.jboss.cdi.tck.cdi.Sections.DEPENDENT_CONTEXT_EE;
import static org.jboss.cdi.tck.cdi.Sections.DEPENDENT_DESTRUCTION;
import static org.jboss.cdi.tck.cdi.Sections.DEPENDENT_DESTRUCTION_EE;
import static org.jboss.cdi.tck.cdi.Sections.DEPENDENT_OBJECTS;
import static org.jboss.cdi.tck.cdi.Sections.OBSERVERS_METHOD_INVOCATION;
import static org.jboss.cdi.tck.cdi.Sections.PRODUCER_OR_DISPOSER_METHODS_INVOCATION;
import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertNotEquals;
import static org.testng.Assert.assertNotNull;
import static org.testng.Assert.assertTrue;
import java.lang.annotation.Annotation;
import java.util.Set;
import javax.enterprise.context.Dependent;
import javax.enterprise.context.spi.Context;
import javax.enterprise.context.spi.CreationalContext;
import javax.enterprise.inject.spi.Bean;
import javax.enterprise.util.AnnotationLiteral;
import org.jboss.arquillian.container.test.api.Deployment;
import org.jboss.cdi.tck.AbstractTest;
import org.jboss.cdi.tck.shrinkwrap.WebArchiveBuilder;
import org.jboss.cdi.tck.util.MockCreationalContext;
import org.jboss.shrinkwrap.api.spec.WebArchive;
import org.jboss.test.audit.annotations.SpecAssertion;
import org.jboss.test.audit.annotations.SpecVersion;
import org.testng.annotations.Test;
@SpecVersion(spec = "cdi", version = "2.0-PFD")
public class DependentContextTest extends AbstractTest {
private static final Annotation TAME_LITERAL = new AnnotationLiteral<Tame>() {
};
private static final Annotation PET_LITERAL = new AnnotationLiteral<Pet>() {
};
@Deployment
public static WebArchive createTestArchive() {
return new WebArchiveBuilder().withTestClassPackage(DependentContextTest.class).withBeansXml("beans.xml").build();
}
@Test
@SpecAssertion(section = DEPENDENT_CONTEXT, id = "a")
@SpecAssertion(section = DEPENDENT_OBJECTS, id = "ga")
public void testInstanceNotSharedBetweenInjectionPoints() {
Set<Bean<Fox>> foxBeans = getBeans(Fox.class);
assert foxBeans.size() == 1;
Set<Bean<FoxRun>> foxRunBeans = getBeans(FoxRun.class);
assert foxRunBeans.size() == 1;
Bean<FoxRun> foxRunBean = foxRunBeans.iterator().next();
CreationalContext<FoxRun> creationalContext = getCurrentManager().createCreationalContext(foxRunBean);
FoxRun foxRun = foxRunBean.create(creationalContext);
assert !foxRun.fox.equals(foxRun.anotherFox);
assert !foxRun.fox.equals(foxRun.petFox);
assert !foxRun.anotherFox.equals(foxRun.petFox);
}
@Test
@SpecAssertion(section = DEPENDENT_OBJECTS, id = "ga")
@SpecAssertion(section = DEPENDENT_OBJECTS, id = "gb")
@SpecAssertion(section = DEPENDENT_OBJECTS, id = "gc")
public void testDependentBeanIsDependentObjectOfBeanInjectedInto() {
FoxFarm foxFarm = getContextualReference(FoxFarm.class);
FoxHole foxHole = getContextualReference(FoxHole.class);
assert !foxFarm.fox.equals(foxHole.fox);
assert !foxFarm.fox.equals(foxFarm.constructorFox);
assert !foxFarm.constructorFox.equals(foxHole.initializerFox);
assert !foxHole.fox.equals(foxHole.initializerFox);
}
@Test
@SpecAssertion(section = DEPENDENT_CONTEXT_EE, id = "ca")
public void testInstanceUsedForElEvaluationNotShared() throws Exception {
Set<Bean<Fox>> foxBeans = getBeans(Fox.class);
assert foxBeans.size() == 1;
Fox fox1 = getCurrentConfiguration().getEl().evaluateValueExpression(getCurrentManager(), "#{fox}", Fox.class);
Fox fox2 = getCurrentConfiguration().getEl().evaluateValueExpression(getCurrentManager(), "#{fox}", Fox.class);
assert !fox1.equals(fox2);
}
@Test
@SpecAssertion(section = DEPENDENT_CONTEXT, id = "da")
public void testInstanceUsedForProducerMethodNotShared() throws Exception {
SpiderProducer.reset();
getContextualReference(Tarantula.class, PET_LITERAL);
Integer firstInstanceHash = SpiderProducer.getInstanceUsedForProducerHashcode();
SpiderProducer.reset();
getContextualReference(Tarantula.class, PET_LITERAL);
Integer secondInstanceHash = SpiderProducer.getInstanceUsedForProducerHashcode();
assertFalse(firstInstanceHash.equals(secondInstanceHash));
}
@Test
@SpecAssertion(section = DEPENDENT_CONTEXT, id = "db")
public void testInstanceUsedForProducerFieldNotShared() throws Exception {
Tarantula firstIntance = getContextualReference(Tarantula.class, TAME_LITERAL);
Tarantula secondIntance = getContextualReference(Tarantula.class, TAME_LITERAL);
assertNotNull(firstIntance.getProducerInstanceHashcode());
assertNotNull(secondIntance.getProducerInstanceHashcode());
assertNotEquals(firstIntance.getProducerInstanceHashcode(), secondIntance.getProducerInstanceHashcode());
}
@Test
@SpecAssertion(section = DEPENDENT_CONTEXT, id = "dc")
@SpecAssertion(section = DEPENDENT_CONTEXT, id = "dg")
public void testInstanceUsedForDisposalMethodNotShared() {
Integer firstFoxHash = getContextualReference(Fox.class).hashCode();
SpiderProducer.reset();
SpiderProducer spiderProducer = getContextualReference(SpiderProducer.class);
Bean<Tarantula> tarantulaBean = getUniqueBean(Tarantula.class, PET_LITERAL);
CreationalContext<Tarantula> creationalContext = getCurrentManager().createCreationalContext(tarantulaBean);
Tarantula tarantula = tarantulaBean.create(creationalContext);
assert tarantula != null;
tarantulaBean.destroy(tarantula, creationalContext);
Integer secondFoxHash = SpiderProducer.getFoxUsedForDisposalHashcode();
assert SpiderProducer.getInstanceUsedForDisposalHashcode() != null;
assert !SpiderProducer.getInstanceUsedForDisposalHashcode().equals(spiderProducer.hashCode());
CreationalContext<Tarantula> nextCreationalContext = getCurrentManager().createCreationalContext(tarantulaBean);
Tarantula nextTarantula = tarantulaBean.create(nextCreationalContext);
assert nextTarantula != null;
tarantulaBean.destroy(nextTarantula, creationalContext);
Integer thirdFoxHash = SpiderProducer.getFoxUsedForDisposalHashcode();
assertNotEquals(firstFoxHash, secondFoxHash);
assertNotEquals(firstFoxHash, thirdFoxHash);
assertNotEquals(thirdFoxHash, secondFoxHash);
SpiderProducer.reset();
}
@Test
@SpecAssertion(section = DEPENDENT_CONTEXT, id = "dd")
@SpecAssertion(section = DEPENDENT_CONTEXT, id = "dg")
public void testInstanceUsedForObserverMethodNotShared() {
HorseStable.reset();
HorseStable firstStableInstance = getContextualReference(HorseStable.class);
getCurrentManager().fireEvent(new HorseInStableEvent());
Integer firstFoxHash = HorseStable.getFoxUsedForObservedEventHashcode();
Integer firstObserverHash = HorseStable.getInstanceThatObservedEventHashcode();
getCurrentManager().fireEvent(new HorseInStableEvent());
Integer secondFoxHash = HorseStable.getFoxUsedForObservedEventHashcode();
Integer secondObserverHash = HorseStable.getInstanceThatObservedEventHashcode();
assertNotNull(firstObserverHash);
assertNotNull(secondObserverHash);
assertNotNull(firstFoxHash);
assertNotNull(secondFoxHash);
assertNotEquals(firstStableInstance.hashCode(), firstObserverHash);
assertNotEquals(firstStableInstance.hashCode(), secondObserverHash);
assertNotEquals(firstObserverHash, secondObserverHash);
assertNotEquals(firstFoxHash, secondFoxHash);
}
@Test
@SpecAssertion(section = DEPENDENT_CONTEXT, id = "e")
public void testContextGetWithCreationalContextReturnsNewInstance() {
Set<Bean<Fox>> foxBeans = getBeans(Fox.class);
assert foxBeans.size() == 1;
Bean<Fox> foxBean = foxBeans.iterator().next();
Context context = getCurrentManager().getContext(Dependent.class);
assert context.get(foxBean, new MockCreationalContext<Fox>()) != null;
assert context.get(foxBean, new MockCreationalContext<Fox>()) instanceof Fox;
}
@Test
@SpecAssertion(section = DEPENDENT_CONTEXT, id = "f")
public void testContextGetWithCreateFalseReturnsNull() {
Set<Bean<Fox>> foxBeans = getBeans(Fox.class);
assert foxBeans.size() == 1;
Bean<Fox> foxBean = foxBeans.iterator().next();
Context context = getCurrentManager().getContext(Dependent.class);
assert context.get(foxBean, null) == null;
}
@Test
@SpecAssertion(section = CONTEXT, id = "ab")
public void testContextScopeType() {
assert getCurrentManager().getContext(Dependent.class).getScope().equals(Dependent.class);
}
@Test
@SpecAssertion(section = CONTEXT, id = "ha")
@SpecAssertion(section = DEPENDENT_CONTEXT, id = "g")
public void testContextIsActive() {
assert getCurrentManager().getContext(Dependent.class).isActive();
}
@Test
@SpecAssertion(section = CONTEXT, id = "ha")
@SpecAssertion(section = DEPENDENT_CONTEXT, id = "g") // Dependent context is now always active
public void testContextIsActiveWhenInvokingProducerMethod() {
SpiderProducer.reset();
Tarantula tarantula = getContextualReference(Tarantula.class, PET_LITERAL);
assert tarantula != null;
assert SpiderProducer.isDependentContextActive();
SpiderProducer.reset();
}
@Test
@SpecAssertion(section = DEPENDENT_CONTEXT, id = "g")
// Dependent context is now always active
public void testContextIsActiveWhenInvokingProducerField() {
// Reset test class
Tarantula.reset();
getContextualReference(Tarantula.class, TAME_LITERAL);
assert Tarantula.isDependentContextActive();
SpiderProducer.reset();
}
@Test
@SpecAssertion(section = DEPENDENT_CONTEXT, id = "g")
@SpecAssertion(section = BEAN, id = "aa")
public void testContextIsActiveWhenInvokingDisposalMethod() {
Bean<Tarantula> tarantulaBean = getBeans(Tarantula.class, PET_LITERAL).iterator().next();
CreationalContext<Tarantula> creationalContext = getCurrentManager().createCreationalContext(tarantulaBean);
Tarantula tarantula = tarantulaBean.create(creationalContext);
assert tarantula != null;
SpiderProducer.reset();
tarantulaBean.destroy(tarantula, creationalContext);
assert SpiderProducer.isDependentContextActive();
SpiderProducer.reset();
}
@Test
@SpecAssertion(section = DEPENDENT_CONTEXT, id = "g")
// Dependent context is now always active
public void testContextIsActiveWhenCreatingObserverMethodInstance() {
getCurrentManager().fireEvent(new HorseInStableEvent());
assert HorseStable.isDependentContextActive();
}
@Test
@SpecAssertion(section = DEPENDENT_CONTEXT, id = "g")
// Dependent context is now always active
public void testContextIsActiveWhenEvaluatingElExpression() {
String foxName = getCurrentConfiguration().getEl().evaluateMethodExpression(getCurrentManager(),
"#{sensitiveFox.getName}", String.class, new Class[0], new Object[0]);
assert foxName != null;
assert SensitiveFox.isDependentContextActiveDuringEval();
}
@Test
@SpecAssertion(section = DEPENDENT_CONTEXT, id = "g")
// Dependent context is now always active
public void testContextIsActiveDuringBeanCreation() {
SensitiveFox fox1 = getContextualReference(SensitiveFox.class);
assert fox1 != null;
assert fox1.isDependentContextActiveDuringCreate();
}
@Test
@SpecAssertion(section = DEPENDENT_CONTEXT, id = "g")
// Dependent context is now always active
public void testContextIsActiveDuringInjection() {
Bean<FoxRun> foxRunBean = getBeans(FoxRun.class).iterator().next();
FoxRun foxRun = foxRunBean.create(new MockCreationalContext<FoxRun>());
assert foxRun.fox != null;
}
@Test
@SpecAssertion(section = DEPENDENT_DESTRUCTION, id = "aaaa")
@SpecAssertion(section = DEPENDENT_CONTEXT, id = "b")
public void testDestroyingSimpleParentDestroysDependents() {
assert getBeans(Farm.class).size() == 1;
Bean<Farm> farmBean = getBeans(Farm.class).iterator().next();
CreationalContext<Farm> creationalContext = getCurrentManager().createCreationalContext(farmBean);
Farm farm = farmBean.create(creationalContext);
farm.open();
Stable.destroyed = false;
Horse.destroyed = false;
farmBean.destroy(farm, creationalContext);
assert Stable.destroyed;
assert Horse.destroyed;
}
@Test
@SpecAssertion(section = CREATIONAL_CONTEXT, id = "e")
public void testCallingCreationalContextReleaseDestroysDependents() {
assert getBeans(Farm.class).size() == 1;
// Unmanaged instance
Bean<Farm> farmBean = getBeans(Farm.class).iterator().next();
CreationalContext<Farm> creationalContext = getCurrentManager().createCreationalContext(farmBean);
Farm farm = farmBean.create(creationalContext);
farm.open();
Stable.destroyed = false;
Horse.destroyed = false;
creationalContext.release();
assert Stable.destroyed;
assert Horse.destroyed;
// Contextual reference
creationalContext = getCurrentManager().createCreationalContext(farmBean);
farm = (Farm) getCurrentManager().getReference(farmBean, Farm.class, creationalContext);
farm.open();
Stable.destroyed = false;
Horse.destroyed = false;
creationalContext.release();
assert Stable.destroyed;
assert Horse.destroyed;
}
@Test
@SpecAssertion(section = DEPENDENT_DESTRUCTION, id = "aaaa")
@SpecAssertion(section = DEPENDENT_CONTEXT, id = "b")
public void testDestroyingManagedParentDestroysDependentsOfSameBean() {
// Reset test class
Fox.reset();
assert getCurrentManager().getBeans(FoxRun.class).size() == 1;
Bean<FoxRun> bean = getBeans(FoxRun.class).iterator().next();
CreationalContext<FoxRun> creationalContext = getCurrentManager().createCreationalContext(bean);
FoxRun instance = bean.create(creationalContext);
assert instance.fox != instance.anotherFox;
bean.destroy(instance, creationalContext);
assert Fox.isDestroyed();
assert Fox.getDestroyCount() == 2;
}
@Test
@SpecAssertion(section = DEPENDENT_DESTRUCTION_EE, id = "eee")
public void testDependentsDestroyedWhenElEvaluationCompletes() throws Exception {
// Reset test class
Fox.reset();
FoxRun.setDestroyed(false);
getCurrentConfiguration().getEl().evaluateValueExpression(getCurrentManager(), "#{foxRun}", FoxRun.class);
assert FoxRun.isDestroyed();
assert Fox.isDestroyed();
}
@Test
@SpecAssertion(section = DEPENDENT_DESTRUCTION, id = "ddd")
@SpecAssertion(section = DEPENDENT_OBJECTS, id = "h")
@SpecAssertion(section = PRODUCER_OR_DISPOSER_METHODS_INVOCATION, id = "f")
public void testDependentsDestroyedWhenProducerMethodCompletes() {
// Reset the test classes
SpiderProducer.reset();
Tarantula.reset();
DomesticationKit.reset();
Bean<Tarantula> tarantulaBean = getUniqueBean(Tarantula.class, PET_LITERAL);
CreationalContext<Tarantula> creationalContext = getCurrentManager().createCreationalContext(tarantulaBean);
Tarantula tarantula = (Tarantula) getCurrentManager().getReference(tarantulaBean, Tarantula.class, creationalContext);
tarantula.ping();
// contextual instance created to receive a producer method invocation
// is destroyed when the invocation completes
assert SpiderProducer.isDestroyed();
// DomesticationKit instance is a dependent object of the Tarantula instance
tarantulaBean.destroy(tarantula, creationalContext);
assert DomesticationKit.isDestroyed();
SpiderProducer.reset();
}
@Test
@SpecAssertion(section = DEPENDENT_DESTRUCTION, id = "dde")
public void testDependentsDestroyedWhenProducerFieldCompletes() {
// Reset the test class
OtherSpiderProducer.setDestroyed(false);
Tarantula spiderInstance = getContextualReference(Tarantula.class, TAME_LITERAL);
assert spiderInstance != null;
assert OtherSpiderProducer.isDestroyed();
}
@Test
@SpecAssertion(section = DEPENDENT_DESTRUCTION, id = "ddf")
@SpecAssertion(section = DEPENDENT_DESTRUCTION, id = "ccc")
@SpecAssertion(section = PRODUCER_OR_DISPOSER_METHODS_INVOCATION, id = "d")
@SpecAssertion(section = PRODUCER_OR_DISPOSER_METHODS_INVOCATION, id = "f")
public void testDependentsDestroyedWhenDisposerMethodCompletes() {
Bean<Tarantula> tarantulaBean = getBeans(Tarantula.class, PET_LITERAL).iterator().next();
CreationalContext<Tarantula> creationalContext = getCurrentManager().createCreationalContext(tarantulaBean);
Tarantula tarantula = tarantulaBean.create(creationalContext);
assertNotNull(tarantula);
// Reset test class state
SpiderProducer.reset();
Fox.reset();
tarantulaBean.destroy(tarantula, creationalContext);
assertTrue(SpiderProducer.isDestroyed());
assertNotNull(SpiderProducer.getFoxUsedForDisposalHashcode());
assertTrue(Fox.isDestroyed());
SpiderProducer.reset();
Fox.reset();
}
@Test
@SpecAssertion(section = DEPENDENT_DESTRUCTION, id = "ddg")
@SpecAssertion(section = DEPENDENT_DESTRUCTION, id = "ccd")
@SpecAssertion(section = OBSERVERS_METHOD_INVOCATION, id = "d")
public void testDependentsDestroyedWhenObserverMethodEvaluationCompletes() {
// Reset test class state...
HorseStable.reset();
Fox.reset();
getCurrentManager().fireEvent(new HorseInStableEvent());
assert HorseStable.getInstanceThatObservedEventHashcode() != null;
assert HorseStable.isDestroyed();
assert Fox.isDestroyed();
}
@Test
@SpecAssertion(section = DEPENDENT_OBJECTS, id = "ab")
public void testDependentScopedDecoratorsAreDependentObjectsOfBean() {
Bean<Interior> roomBean = getBeans(Interior.class, new RoomBinding()).iterator().next();
CreationalContext<Interior> roomCreationalContext = getCurrentManager().createCreationalContext(roomBean);
Interior room = (Interior) getCurrentManager().getReference(roomBean, Interior.class, roomCreationalContext);
InteriorDecorator.reset();
room.foo();
assert InteriorDecorator.getInstances().size() == 1;
roomCreationalContext.release();
assert InteriorDecorator.isDestroyed();
}
@Test
@SpecAssertion(section = DEPENDENT_OBJECTS, id = "aa")
public void testDependentScopedInterceptorsAreDependentObjectsOfBean() {
TransactionalInterceptor.destroyed = false;
TransactionalInterceptor.intercepted = false;
Bean<AccountTransaction> bean = getBeans(AccountTransaction.class).iterator().next();
CreationalContext<AccountTransaction> ctx = getCurrentManager().createCreationalContext(bean);
AccountTransaction trans = (AccountTransaction) getCurrentManager().getReference(bean, AccountTransaction.class, ctx);
trans.execute();
assert TransactionalInterceptor.intercepted;
ctx.release();
assert TransactionalInterceptor.destroyed;
}
}