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     * Original code by                                                          *
009     *****************************************************************************/
010    package org.picocontainer;
011    
012    import static org.junit.Assert.assertEquals;
013    import static org.junit.Assert.fail;
014    import static org.picocontainer.behaviors.Behaviors.caching;
015    import static org.picocontainer.behaviors.Behaviors.implementationHiding;
016    import static org.picocontainer.behaviors.Behaviors.synchronizing;
017    import static org.picocontainer.injectors.Injectors.SDI;
018    
019    import java.util.HashMap;
020    import java.util.Properties;
021    
022    import org.junit.Before;
023    import org.junit.Test;
024    import org.picocontainer.behaviors.Caching;
025    import org.picocontainer.behaviors.ImplementationHiding;
026    import org.picocontainer.behaviors.Locking;
027    import org.picocontainer.behaviors.PropertyApplying;
028    import org.picocontainer.behaviors.Synchronizing;
029    import org.picocontainer.containers.EmptyPicoContainer;
030    import org.picocontainer.injectors.AdaptingInjection;
031    import org.picocontainer.injectors.AnnotatedFieldInjection;
032    import org.picocontainer.injectors.AnnotatedMethodInjection;
033    import org.picocontainer.injectors.ConstructorInjection;
034    import org.picocontainer.injectors.SetterInjection;
035    import org.picocontainer.lifecycle.NullLifecycleStrategy;
036    import org.picocontainer.lifecycle.ReflectionLifecycleStrategy;
037    import org.picocontainer.lifecycle.StartableLifecycleStrategy;
038    import org.picocontainer.monitors.ConsoleComponentMonitor;
039    import org.picocontainer.monitors.NullComponentMonitor;
040    
041    import com.thoughtworks.xstream.XStream;
042    
043    @SuppressWarnings("serial")
044    public class PicoBuilderTestCase {
045    
046        private XStream xs;
047    
048        @Before
049        public void setUp() throws Exception {
050            xs = new XStream();
051            xs.setMode(XStream.XPATH_ABSOLUTE_REFERENCES);
052        }
053    
054        @Test public void testBasic() {
055            MutablePicoContainer actual = new PicoBuilder().build();
056            MutablePicoContainer expected = new DefaultPicoContainer(new AdaptingInjection(),
057                    new NullLifecycleStrategy(), new EmptyPicoContainer());
058            assertEquals(xs.toXML(expected), xs.toXML(actual));
059        }
060    
061        @Test public void testWithStartableLifecycle() {
062    
063            NullComponentMonitor ncm = new NullComponentMonitor();
064    
065            MutablePicoContainer actual = new PicoBuilder().withLifecycle().build();
066            MutablePicoContainer expected = new DefaultPicoContainer(new AdaptingInjection(),
067                    new StartableLifecycleStrategy(ncm), new EmptyPicoContainer(), ncm);
068            assertEquals(xs.toXML(expected), xs.toXML(actual));
069        }
070    
071        @Test public void testWithReflectionLifecycle() {
072            NullComponentMonitor ncm = new NullComponentMonitor();
073    
074            MutablePicoContainer actual = new PicoBuilder().withReflectionLifecycle().build();
075            MutablePicoContainer expected = new DefaultPicoContainer(new AdaptingInjection(),
076                    new ReflectionLifecycleStrategy(ncm), new EmptyPicoContainer(), ncm);
077            assertEquals(xs.toXML(expected), xs.toXML(actual));
078        }
079    
080    
081        @Test public void testWithConsoleMonitor() {
082            MutablePicoContainer actual = new PicoBuilder().withConsoleMonitor().build();
083            MutablePicoContainer expected = new DefaultPicoContainer(new AdaptingInjection(),
084                    new NullLifecycleStrategy(), new EmptyPicoContainer(), new ConsoleComponentMonitor());
085            assertEquals(xs.toXML(expected), xs.toXML(actual));
086        }
087    
088        @Test public void testWithConsoleMonitorAndLifecycleUseTheSameUltimateMonitor() {
089            MutablePicoContainer actual = new PicoBuilder().withLifecycle().withConsoleMonitor().build();
090            ConsoleComponentMonitor cm = new ConsoleComponentMonitor();
091            MutablePicoContainer expected = new DefaultPicoContainer(new AdaptingInjection(),
092                    new StartableLifecycleStrategy(cm), new EmptyPicoContainer(), cm);
093            assertEquals(xs.toXML(expected), xs.toXML(actual));
094        }
095    
096    
097        @Test public void testWithCustomMonitorByClass() {
098            MutablePicoContainer actual = new PicoBuilder().withMonitor(ConsoleComponentMonitor.class).build();
099            ConsoleComponentMonitor cm = new ConsoleComponentMonitor();
100            MutablePicoContainer expected = new DefaultPicoContainer(new AdaptingInjection(),
101                    new NullLifecycleStrategy(), new EmptyPicoContainer(), cm);
102            assertEquals(xs.toXML(expected), xs.toXML(actual));
103        }
104    
105        @SuppressWarnings({ "unchecked" })
106        @Test public void testWithBogusCustomMonitorByClass() {
107            // We do unchecked assignment so we test what its really doing, and smart IDE's don't complain
108            try {
109                Class aClass = HashMap.class;
110                new PicoBuilder().withMonitor(aClass).build();
111                fail("should have barfed");
112            } catch (ClassCastException e) {
113                // expected
114            }
115        }
116    
117        @Test public void testWithImplementationHiding() {
118            MutablePicoContainer actual = new PicoBuilder().withHiddenImplementations().build();
119            MutablePicoContainer expected = new DefaultPicoContainer(new ImplementationHiding().wrap(new AdaptingInjection()),
120                    new NullLifecycleStrategy(), new EmptyPicoContainer(), new NullComponentMonitor());
121            assertEquals(xs.toXML(expected), xs.toXML(actual));
122        }
123    
124        @Test public void testWithImplementationHidingInstance() {
125            MutablePicoContainer actual = new PicoBuilder().withComponentFactory(new ImplementationHiding()).build();
126            MutablePicoContainer expected = new DefaultPicoContainer(new ImplementationHiding().wrap(new AdaptingInjection()),
127                    new NullLifecycleStrategy(), new EmptyPicoContainer(), new NullComponentMonitor());
128            assertEquals(xs.toXML(expected), xs.toXML(actual));
129        }
130    
131        @Test public void testWithCafsListChainThingy() {
132            MutablePicoContainer actual = new PicoBuilder(SDI()).withBehaviors(caching(), synchronizing(), implementationHiding()).build();
133            MutablePicoContainer expected = new DefaultPicoContainer(new Caching().wrap(new Synchronizing().wrap(new ImplementationHiding().wrap(new SetterInjection()))),
134                    new NullLifecycleStrategy(), new EmptyPicoContainer(), new NullComponentMonitor());
135            assertEquals(xs.toXML(expected), xs.toXML(actual));
136        }
137    
138    
139        public static class CustomParentcontainer extends EmptyPicoContainer {}
140    
141        @Test public void testWithCustomParentContainer() {
142            MutablePicoContainer actual = new PicoBuilder(new CustomParentcontainer()).build();
143            MutablePicoContainer expected = new DefaultPicoContainer(new AdaptingInjection(),
144                    new NullLifecycleStrategy(), new CustomParentcontainer(), new NullComponentMonitor());
145            assertEquals(xs.toXML(expected), xs.toXML(actual));
146        }
147    
148        @Test public void testWithBogusParentContainerBehavesAsIfNotSet() {
149            MutablePicoContainer actual = new PicoBuilder((PicoContainer)null).build();
150            MutablePicoContainer expected = new DefaultPicoContainer(new AdaptingInjection(),
151                    new NullLifecycleStrategy(), new EmptyPicoContainer(), new NullComponentMonitor());
152            assertEquals(xs.toXML(expected), xs.toXML(actual));
153        }
154    
155    
156        @Test public void testWithSetterDI() {
157            MutablePicoContainer actual = new PicoBuilder().withSetterInjection().build();
158            MutablePicoContainer expected = new DefaultPicoContainer(new SetterInjection(),
159                    new NullLifecycleStrategy(), new EmptyPicoContainer(), new NullComponentMonitor());
160            assertEquals(xs.toXML(expected), xs.toXML(actual));
161        }
162    
163        @Test public void testWithAnnotatedMethodDI() {
164                MutablePicoContainer actual = new PicoBuilder().withAnnotatedMethodInjection().build();
165            MutablePicoContainer expected = new DefaultPicoContainer(new AnnotatedMethodInjection(),
166                    new NullLifecycleStrategy(), new EmptyPicoContainer(), new NullComponentMonitor());
167            assertEquals(xs.toXML(expected), xs.toXML(actual));
168        }
169    
170        @Test public void testWithAnnotatedFieldDI() {
171                MutablePicoContainer actual = new PicoBuilder().withAnnotatedFieldInjection().build();
172            MutablePicoContainer expected = new DefaultPicoContainer(new AnnotatedFieldInjection(),
173                    new NullLifecycleStrategy(), new EmptyPicoContainer(), new NullComponentMonitor());
174            assertEquals(xs.toXML(expected), xs.toXML(actual));
175        }
176    
177        @Test public void testWithCtorDI() {
178            MutablePicoContainer actual = new PicoBuilder().withConstructorInjection().build();
179            MutablePicoContainer expected = new DefaultPicoContainer(new ConstructorInjection(),
180                    new NullLifecycleStrategy(), new EmptyPicoContainer(), new NullComponentMonitor());
181            assertEquals(xs.toXML(expected), xs.toXML(actual));
182        }
183    
184        @Test public void testWithImplementationHidingAndSetterDI() {
185            MutablePicoContainer actual = new PicoBuilder().withHiddenImplementations().withSetterInjection().build();
186            MutablePicoContainer expected = new DefaultPicoContainer(new ImplementationHiding().wrap(new SetterInjection()),
187                    new NullLifecycleStrategy(), new EmptyPicoContainer(), new NullComponentMonitor());
188            assertEquals(xs.toXML(expected), xs.toXML(actual));
189        }
190    
191        @Test public void testWithCachingImplementationHidingAndSetterDI() {
192            MutablePicoContainer actual = new PicoBuilder().withCaching().withHiddenImplementations().withSetterInjection().build();
193            MutablePicoContainer expected = new DefaultPicoContainer(new Caching().wrap(new ImplementationHiding().wrap(new SetterInjection())),
194                    new NullLifecycleStrategy(), new EmptyPicoContainer(), new NullComponentMonitor());
195            assertEquals(xs.toXML(expected), xs.toXML(actual));
196        }
197    
198        @Test public void testWithSynchronizing() {
199            MutablePicoContainer actual = new PicoBuilder().withSynchronizing().build();
200            MutablePicoContainer expected = new DefaultPicoContainer(new Synchronizing().wrap(new AdaptingInjection()),
201                    new NullLifecycleStrategy(), new EmptyPicoContainer(), new NullComponentMonitor());
202            assertEquals(xs.toXML(expected), xs.toXML(actual));
203        }
204    
205        @Test public void testWithLocking() {
206            MutablePicoContainer actual = new PicoBuilder().withLocking().build();
207            MutablePicoContainer expected = new DefaultPicoContainer(new Locking().wrap(new AdaptingInjection()),
208                    new NullLifecycleStrategy(), new EmptyPicoContainer(), new NullComponentMonitor());
209            assertEquals(xs.toXML(expected), xs.toXML(actual));
210        }
211    
212        @Test public void testWithPropertyApplier() {
213            MutablePicoContainer actual = new PicoBuilder().withPropertyApplier().build();
214            MutablePicoContainer expected = new DefaultPicoContainer(new PropertyApplying().wrap(new AdaptingInjection()),
215                    new NullLifecycleStrategy(), new EmptyPicoContainer(), new NullComponentMonitor());
216            assertEquals(xs.toXML(expected), xs.toXML(actual));
217        }
218    
219        //TODO - fix up to refer to SomeContainerDependency
220        @Test public void testWithCustomComponentFactory() {
221            MutablePicoContainer actual = new PicoBuilder().withCustomContainerComponent(new SomeContainerDependency()).withComponentFactory(CustomComponentFactory.class).build();
222            MutablePicoContainer expected = new DefaultPicoContainer(new CustomComponentFactory(new SomeContainerDependency()),
223                    new NullLifecycleStrategy(), new EmptyPicoContainer(), new NullComponentMonitor());
224            assertEquals(xs.toXML(expected), xs.toXML(actual));
225        }
226    
227        public static class SomeContainerDependency {
228        }
229        public static class CustomComponentFactory implements ComponentFactory {
230    
231            @SuppressWarnings({ "UnusedDeclaration" })
232            public CustomComponentFactory(SomeContainerDependency someDependency) {
233            }
234    
235            public ComponentAdapter createComponentAdapter(ComponentMonitor componentMonitor,
236                                                           LifecycleStrategy lifecycleStrategy,
237                                                           Properties componentProperties,
238                                                           Object componentKey,
239                                                           Class componentImplementation,
240                                                           Parameter... parameters) throws PicoCompositionException {
241                return null;
242            }
243    
244            public void verify(PicoContainer container) {
245            }
246    
247            public void accept(PicoVisitor visitor) {
248                visitor.visitComponentFactory(this);
249            }
250        }
251    
252    
253        @Test public void testWithCustomPicoContainer() {
254            MutablePicoContainer actual = new PicoBuilder().implementedBy(TestPicoContainer.class).build();
255            MutablePicoContainer expected = new TestPicoContainer(new AdaptingInjection(),
256                    new NullComponentMonitor(), new NullLifecycleStrategy(), new EmptyPicoContainer());
257            assertEquals(xs.toXML(expected), xs.toXML(actual));
258        }
259    
260    
261        public static class TestPicoContainer extends DefaultPicoContainer {
262            public TestPicoContainer(ComponentFactory componentFactory, ComponentMonitor monitor, LifecycleStrategy lifecycleStrategy, PicoContainer parent) {
263                super(componentFactory, lifecycleStrategy, parent, monitor);
264            }
265        }
266    
267    
268    }