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 }