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