/*****************************************************************************
* Copyright (C) PicoContainer Organization. All rights reserved. *
* ------------------------------------------------------------------------- *
* The software in this package is published under the terms of the BSD *
* style license a copy of which has been included with this distribution in *
* the LICENSE.txt file. *
* *
* Original code by *
*****************************************************************************/
package tests.jfun.yan;
import java.util.HashMap;
import java.util.Map;
import junit.framework.TestCase;
import junit.framework.TestSuite;
import jfun.yan.*;
import jfun.yan.containers.DefaultContainer;
import tests.jfun.yan.tck.BaseContainerTestCase;
import tests.jfun.yan.testmodel.AlternativeTouchable;
import tests.jfun.yan.testmodel.DependsOnTouchable;
import tests.jfun.yan.testmodel.SimpleTouchable;
import tests.jfun.yan.testmodel.Touchable;
/**
* @author Paul Hammant
* @author Aslak Hellesøy
* @author Rafal Krzewski
* @version $Revision: 1.2 $
*/
public class ChildContainerTestCase extends BaseNonSingletonContainerTestCase {
public static void main(String[] args){
Utils.runTest(suite());
}
private static TestSuite suite(){
return new TestSuite(ChildContainerTestCase.class);
}
protected Container getContainerImpl(){
return new DefaultContainer().inherit(new jfun.yan.containers.SingletonProxyContainer());
}
public void testParentContainerWithComponentWithEqualKeyShouldBeShadowedByChild() throws Exception {
DefaultContainer parent = new DefaultContainer();
Container child = new DefaultContainer().inherit(parent);
parent.registerConstructor("key", AlternativeTouchable.class);
child.registerConstructor("key", SimpleTouchable.class);
child.registerConstructor(DependsOnTouchable.class);
DependsOnTouchable dot = (DependsOnTouchable) child.getInstanceOfType(DependsOnTouchable.class);
assertEquals(SimpleTouchable.class, dot.getTouchable().getClass());
}
/*
public void testChildComponentRegisteredAsClassShouldBePreffered() throws Exception {
DefaultContainer parent = new DefaultContainer();
Container child = new DefaultContainer().inherit(parent);
parent.registerConstructor(Touchable.class, AlternativeTouchable.class);
child.registerConstructor("key", SimpleTouchable.class);
child.registerConstructor(DependsOnTouchable.class);
DependsOnTouchable dot = (DependsOnTouchable) child.getInstanceOfType(DependsOnTouchable.class);
assertEquals(SimpleTouchable.class, dot.getTouchable().getClass());
}*/
public void testParentComponentRegisteredAsClassShouldBePreffered() throws Exception {
DefaultContainer parent = new DefaultContainer();
Container child = new DefaultContainer().inherit(parent);
parent.registerConstructor(Touchable.class, AlternativeTouchable.class);
child.registerConstructor("key", SimpleTouchable.class);
child.registerConstructor(DependsOnTouchable.class);
DependsOnTouchable dot = (DependsOnTouchable) child.getInstanceOfType(DependsOnTouchable.class);
assertEquals(AlternativeTouchable.class, dot.getTouchable().getClass());
}
public void testResolveFromParentByType() {
Container parent = new DefaultContainer();
parent.registerConstructor(Touchable.class, SimpleTouchable.class);
Container child = new DefaultContainer().inherit(parent);
child.registerConstructor(DependsOnTouchable.class);
assertNotNull(child.getInstance(DependsOnTouchable.class));
}
public void testResolveFromParentByKey() {
Container parent = new DefaultContainer();
parent.registerConstructor(Touchable.class, SimpleTouchable.class);
Container child = new DefaultContainer().inherit(parent);
child.registerComponent(Components.ctor(DependsOnTouchable.class).
withArguments(new Creator[]{Components.useType(Touchable.class)}));
/*
child.registerConstructor(DependsOnTouchable.class, DependsOnTouchable.class,
new Parameter[]{new ComponentParameter((Object) Touchable.class)});
*/
assertNotNull(child.getInstance(DependsOnTouchable.class));
}
public void testResolveFromGrandParentByType() {
Container grandParent = new DefaultContainer();
grandParent.registerConstructor(Touchable.class, SimpleTouchable.class);
Container parent = new DefaultContainer().inherit(grandParent);
Container child = new DefaultContainer().inherit(parent);
child.registerConstructor(DependsOnTouchable.class);
assertNotNull(child.getInstance(DependsOnTouchable.class));
}
public void testResolveFromGrandParentByKey() {
Container grandParent = new DefaultContainer();
grandParent.registerConstructor(Touchable.class, SimpleTouchable.class);
Container parent = new DefaultContainer().inherit(grandParent);
Container child = new DefaultContainer().inherit(parent);
child.registerComponent(Components.ctor(DependsOnTouchable.class)
.withArguments(new Creator[]{Components.useType(Touchable.class)}));
child.verify();
parent.verify();
/*
child.registerConstructor(DependsOnTouchable.class, DependsOnTouchable.class,
new Parameter[]{new ComponentParameter((Object) Touchable.class)});
*/
assertNotNull(child.getInstance(DependsOnTouchable.class));
}
public static final class Y{
private static final Y singleton = new Y();
private Y(){};
public static Y instance(){return singleton;}
}
public static final class X{
private final Y y;
public X(Y y){
this.y = y;
}
public boolean equals(Object obj){
if(obj instanceof X){
final X other = (X)obj;
return y.equals(other.y);
}
else return false;
}
}
public void testUnregisterOnlyAffectsChild()
throws Exception{
final Container parent = new DefaultContainer();
final Container child = new DefaultContainer();
final Container cc = child.inherit(parent);
cc.registerConstructor(HashMap.class, (Class[])null);
assertNull(parent.getComponent(HashMap.class));
cc.verify();
parent.registerValue(new Character('a'));
assertTrue(cc.getComponent(Character.class)!=null);
cc.verify();
parent.registerValue("parent");
child.registerValue("child");
cc.verify();
assertEquals("child", cc.getInstance(String.class));
assertEquals("child", child.getInstance(String.class));
cc.unregisterComponent(String.class);
cc.verify();
assertEquals("parent", cc.getInstance(String.class));
assertEquals("parent", cc.getInstanceOfType(String.class));
assertEquals(1, cc.getInstancesOfType(String.class).size());
child.registerComponent(Components.ctor(X.class)
.withArgument(0, Components.static_method(Y.class, "instance")));
assertEquals(4, cc.getInstances().size());
cc.verify();
final Object[] expecting = new Object[]{
"child", "parent", new Character('a'), new HashMap(),
Y.instance(), new X(Y.instance())};
/*
final InstanceListener cb = new InstanceListener(){
private int seq = 0;
public void onInstance(Object obj, Component c){
assertEquals(expecting[seq++], obj);
}
};
cc.fifo(cb);
final InstanceListener cb2 = new InstanceListener(){
private int seq = expecting.length;
public void onInstance(Object obj, Component c){
assertEquals(expecting[--seq], obj);
}
};
cc.filo(cb2);
*/
cc.verify();
cc.registerComponent(Components.value("proxy").proxy().proxy(CharSequence.class));
cc.verify();
assertEquals("proxy", ""+cc.getInstanceOfType(CharSequence.class));
assertEquals("proxy", ""+child.getInstanceOfType(CharSequence.class));
/*
cc.clearHistory();
assertEquals(0, InstanceCounter.countInstance(child));
assertEquals(0, InstanceCounter.countInstance(parent));
*/
cc.registerComponent("target", Components.method(this, "f1"));
cc.verify();
assertEquals(new Integer(1), cc.getInstance("target"));
final Map props = new HashMap();
props.put("map", Components.useType(Map.class));
cc.registerComponent("target2",
Components.bean(F1.class)
.withProperties(props));
final F1 f = (F1)cc.getInstanceOfType(F1.class);
assertEquals("parent", f.getName());
assertEquals(new HashMap(), f.getMap());
}
public int f1(String name, Map map){
return 1;
}
public static class F1{
private String name;
private Map map;
public Map getMap() {
return map;
}
public void setMap(Map map) {
this.map = map;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
}