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 }