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 *****************************************************************************/
008package org.picocontainer.visitors;
009
010import org.junit.After;
011import org.junit.Before;
012import org.junit.Test;
013import org.picocontainer.ComponentAdapter;
014import org.picocontainer.ComponentFactory;
015import org.picocontainer.DefaultPicoContainer;
016import org.picocontainer.MutablePicoContainer;
017import org.picocontainer.NameBinding;
018import org.picocontainer.Parameter;
019import org.picocontainer.PicoContainer;
020import org.picocontainer.PicoVisitor;
021import org.picocontainer.behaviors.Caching;
022import org.picocontainer.behaviors.ImplementationHiding;
023import org.picocontainer.injectors.ConstructorInjection;
024import org.picocontainer.injectors.ConstructorInjector;
025import org.picocontainer.injectors.SetterInjector;
026import org.picocontainer.monitors.NullComponentMonitor;
027import org.picocontainer.parameters.ConstantParameter;
028
029import java.util.ArrayList;
030import java.util.HashSet;
031import java.util.List;
032import java.util.Set;
033
034import static org.junit.Assert.assertEquals;
035import static org.junit.Assert.assertTrue;
036
037/**
038 * @author Michael Rimov
039 */
040public 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}