001    /*****************************************************************************
002     * Copyright (C) PicoContainer Organization. All rights reserved.            *
003     * ------------------------------------------------------------------------- *
004     * The software in this package is published under the terms of the BSD      *
005     * style license a copy of which has been included with this distribution in *
006     * the LICENSE.txt file.                                                     *
007     *****************************************************************************/
008    package org.picocontainer.visitors;
009    
010    import org.picocontainer.MutablePicoContainer;
011    import org.picocontainer.PicoVisitor;
012    import org.picocontainer.DefaultPicoContainer;
013    import org.picocontainer.injectors.AdaptiveInjectionFactory;
014    import org.picocontainer.behaviors.CachingBehaviorFactory;
015    import org.picocontainer.visitors.MethodCallingVisitor;
016    import org.picocontainer.testmodel.Touchable;
017    
018    import org.jmock.Mock;
019    import org.jmock.MockObjectTestCase;
020    
021    import java.lang.reflect.Method;
022    import java.util.LinkedList;
023    import java.util.List;
024    
025    
026    /**
027     * @author Jörg Schaible
028     */
029    public class MethodCallingVisitorTest extends MockObjectTestCase {
030    
031        private Method add;
032        private Method touch;
033    
034        protected void setUp() throws Exception {
035            super.setUp();
036            add = List.class.getMethod("add", Object.class);
037            touch = Touchable.class.getMethod("touch", (Class[])null);
038        }
039    
040        public void testVisitorWillTraverseAndCall() throws Exception {
041            MutablePicoContainer parent = new DefaultPicoContainer(new CachingBehaviorFactory());
042            MutablePicoContainer child = new DefaultPicoContainer(new CachingBehaviorFactory());
043            parent.addChildContainer(child);
044            parent.addComponent(List.class, LinkedList.class);
045            child.addComponent(List.class, LinkedList.class);
046            List parentList = parent.getComponent(List.class);
047            List childList = child.getComponent(List.class);
048    
049            assertEquals(0, parentList.size());
050            assertEquals(0, childList.size());
051    
052            PicoVisitor visitor = new MethodCallingVisitor(add, List.class, new Object[]{Boolean.TRUE});
053            visitor.traverse(parent);
054    
055            assertEquals(1, parentList.size());
056            assertEquals(1, childList.size());
057        }
058    
059        public void testVisitsInInstantiationOrder() throws Exception {
060            Mock mockTouchable1 = mock(Touchable.class);
061            Mock mockTouchable2 = mock(Touchable.class);
062    
063            MutablePicoContainer parent = new DefaultPicoContainer();
064            MutablePicoContainer child = new DefaultPicoContainer();
065            parent.addChildContainer(child);
066            parent.addComponent(mockTouchable1.proxy());
067            child.addComponent(mockTouchable2.proxy());
068    
069            mockTouchable1.expects(once()).method("touch").id("1");
070            mockTouchable2.expects(once()).method("touch").after(mockTouchable1, "1");
071    
072            PicoVisitor visitor = new MethodCallingVisitor(touch, Touchable.class, null);
073            visitor.traverse(parent);
074        }
075    
076        public void testVisitsInReverseInstantiationOrder() throws Exception {
077            Mock mockTouchable1 = mock(Touchable.class);
078            Mock mockTouchable2 = mock(Touchable.class);
079    
080            MutablePicoContainer parent = new DefaultPicoContainer();
081            MutablePicoContainer child = new DefaultPicoContainer();
082            parent.addChildContainer(child);
083            parent.addComponent(mockTouchable1.proxy());
084            child.addComponent(mockTouchable2.proxy());
085    
086            mockTouchable2.expects(once()).method("touch").id("1");
087            mockTouchable1.expects(once()).method("touch").after(mockTouchable2, "1");
088    
089            PicoVisitor visitor = new MethodCallingVisitor(touch, Touchable.class, null, false);
090            visitor.traverse(parent);
091        }
092    }