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