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 com.thoughtworks.xstream.XStream;
013 import org.junit.Before;
014 import org.junit.Test;
015 import org.picocontainer.behaviors.Caching;
016 import org.picocontainer.behaviors.ImplementationHiding;
017 import org.picocontainer.behaviors.Locking;
018 import org.picocontainer.behaviors.PropertyApplying;
019 import org.picocontainer.behaviors.Synchronizing;
020 import org.picocontainer.containers.EmptyPicoContainer;
021 import org.picocontainer.injectors.AdaptingInjection;
022 import org.picocontainer.injectors.AnnotatedFieldInjection;
023 import org.picocontainer.injectors.AnnotatedMethodInjection;
024 import org.picocontainer.injectors.CompositeInjection;
025 import org.picocontainer.injectors.ConstructorInjection;
026 import org.picocontainer.injectors.NamedFieldInjection;
027 import org.picocontainer.injectors.NamedMethodInjection;
028 import org.picocontainer.injectors.SetterInjection;
029 import org.picocontainer.injectors.TypedFieldInjection;
030 import org.picocontainer.lifecycle.JavaEE5LifecycleStrategy;
031 import org.picocontainer.lifecycle.NullLifecycleStrategy;
032 import org.picocontainer.lifecycle.ReflectionLifecycleStrategy;
033 import org.picocontainer.lifecycle.StartableLifecycleStrategy;
034 import org.picocontainer.monitors.ConsoleComponentMonitor;
035 import org.picocontainer.monitors.NullComponentMonitor;
036
037 import java.util.HashMap;
038 import java.util.Properties;
039
040 import static junit.framework.Assert.assertTrue;
041 import static org.junit.Assert.assertEquals;
042 import static org.junit.Assert.fail;
043 import static org.picocontainer.behaviors.Behaviors.caching;
044 import static org.picocontainer.behaviors.Behaviors.implementationHiding;
045 import static org.picocontainer.behaviors.Behaviors.synchronizing;
046 import static org.picocontainer.injectors.Injectors.SDI;
047
048 @SuppressWarnings("serial")
049 public class PicoBuilderTestCase {
050
051 private XStream xs;
052 private EmptyPicoContainer parent = new EmptyPicoContainer();
053 private NullLifecycleStrategy lifecycle = new NullLifecycleStrategy();
054 private NullComponentMonitor ncm = new NullComponentMonitor();
055 private AdaptingInjection ai = new AdaptingInjection();
056
057 @Before
058 public void setUp() throws Exception {
059 xs = new XStream();
060 xs.setMode(XStream.XPATH_ABSOLUTE_REFERENCES);
061 }
062
063 @Test public void testDefaultHasNullComponentManagerAndNullLifecycleAndAdaptingInjection() {
064 Object actual = new PicoBuilder().build();
065 Object expected = new DefaultPicoContainer(ai, lifecycle, parent);
066 assertEquals(toXml(expected), toXml(actual));
067 }
068
069 @Test public void testWithStartableLifecycle() {
070 Object actual = new PicoBuilder().withLifecycle().build();
071 Object expected = new DefaultPicoContainer(ai, new StartableLifecycleStrategy(ncm), parent, ncm);
072 assertEquals(toXml(expected), toXml(actual));
073 }
074
075 public static class FooLifecycleStrategy extends NullLifecycleStrategy{
076 }
077
078 @Test public void testWithCustomLifecycle() {
079 Object actual = new PicoBuilder().withLifecycle(FooLifecycleStrategy.class).build();
080 Object expected = new DefaultPicoContainer(ai, new FooLifecycleStrategy(), parent);
081 assertEquals(toXml(expected), toXml(actual));
082 }
083
084 @Test public void testWithCustomLifecycle2() {
085 Object actual = new PicoBuilder().withLifecycle(new FooLifecycleStrategy()).build();
086 Object expected = new DefaultPicoContainer(ai, new FooLifecycleStrategy(), parent);
087 assertEquals(toXml(expected), toXml(actual));
088 }
089
090 @Test public void testWithJEE5Lifecycle() {
091
092 Object actual = new PicoBuilder().withJavaEE5Lifecycle().build();
093 Object expected = new DefaultPicoContainer(ai, new JavaEE5LifecycleStrategy(ncm), parent, ncm);
094 assertEquals(toXml(expected), toXml(actual));
095 }
096
097 @Test public void testWithLifecycleInstance() {
098
099 Object actual = new PicoBuilder().withLifecycle(new FooLifecycleStrategy()).build();
100 Object expected = new DefaultPicoContainer(ai, new FooLifecycleStrategy(), parent);
101 assertEquals(toXml(expected), toXml(actual));
102 }
103
104 @Test public void testThatLastOfInstanceOrClassLifecycleIsDominant() {
105 Object actual = new PicoBuilder().withLifecycle(new FooLifecycleStrategy()).withLifecycle().build();
106 Object expected = new DefaultPicoContainer(ai, new StartableLifecycleStrategy(ncm), parent, ncm);
107 assertEquals(toXml(expected), toXml(actual));
108 actual = new PicoBuilder().withLifecycle().withLifecycle(new FooLifecycleStrategy()).build();
109 expected = new DefaultPicoContainer(ai,
110 new FooLifecycleStrategy(), parent);
111 assertEquals(toXml(expected), toXml(actual));
112 }
113
114
115 @Test public void testWithReflectionLifecycle() {
116 Object actual = new PicoBuilder().withReflectionLifecycle().build();
117 Object expected = new DefaultPicoContainer(ai, new ReflectionLifecycleStrategy(ncm), parent, ncm);
118 assertEquals(toXml(expected), toXml(actual));
119 }
120
121
122 @Test public void testWithConsoleMonitor() {
123 Object actual = new PicoBuilder().withConsoleMonitor().build();
124 Object expected = new DefaultPicoContainer(ai, lifecycle, parent, new ConsoleComponentMonitor());
125 assertEquals(toXml(expected), toXml(actual));
126 }
127
128 @Test public void testWithConsoleMonitorAndLifecycleUseTheSameUltimateMonitor() {
129 Object actual = new PicoBuilder().withLifecycle().withConsoleMonitor().build();
130 ConsoleComponentMonitor cm = new ConsoleComponentMonitor();
131 Object expected = new DefaultPicoContainer(ai, new StartableLifecycleStrategy(cm), parent, cm);
132 assertEquals(toXml(expected), toXml(actual));
133 }
134
135
136 @Test public void testWithCustomMonitorByClass() {
137 Object actual = new PicoBuilder().withMonitor(ConsoleComponentMonitor.class).build();
138 ConsoleComponentMonitor cm = new ConsoleComponentMonitor();
139 Object expected = new DefaultPicoContainer(ai, lifecycle, parent, cm);
140 assertEquals(toXml(expected), toXml(actual));
141 }
142
143 @SuppressWarnings({ "unchecked" })
144 @Test public void testWithBogusCustomMonitorByClass() {
145 // We do unchecked assignment so we test what its really doing, and smart IDE's don't complain
146 try {
147 Class aClass = HashMap.class;
148 new PicoBuilder().withMonitor(aClass).build();
149 fail("should have barfed");
150 } catch (ClassCastException e) {
151 // expected
152 }
153 }
154
155 @Test public void testWithImplementationHiding() {
156 Object actual = new PicoBuilder().withHiddenImplementations().build();
157 Object expected = new DefaultPicoContainer(new ImplementationHiding().wrap(ai), lifecycle, parent, ncm);
158 assertEquals(toXml(expected), toXml(actual));
159 }
160
161 @Test public void testWithImplementationHidingInstance() {
162 Object actual = new PicoBuilder().withComponentFactory(new ImplementationHiding()).build();
163 Object expected = new DefaultPicoContainer(new ImplementationHiding().wrap(ai), lifecycle, parent, ncm);
164 assertEquals(toXml(expected), toXml(actual));
165 }
166
167 @Test public void testWithInjectionFactoryChain() {
168 Object actual = new PicoBuilder(SDI()).withBehaviors(caching(), synchronizing(), implementationHiding()).build();
169 Object expected = new DefaultPicoContainer(new Caching().wrap(new Synchronizing()
170 .wrap(new ImplementationHiding().wrap(new SetterInjection()))), lifecycle, parent, ncm);
171 assertEquals(toXml(expected), toXml(actual));
172 }
173
174 public static class CustomParentcontainer extends EmptyPicoContainer {}
175
176 @Test public void testCustomParentContainer() {
177 Object actual = new PicoBuilder(new CustomParentcontainer()).build();
178 Object expected = new DefaultPicoContainer(ai, lifecycle, new CustomParentcontainer(), ncm);
179 assertEquals(toXml(expected), toXml(actual));
180 }
181
182 @Test public void testBogusParentContainerBehavesAsIfNotSet() {
183 Object actual = new PicoBuilder((PicoContainer)null).build();
184 Object expected = new DefaultPicoContainer(ai, lifecycle, parent, ncm);
185 assertEquals(toXml(expected), toXml(actual));
186 }
187
188 @Test public void testParentAndChildContainersMutallyVisible() {
189 MutablePicoContainer parent = new PicoBuilder().build();
190 MutablePicoContainer actual = new PicoBuilder(parent).addChildToParent().build();
191
192 MutablePicoContainer parentExpected = new PicoBuilder().build();
193 MutablePicoContainer expected = new DefaultPicoContainer(ai, lifecycle, parentExpected, ncm);
194 parentExpected.addChildContainer(expected);
195
196 assertEquals(toXml(expected), toXml(actual));
197 boolean b = parent.removeChildContainer(actual);
198 assertTrue(b);
199 }
200
201 @Test
202 public void testParentAndChildContainersVetoedWhenParentNotMutable() {
203 try {
204 new PicoBuilder(parent).addChildToParent().build();
205 fail("should have barfed");
206 } catch (PicoCompositionException e) {
207 assertTrue(e.getMessage().contains("parent must be a MutablePicoContainer"));
208 }
209 }
210
211 @Test public void testWithSetterInjection() {
212 Object actual = new PicoBuilder().withSetterInjection().build();
213 Object expected = new DefaultPicoContainer(new SetterInjection(), lifecycle, parent, ncm);
214 assertEquals(toXml(expected), toXml(actual));
215 }
216
217 @Test public void testWithConstructorAndSetterInjectionMakesHiddenCompositeInjection() {
218 Object actual = new PicoBuilder().withConstructorInjection().withSetterInjection().build();
219 Object expected = new DefaultPicoContainer(
220 new CompositeInjection(new ConstructorInjection(), new SetterInjection()), lifecycle, parent, ncm);
221 assertEquals(toXml(expected), toXml(actual));
222 }
223
224 @Test public void testWithAnnotatedMethodDI() {
225 Object actual = new PicoBuilder().withAnnotatedMethodInjection().build();
226 Object expected = new DefaultPicoContainer(new AnnotatedMethodInjection(), lifecycle, parent, ncm);
227 assertEquals(toXml(expected), toXml(actual));
228 }
229
230 @Test public void testWithAnnotatedFieldDI() {
231 Object actual = new PicoBuilder().withAnnotatedFieldInjection().build();
232 Object expected = new DefaultPicoContainer(new AnnotatedFieldInjection(), lifecycle, parent, ncm);
233 assertEquals(toXml(expected), toXml(actual));
234 }
235
236 @Test public void testWithTypedFieldDI() {
237 Object actual = new PicoBuilder().withTypedFieldInjection().build();
238 Object expected = new DefaultPicoContainer(new TypedFieldInjection(), lifecycle, parent, ncm);
239 assertEquals(toXml(expected), toXml(actual));
240 }
241
242 @Test public void testWithCtorDI() {
243 Object actual = new PicoBuilder().withConstructorInjection().build();
244 Object expected = new DefaultPicoContainer(new ConstructorInjection(), lifecycle, parent, ncm);
245 assertEquals(toXml(expected), toXml(actual));
246 }
247
248 @Test public void testWithNamedMethodInjection() {
249 Object actual = new PicoBuilder().withNamedMethodInjection().build();
250 Object expected = new DefaultPicoContainer(new NamedMethodInjection(), lifecycle, parent, ncm);
251 assertEquals(toXml(expected), toXml(actual));
252 }
253
254 @Test public void testWithNamedFieldInjection() {
255 Object actual = new PicoBuilder().withNamedFieldInjection().build();
256 Object expected = new DefaultPicoContainer(new NamedFieldInjection(), lifecycle, parent, ncm);
257 assertEquals(toXml(expected), toXml(actual));
258 }
259
260 @Test public void testWithImplementationHidingAndSetterDI() {
261 Object actual = new PicoBuilder().withHiddenImplementations().withSetterInjection().build();
262 Object expected = new DefaultPicoContainer(new ImplementationHiding().wrap(new SetterInjection()),
263 lifecycle, parent, ncm);
264 assertEquals(toXml(expected), toXml(actual));
265 }
266
267 @Test public void testWithCachingImplementationHidingAndSetterDI() {
268 Object actual = new PicoBuilder().withCaching().withHiddenImplementations().withSetterInjection().build();
269 Object expected = new DefaultPicoContainer(new Caching().wrap(new ImplementationHiding().wrap(new SetterInjection())),
270 lifecycle, parent, ncm);
271 assertEquals(toXml(expected), toXml(actual));
272 }
273
274 @Test public void testWithSynchronizing() {
275 Object actual = new PicoBuilder().withSynchronizing().build();
276 Object expected = new DefaultPicoContainer(new Synchronizing().wrap(ai), lifecycle, parent, ncm);
277 assertEquals(toXml(expected), toXml(actual));
278 }
279
280 @Test public void testWithLocking() {
281 Object actual = new PicoBuilder().withLocking().build();
282 Object expected = new DefaultPicoContainer(new Locking().wrap(ai), lifecycle, parent, ncm);
283 assertEquals(toXml(expected), toXml(actual));
284 }
285
286 @Test public void testWithPropertyApplier() {
287 Object actual = new PicoBuilder().withPropertyApplier().build();
288 Object expected = new DefaultPicoContainer(new PropertyApplying().wrap(ai), lifecycle, parent, ncm);
289 assertEquals(toXml(expected), toXml(actual));
290 }
291
292 //TODO - fix up to refer to SomeContainerDependency
293 @Test public void testWithCustomComponentFactory() {
294 Object actual = new PicoBuilder().withCustomContainerComponent(new SomeContainerDependency()).withComponentFactory(CustomComponentFactory.class).build();
295 Object expected = new DefaultPicoContainer(new CustomComponentFactory(new SomeContainerDependency()),
296 lifecycle, parent, ncm);
297 assertEquals(toXml(expected), toXml(actual));
298 }
299
300 public static class SomeContainerDependency {
301 }
302 public static class CustomComponentFactory implements ComponentFactory {
303
304 @SuppressWarnings({ "UnusedDeclaration" })
305 public CustomComponentFactory(SomeContainerDependency someDependency) {
306 }
307
308 public ComponentAdapter createComponentAdapter(ComponentMonitor componentMonitor,
309 LifecycleStrategy lifecycleStrategy,
310 Properties componentProperties,
311 Object componentKey,
312 Class componentImplementation,
313 Parameter... parameters) throws PicoCompositionException {
314 return null;
315 }
316
317 public void verify(PicoContainer container) {
318 }
319
320 public void accept(PicoVisitor visitor) {
321 visitor.visitComponentFactory(this);
322 }
323 }
324
325
326 @Test public void testWithCustomPicoContainer() {
327 Object actual = new PicoBuilder().implementedBy(TestPicoContainer.class).build();
328 Object expected = new TestPicoContainer(ai, ncm, lifecycle, parent);
329 assertEquals(toXml(expected), toXml(actual));
330 }
331
332
333 public static class TestPicoContainer extends DefaultPicoContainer {
334 public TestPicoContainer(ComponentFactory componentFactory, ComponentMonitor monitor, LifecycleStrategy lifecycleStrategy, PicoContainer parent) {
335 super(componentFactory, lifecycleStrategy, parent, monitor);
336 }
337 }
338
339 private String toXml(Object expected) {
340 return xs.toXML(expected);
341 }
342
343
344 }