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