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.defaults;
009    
010    import org.picocontainer.MutablePicoContainer;
011    import org.picocontainer.Parameter;
012    import org.picocontainer.PicoVisitor;
013    import org.picocontainer.testmodel.Touchable;
014    
015    import org.jmock.Mock;
016    import org.jmock.MockObjectTestCase;
017    
018    import java.lang.reflect.Method;
019    import java.util.LinkedList;
020    import java.util.List;
021    
022    
023    /**
024     * @author Jörg Schaible
025     */
026    public class MethodCallingVisitorTest extends MockObjectTestCase {
027    
028        private Method add;
029        private Method touch;
030    
031        protected void setUp() throws Exception {
032            super.setUp();
033            add = List.class.getMethod("add", new Class[]{Object.class});
034            touch = Touchable.class.getMethod("touch", (Class[])null);
035        }
036    
037        public void testVisitorWillTraverseAndCall() throws Exception {
038            MutablePicoContainer parent = new DefaultPicoContainer();
039            MutablePicoContainer child = new DefaultPicoContainer();
040            parent.addChildContainer(child);
041            parent.registerComponentImplementation(List.class, LinkedList.class, new Parameter[0]);
042            child.registerComponentImplementation(List.class, LinkedList.class, new Parameter[0]);
043            List parentList = (List)parent.getComponentInstanceOfType(List.class);
044            List childList = (List)child.getComponentInstanceOfType(List.class);
045    
046            assertEquals(0, parentList.size());
047            assertEquals(0, childList.size());
048    
049            PicoVisitor visitor = new MethodCallingVisitor(add, List.class, new Object[]{Boolean.TRUE});
050            visitor.traverse(parent);
051    
052            assertEquals(1, parentList.size());
053            assertEquals(1, childList.size());
054        }
055    
056        public void testVisitsInInstantiationOrder() throws Exception {
057            Mock mockTouchable1 = mock(Touchable.class);
058            Mock mockTouchable2 = mock(Touchable.class);
059    
060            MutablePicoContainer parent = new DefaultPicoContainer();
061            MutablePicoContainer child = new DefaultPicoContainer();
062            parent.addChildContainer(child);
063            parent.registerComponentInstance(mockTouchable1.proxy());
064            child.registerComponentInstance(mockTouchable2.proxy());
065    
066            mockTouchable1.expects(once()).method("touch").id("1");
067            mockTouchable2.expects(once()).method("touch").after(mockTouchable1, "1");
068    
069            PicoVisitor visitor = new MethodCallingVisitor(touch, Touchable.class, null);
070            visitor.traverse(parent);
071        }
072    
073        public void testVisitsInReverseInstantiationOrder() throws Exception {
074            Mock mockTouchable1 = mock(Touchable.class);
075            Mock mockTouchable2 = mock(Touchable.class);
076    
077            MutablePicoContainer parent = new DefaultPicoContainer();
078            MutablePicoContainer child = new DefaultPicoContainer();
079            parent.addChildContainer(child);
080            parent.registerComponentInstance(mockTouchable1.proxy());
081            child.registerComponentInstance(mockTouchable2.proxy());
082    
083            mockTouchable2.expects(once()).method("touch").id("1");
084            mockTouchable1.expects(once()).method("touch").after(mockTouchable2, "1");
085    
086            PicoVisitor visitor = new MethodCallingVisitor(touch, Touchable.class, null, false);
087            visitor.traverse(parent);
088        }
089    }