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 static org.junit.Assert.assertEquals;
011    import static org.picocontainer.tck.MockFactory.mockeryWithCountingNamingScheme;
012    
013    import java.lang.reflect.Method;
014    import java.util.LinkedList;
015    import java.util.List;
016    
017    import org.jmock.Expectations;
018    import org.jmock.Mockery;
019    import org.jmock.Sequence;
020    import org.jmock.integration.junit4.JMock;
021    import org.junit.Before;
022    import org.junit.Test;
023    import org.junit.runner.RunWith;
024    import org.picocontainer.DefaultPicoContainer;
025    import org.picocontainer.MutablePicoContainer;
026    import org.picocontainer.PicoVisitor;
027    import org.picocontainer.behaviors.Caching;
028    import org.picocontainer.testmodel.Touchable;
029    
030    
031    /**
032     * @author Jörg Schaible
033     * @author Mauro Talevi
034     */
035    @RunWith(JMock.class)
036    public class MethodCallingVisitorTest {
037    
038            private Mockery mockery = mockeryWithCountingNamingScheme();
039            
040        private Method add;
041        private Method touch;
042    
043        @Before
044        public void setUp() throws Exception {
045            add = List.class.getMethod("add", Object.class);
046            touch = Touchable.class.getMethod("touch", (Class[])null);
047        }
048    
049        @Test public void testVisitorWillTraverseAndCall() throws Exception {
050            MutablePicoContainer parent = new DefaultPicoContainer(new Caching());
051            MutablePicoContainer child = new DefaultPicoContainer(new Caching());
052            parent.addChildContainer(child);
053            parent.addComponent(List.class, LinkedList.class);
054            child.addComponent(List.class, LinkedList.class);
055            List parentList = parent.getComponent(List.class);
056            List childList = child.getComponent(List.class);
057    
058            assertEquals(0, parentList.size());
059            assertEquals(0, childList.size());
060    
061            PicoVisitor visitor = new MethodCallingVisitor(add, List.class, new Object[]{Boolean.TRUE});
062            visitor.traverse(parent);
063    
064            assertEquals(1, parentList.size());
065            assertEquals(1, childList.size());
066        }
067    
068        @Test public void testVisitsInInstantiationOrder() throws Exception {
069            final Touchable touchable1 = mockery.mock(Touchable.class);
070            final Touchable touchable2 = mockery.mock(Touchable.class);
071            
072            final Sequence sequence = mockery.sequence("touching");
073            mockery.checking(new Expectations() {{
074                one(touchable1).touch(); inSequence(sequence);
075                one(touchable2).touch(); inSequence(sequence);
076            }});
077            
078            MutablePicoContainer parent = new DefaultPicoContainer();
079            MutablePicoContainer child = new DefaultPicoContainer();
080            parent.addChildContainer(child);
081            parent.addComponent(touchable1);
082            child.addComponent(touchable2);
083    
084            PicoVisitor visitor = new MethodCallingVisitor(touch, Touchable.class, null);
085            visitor.traverse(parent);
086        }
087    
088        @Test public void testVisitsInReverseInstantiationOrder() throws Exception {
089            final Touchable touchable1 = mockery.mock(Touchable.class);
090            final Touchable touchable2 = mockery.mock(Touchable.class);
091            
092            final Sequence sequence = mockery.sequence("touching");
093            mockery.checking(new Expectations() {{
094                one(touchable2).touch(); inSequence(sequence);
095                one(touchable1).touch(); inSequence(sequence);
096            }});
097    
098            MutablePicoContainer parent = new DefaultPicoContainer();
099            MutablePicoContainer child = new DefaultPicoContainer();
100            parent.addChildContainer(child);
101            parent.addComponent(touchable1);
102            child.addComponent(touchable2);
103    
104            PicoVisitor visitor = new MethodCallingVisitor(touch, Touchable.class, null, false);
105            visitor.traverse(parent);
106        }
107    }