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.junit.Assert.assertTrue;
012    
013    import java.util.ArrayList;
014    import java.util.HashSet;
015    import java.util.List;
016    import java.util.Set;
017    
018    import org.junit.After;
019    import org.junit.Before;
020    import org.junit.Test;
021    import org.picocontainer.ComponentAdapter;
022    import org.picocontainer.ComponentFactory;
023    import org.picocontainer.DefaultPicoContainer;
024    import org.picocontainer.MutablePicoContainer;
025    import org.picocontainer.NameBinding;
026    import org.picocontainer.Parameter;
027    import org.picocontainer.PicoContainer;
028    import org.picocontainer.PicoVisitor;
029    import org.picocontainer.behaviors.Caching;
030    import org.picocontainer.behaviors.ImplementationHiding;
031    import org.picocontainer.injectors.ConstructorInjection;
032    import org.picocontainer.injectors.ConstructorInjector;
033    import org.picocontainer.injectors.SetterInjector;
034    import org.picocontainer.lifecycle.NullLifecycleStrategy;
035    import org.picocontainer.monitors.NullComponentMonitor;
036    import org.picocontainer.parameters.ConstantParameter;
037    
038    /**
039     * @author Michael Rimov
040     */
041    public class TraversalCheckingVisitorTest {
042    
043        private MutablePicoContainer pico;
044    
045        private MutablePicoContainer child;
046    
047        private ComponentAdapter parentAdapter;
048    
049        private ComponentAdapter childAdapter;
050    
051        @Before
052        public void setUp() throws Exception {
053    
054            pico = new DefaultPicoContainer();
055            SetterInjector componentAdapter = new SetterInjector(StringBuffer.class, StringBuffer.class,
056                                                                 null, new NullComponentMonitor(), new NullLifecycleStrategy(),
057                                                                 "set", false);
058            parentAdapter = pico.addAdapter(componentAdapter).getComponentAdapter(StringBuffer.class, (NameBinding) null);
059            child = pico.makeChildContainer();
060            ConstructorInjector adapter = new ConstructorInjector(ArrayList.class, ArrayList.class, new Parameter[] {new ConstantParameter(3)}, new NullComponentMonitor(), new NullLifecycleStrategy(), false);
061            childAdapter = child.addAdapter(adapter).getComponentAdapter(ArrayList.class, (NameBinding) null);
062        }
063    
064        @After
065        public void tearDown() throws Exception {
066            child = null;
067            pico = null;
068            parentAdapter = null;
069            childAdapter = null;
070        }
071    
072        @Test public void testVisitComponentAdapter() {
073            final int numExpectedComponentAdapters = 2;
074            final List<ComponentAdapter> allAdapters = new ArrayList<ComponentAdapter>();
075    
076            Set<ComponentAdapter> knownAdapters = new HashSet<ComponentAdapter>();
077            knownAdapters.add(parentAdapter);
078            knownAdapters.add(childAdapter);
079    
080            PicoVisitor containerCollector = new TraversalCheckingVisitor() {
081                public void visitComponentAdapter(ComponentAdapter adapter) {
082                    super.visitComponentAdapter(adapter); //Calls checkTraversal for us.
083                    allAdapters.add(adapter);
084                }
085            };
086            containerCollector.traverse(pico);
087    
088            assertEquals(numExpectedComponentAdapters, allAdapters.size());
089    
090            for (ComponentAdapter allAdapter : allAdapters) {
091                boolean knownAdapter = knownAdapters.remove(allAdapter);
092                assertTrue("Encountered unknown adapter in collection: " + allAdapters.toString(), knownAdapter);
093            }
094    
095            assertTrue("All adapters should match known adapters.", knownAdapters.size() == 0);
096        }
097    
098        @Test public void testVisitComponentFactory() {
099            final List<ComponentFactory> allFactories = new ArrayList<ComponentFactory>();
100    
101            DefaultPicoContainer dpc = new DefaultPicoContainer(new Caching().wrap(new ImplementationHiding().wrap(new ConstructorInjection())));
102    
103            PicoVisitor containerCollector = new TraversalCheckingVisitor() {
104                public void visitComponentFactory(ComponentFactory factory) {
105                    super.visitComponentFactory(factory); //Calls checkTraversal for us.
106                    allFactories.add(factory);
107                }
108            };
109            containerCollector.traverse(dpc);
110    
111            assertEquals(3, allFactories.size());
112            assertTrue(allFactories.get(0) instanceof Caching);
113            assertTrue(allFactories.get(1) instanceof ImplementationHiding);
114            assertTrue(allFactories.get(2) instanceof ConstructorInjection);
115    
116        }
117    
118        @Test public void testVisitContainer() {
119            final List<PicoContainer> allContainers = new ArrayList<PicoContainer>();
120            final int expectedNumberOfContainers = 2;
121    
122            PicoVisitor containerCollector = new TraversalCheckingVisitor() {
123                public boolean visitContainer(PicoContainer pico) {
124                    super.visitContainer(pico); //Calls checkTraversal for us.
125                    allContainers.add(pico);
126                    return CONTINUE_TRAVERSAL;
127                }
128            };
129    
130            containerCollector.traverse(pico);
131    
132            assertTrue(allContainers.size() == expectedNumberOfContainers);
133    
134            Set<MutablePicoContainer> knownContainers = new HashSet<MutablePicoContainer>();
135            knownContainers.add(pico);
136            knownContainers.add(child);
137            for (PicoContainer oneContainer : allContainers) {
138                boolean knownContainer = knownContainers.remove(oneContainer);
139                assertTrue("Found a picocontainer that wasn't previously expected.", knownContainer);
140            }
141    
142            assertTrue("All containers must match what is returned by traversal.",
143                knownContainers.size() == 0);
144    
145        }
146    
147    
148        @Test public void testVisitParameter() {
149            final List allParameters = new ArrayList();
150    
151            PicoVisitor containerCollector = new TraversalCheckingVisitor() {
152                public void visitParameter(Parameter param) {
153                    super.visitParameter(param); //Calls checkTraversal for us.
154                    allParameters.add(param);
155                }
156            };
157    
158            containerCollector.traverse(pico);
159    
160            assertTrue(allParameters.size() == 1);
161            assertTrue(allParameters.get(0) instanceof ConstantParameter);
162            assertTrue( ( (ConstantParameter) allParameters.get(0)).resolveInstance(null, null, null, null, false, null) instanceof Integer);
163            assertEquals(3, ( (Integer) ( (ConstantParameter) allParameters.get(0)).resolveInstance(null, null,
164                null, null, false, null)).intValue());
165        }
166    
167    }