org.picocontainer.containers.TieringPicoContainerTestCase Maven / Gradle / Ivy
package org.picocontainer.containers;
import org.junit.Test;
import static org.junit.Assert.fail;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.assertEquals;
import org.picocontainer.MutablePicoContainer;
import org.picocontainer.testmodel.SimpleTouchable;
import org.picocontainer.testmodel.DependsOnTouchable;
import static org.picocontainer.BindKey.bindKey;
import org.picocontainer.annotations.Bind;
import org.picocontainer.injectors.AbstractInjector;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.annotation.ElementType;
public class TieringPicoContainerTestCase {
public static class Couch {
}
public static class TiredPerson {
private Couch couchToSitOn;
public TiredPerson(Couch couchToSitOn) {
this.couchToSitOn = couchToSitOn;
}
}
@Test
public void testThatGrandparentTraversalForComponentsCanBeBlocked() {
MutablePicoContainer grandparent = new TieringPicoContainer();
MutablePicoContainer parent = grandparent.makeChildContainer();
MutablePicoContainer child = parent.makeChildContainer();
grandparent.addComponent(Couch.class);
child.addComponent(TiredPerson.class);
TiredPerson tp = null;
try {
tp = child.getComponent(TiredPerson.class);
fail("should have barfed");
} catch (AbstractInjector.UnsatisfiableDependenciesException e) {
// expected
}
}
@Test
public void testThatParentTraversalIsOkForTiering() {
MutablePicoContainer parent = new TieringPicoContainer();
MutablePicoContainer child = parent.makeChildContainer();
parent.addComponent(Couch.class);
child.addComponent(TiredPerson.class);
TiredPerson tp = child.getComponent(TiredPerson.class);
assertNotNull(tp);
assertNotNull(tp.couchToSitOn);
}
public static class Doctor {
private TiredPerson tiredPerson;
public Doctor(TiredPerson tiredPerson) {
this.tiredPerson = tiredPerson;
}
}
public static class TiredDoctor {
private Couch couchToSitOn;
private final TiredPerson tiredPerson;
public TiredDoctor(Couch couchToSitOn, TiredPerson tiredPerson) {
this.couchToSitOn = couchToSitOn;
this.tiredPerson = tiredPerson;
}
}
@Test
public void testThatParentTraversalIsOnlyBlockedOneTierAtATime() {
MutablePicoContainer gp = new TieringPicoContainer();
MutablePicoContainer p = gp.makeChildContainer();
MutablePicoContainer c = p.makeChildContainer();
gp.addComponent(Couch.class);
p.addComponent(TiredPerson.class);
c.addComponent(Doctor.class);
c.addComponent(TiredDoctor.class);
Doctor d = c.getComponent(Doctor.class);
assertNotNull(d);
assertNotNull(d.tiredPerson);
assertNotNull(d.tiredPerson.couchToSitOn);
try {
TiredDoctor td = c.getComponent(TiredDoctor.class);
fail("should have barfed");
} catch (AbstractInjector.UnsatisfiableDependenciesException e) {
// expected
}
}
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD, ElementType.PARAMETER})
@Bind
public static @interface Grouchy {}
public static class GrouchyTiredPerson extends TiredPerson {
public GrouchyTiredPerson(Couch couchToSitOn) {
super(couchToSitOn);
}
}
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD, ElementType.PARAMETER})
@Bind
public static @interface Polite {}
public static class PoliteTiredPerson extends TiredPerson {
public PoliteTiredPerson(Couch couchToSitOn) {
super(couchToSitOn);
}
}
public static class DiscerningDoctor {
private final TiredPerson tiredPerson;
public DiscerningDoctor(@Polite TiredPerson tiredPerson) {
this.tiredPerson = tiredPerson;
}
}
@Test
public void testThatGrandparentTraversalForComponentsCanBeBlockedEvenForAnnotatedInjections() {
MutablePicoContainer grandparent = new TieringPicoContainer();
MutablePicoContainer parent = grandparent.makeChildContainer();
MutablePicoContainer child = parent.makeChildContainer();
grandparent.addComponent(Couch.class);
grandparent.addComponent(bindKey(TiredPerson.class, Polite.class), PoliteTiredPerson.class);
grandparent.addComponent(bindKey(TiredPerson.class, Grouchy.class), GrouchyTiredPerson.class);
child.addComponent(DiscerningDoctor.class);
assertNotNull(grandparent.getComponent(TiredPerson.class, Polite.class));
assertNotNull(grandparent.getComponent(TiredPerson.class, Grouchy.class));
DiscerningDoctor dd = null;
try {
dd = child.getComponent(DiscerningDoctor.class);
fail("should have barfed");
} catch (AbstractInjector.UnsatisfiableDependenciesException e) {
// expected
}
}
@Test
public void testThatGrandparentTraversalForComponentsCanBeBlockedEvenForAnnotatedInjections2() {
MutablePicoContainer grandparent = new TieringPicoContainer();
grandparent.addComponent(Couch.class);
grandparent.addComponent(bindKey(TiredPerson.class, Polite.class), PoliteTiredPerson.class);
grandparent.addComponent(bindKey(TiredPerson.class, Grouchy.class), GrouchyTiredPerson.class);
grandparent.addComponent(DiscerningDoctor.class);
assertNotNull(grandparent.getComponent(TiredPerson.class, Polite.class));
assertNotNull(grandparent.getComponent(TiredPerson.class, Grouchy.class));
DiscerningDoctor dd = grandparent.getComponent(DiscerningDoctor.class);
assertNotNull(dd.tiredPerson);
assertTrue(dd.tiredPerson instanceof PoliteTiredPerson);
}
@Test public void testRepresentationOfContainerTree() {
TieringPicoContainer parent = new TieringPicoContainer();
parent.setName("parent");
TieringPicoContainer child = new TieringPicoContainer(parent);
child.setName("child");
parent.addComponent("st", SimpleTouchable.class);
child.addComponent("dot", DependsOnTouchable.class);
assertEquals("child:1<[Immutable]:parent:1<|", child.toString());
}
}