1 /****************************************************************************** 2 * Copyright (C) PicoContainer Organization. All rights reserved. * 3 * ------------------------------------------------------------------------- * 4 * The software in this package is published under the terms of the BSD * 5 * style license a copy of which has been included with this distribution in * 6 * the LICENSE.txt file. * 7 * * 8 * Idea by Rachel Davies, Original code by Aslak Hellesoy and Paul Hammant * 9 *****************************************************************************/ 10 11 package org.picocontainer.defaults; 12 13 import junit.framework.TestCase; 14 import org.picocontainer.internals.ComponentFactory; 15 import org.picocontainer.internals.Parameter; 16 import org.picocontainer.PicoInitializationException; 17 import org.picocontainer.PicoInstantiationException; 18 import org.picocontainer.PicoIntrospectionException; 19 import org.picocontainer.PicoRegistrationException; 20 import org.picocontainer.RegistrationPicoContainer; 21 import org.picocontainer.internals.ComponentSpecification; 22 import org.picocontainer.internals.ComponentParameter; 23 import org.picocontainer.testmodel.DependsOnTouchable; 24 import org.picocontainer.testmodel.DependsOnTwoComponents; 25 import org.picocontainer.testmodel.SimpleTouchable; 26 import org.picocontainer.testmodel.Touchable; 27 import org.picocontainer.testmodel.Webster; 28 29 import java.io.Serializable; 30 import java.lang.reflect.UndeclaredThrowableException; 31 import java.util.ArrayList; 32 import java.util.Arrays; 33 import java.util.HashMap; 34 import java.util.List; 35 import java.util.Map; 36 import java.util.Vector; 37 38 public class OldDefaultPicoContainerTestCase extends TestCase { 39 40 public interface Peelable { 41 void peel(); 42 } 43 44 public interface Washable { 45 void wash(); 46 } 47 48 public interface Startable { 49 void start(); 50 51 void stop(); 52 } 53 54 public static class PeelableComponent implements Peelable { 55 boolean wasPeeled; 56 57 public PeelableComponent() { 58 } 59 60 public void peel() { 61 wasPeeled = true; 62 } 63 } 64 65 public static class CoincidentallyPeelableComponent { 66 boolean wasPeeled; 67 68 public void peel() { 69 wasPeeled = true; 70 } 71 } 72 73 public static class PeelableAndWashableComponent extends PeelableComponent implements Washable { 74 boolean wasWashed; 75 76 public void wash() { 77 wasWashed = true; 78 } 79 } 80 81 public static class Recorder { 82 List thingsThatHappened = new ArrayList(); 83 84 public void record(String something) { 85 thingsThatHappened.add(something); 86 } 87 88 public String getWhatHappened(int i) { 89 return (String) thingsThatHappened.get(i); 90 } 91 92 public void clear() { 93 thingsThatHappened.clear(); 94 } 95 } 96 97 public static abstract class RecordingAware { 98 protected Recorder recorder; 99 100 public RecordingAware(Recorder recorder) { 101 this.recorder = recorder; 102 String name = getClass().getName(); 103 String niceName = name.substring(name.lastIndexOf("$") + 1); 104 recorder.record("instantiated " + niceName); 105 } 106 } 107 108 public static class RecordingAware2 extends RecordingAware implements Washable { 109 public RecordingAware2(Recorder recorder) { 110 super(recorder); 111 } 112 113 public void wash() { 114 recorder.record("RecordingAware2.wash()"); 115 } 116 } 117 118 public static class RecordingAware3 extends RecordingAware implements Washable { 119 public RecordingAware3(Recorder recorder, RecordingAware2 a) { 120 super(recorder); 121 a.toString(); 122 } 123 124 public void wash() { 125 recorder.record("RecordingAware3.wash()"); 126 } 127 } 128 129 public static class RecordingAware4 extends RecordingAware implements Washable { 130 public RecordingAware4(Recorder recorder, RecordingAware2 a, RecordingAware3 b) { 131 super(recorder); 132 a.toString(); 133 b.toString(); 134 } 135 136 public void wash() { 137 recorder.record("RecordingAware4.wash()"); 138 } 139 } 140 141 public void testApplyInterfaceMethodsToWholeContainer() throws PicoRegistrationException, PicoInitializationException { 142 143 DefaultPicoContainer pico = new DefaultPicoContainer.Default(); 144 pico.registerComponentByClass(PeelableComponent.class); 145 pico.registerComponentByClass(CoincidentallyPeelableComponent.class); 146 pico.instantiateComponents(); 147 148 assertEquals(2, pico.getComponents().size()); 149 150 Peelable myPeelableContainer = (Peelable) pico.getComponentMulticaster(); 151 152 myPeelableContainer.peel(); 153 154 PeelableComponent peelableComponent = 155 (PeelableComponent) pico.getComponent(PeelableComponent.class); 156 CoincidentallyPeelableComponent notReallyPeelableComponent = 157 (CoincidentallyPeelableComponent) pico.getComponent(CoincidentallyPeelableComponent.class); 158 159 assertTrue(peelableComponent.wasPeeled); 160 assertFalse(notReallyPeelableComponent.wasPeeled); 161 } 162 163 public void testWorksWithMultipleInterfaces() throws PicoRegistrationException, PicoInitializationException { 164 165 DefaultPicoContainer pico = new DefaultPicoContainer.Default(); 166 167 pico.registerComponentByClass(PeelableComponent.class); 168 pico.registerComponentByClass(CoincidentallyPeelableComponent.class); 169 pico.registerComponentByClass(PeelableAndWashableComponent.class); 170 171 pico.instantiateComponents(); 172 173 Object myPeelableAndWashableContainer = pico.getComponentMulticaster(); 174 175 ((Washable) myPeelableAndWashableContainer).wash(); 176 177 PeelableComponent peelableComponent = 178 (PeelableComponent) pico.getComponent(PeelableComponent.class); 179 CoincidentallyPeelableComponent notReallyPeelableComponent = 180 (CoincidentallyPeelableComponent) pico.getComponent(CoincidentallyPeelableComponent.class); 181 PeelableAndWashableComponent washAndPeel = 182 (PeelableAndWashableComponent) pico.getComponent(PeelableAndWashableComponent.class); 183 ; 184 185 assertFalse(washAndPeel.wasPeeled); 186 assertTrue(washAndPeel.wasWashed); 187 188 ((Peelable) myPeelableAndWashableContainer).peel(); 189 190 assertTrue(peelableComponent.wasPeeled); 191 assertTrue(washAndPeel.wasPeeled); 192 assertTrue(washAndPeel.wasWashed); 193 assertFalse(notReallyPeelableComponent.wasPeeled); 194 195 } 196 197 public void testAsCallsAllComponents() throws PicoRegistrationException, PicoInitializationException { 198 199 DefaultPicoContainer pico = new DefaultPicoContainer.Default(); 200 201 //an unmanaged component 202 PeelableComponent peelableComponent = new PeelableComponent(); 203 pico.registerComponent(PeelableComponent.class, peelableComponent); 204 205 //some managed ones 206 pico.registerComponentByClass(CoincidentallyPeelableComponent.class); 207 pico.registerComponentByClass(PeelableAndWashableComponent.class); 208 209 pico.instantiateComponents(); 210 211 Object myPeelableAndWashableContainer = pico.getComponentMulticaster(true, true); 212 213 ((Washable) myPeelableAndWashableContainer).wash(); 214 215 CoincidentallyPeelableComponent notReallyPeelableComponent = 216 (CoincidentallyPeelableComponent) pico.getComponent(CoincidentallyPeelableComponent.class); 217 PeelableAndWashableComponent washAndPeel = 218 (PeelableAndWashableComponent) pico.getComponent(PeelableAndWashableComponent.class); 219 220 assertFalse(washAndPeel.wasPeeled); 221 assertTrue(washAndPeel.wasWashed); 222 223 ((Peelable) myPeelableAndWashableContainer).peel(); 224 225 assertTrue(peelableComponent.wasPeeled); 226 assertTrue(washAndPeel.wasPeeled); 227 assertTrue(washAndPeel.wasWashed); 228 assertFalse(notReallyPeelableComponent.wasPeeled); 229 230 } 231 232 public void testBespokeLifecycleCallsComponentsInReverseOrder() throws PicoRegistrationException, PicoInitializationException { 233 234 DefaultPicoContainer pico = new DefaultPicoContainer.Default(); 235 236 Recorder recorder = new Recorder(); 237 238 pico.registerComponent(Recorder.class, recorder); 239 pico.registerComponent(RecordingAware2.class, RecordingAware2.class); 240 pico.registerComponent(RecordingAware3.class, RecordingAware3.class); 241 pico.registerComponent(RecordingAware4.class, RecordingAware4.class); 242 243 pico.instantiateComponents(); 244 245 assertEquals("instantiated RecordingAware2", recorder.getWhatHappened(0)); 246 assertEquals("instantiated RecordingAware3", recorder.getWhatHappened(1)); 247 assertEquals("instantiated RecordingAware4", recorder.getWhatHappened(2)); 248 249 recorder.clear(); 250 251 Object washableContainer = 252 pico.getComponentMulticaster(false, true); 253 254 ((Washable) washableContainer).wash(); 255 256 assertEquals("RecordingAware4.wash()", recorder.getWhatHappened(0)); 257 assertEquals("RecordingAware3.wash()", recorder.getWhatHappened(1)); 258 assertEquals("RecordingAware2.wash()", recorder.getWhatHappened(2)); 259 260 } 261 262 public void testGetAggregateComponentProxyOnlyCallsManagedComponents() throws PicoRegistrationException, PicoInitializationException { 263 264 DefaultPicoContainer pico = new DefaultPicoContainer.Default(); 265 266 Recorder recorder = new Recorder(); 267 268 RecordingAware2 unmanagedComponent = new RecordingAware2(recorder); 269 270 recorder.clear(); 271 272 pico.registerComponent(Recorder.class, recorder); 273 pico.registerComponent(RecordingAware2.class, unmanagedComponent); 274 pico.registerComponentByClass(RecordingAware3.class); 275 pico.registerComponentByClass(RecordingAware4.class); 276 277 pico.instantiateComponents(); 278 279 assertEquals("instantiated RecordingAware3", recorder.getWhatHappened(0)); 280 assertEquals("instantiated RecordingAware4", recorder.getWhatHappened(1)); 281 282 recorder.clear(); 283 284 Object washableContainer = 285 pico.getComponentMulticaster(false, false); 286 287 ((Washable) washableContainer).wash(); 288 289 assertEquals("RecordingAware4.wash()", recorder.getWhatHappened(0)); 290 assertEquals("RecordingAware3.wash()", recorder.getWhatHappened(1)); 291 assertTrue( 292 "Unmanaged components should not be called by an getComponentMulticaster() proxy", 293 !recorder.thingsThatHappened.contains("RecordingAware2.wash()")); 294 } 295 296 public void testPeelableAndWashable() throws PicoInitializationException, PicoRegistrationException { 297 298 DefaultPicoContainer pico = new DefaultPicoContainer.Default(); 299 300 pico.registerComponentByClass(PeelableComponent.class); 301 pico.registerComponentByClass(PeelableAndWashableComponent.class); 302 303 pico.instantiateComponents(); 304 305 Object proxy = pico.getComponentMulticaster(); 306 307 Peelable peelable = (Peelable) proxy; 308 peelable.peel(); 309 310 Washable washable = (Washable) proxy; 311 washable.wash(); 312 313 PeelableComponent pComp = (PeelableComponent) pico.getComponent(PeelableComponent.class); 314 PeelableAndWashableComponent peelNWash = (PeelableAndWashableComponent) pico.getComponent(PeelableAndWashableComponent.class); 315 316 assertTrue(pComp.wasPeeled); 317 assertTrue(peelNWash.wasWashed); 318 319 } 320 321 public static interface FoodFactory { 322 Food makeFood(); 323 324 int hashCode(); 325 } 326 327 public abstract static class AbstractFoodFactory extends RecordingAware implements FoodFactory { 328 public AbstractFoodFactory(Recorder recorder) { 329 super(recorder); 330 } 331 } 332 333 public static class AppleFactory extends AbstractFoodFactory { 334 public AppleFactory(Recorder recorder) { 335 super(recorder); 336 } 337 338 public Food makeFood() { 339 return new Apple(recorder); 340 } 341 } 342 343 public static class OrangeFactory extends AbstractFoodFactory { 344 public OrangeFactory(Recorder recorder) { 345 super(recorder); 346 } 347 348 public Food makeFood() { 349 return new Orange(recorder); 350 } 351 } 352 353 public static interface Food { 354 void eat(); 355 356 int magic(); 357 } 358 359 public abstract static class AbstractFood extends RecordingAware implements Food { 360 public AbstractFood(Recorder recorder) { 361 super(recorder); 362 } 363 } 364 365 public static interface Boozable { 366 String getBooze(); 367 } 368 369 public static class Apple extends AbstractFood implements Boozable { 370 public Apple(Recorder recorder) { 371 super(recorder); 372 } 373 374 public void eat() { 375 recorder.record("Apple eaten"); 376 } 377 378 public int magic() { 379 return 5; 380 } 381 382 public String getBooze() { 383 return "Calvados"; 384 } 385 } 386 387 public static class Orange extends AbstractFood { 388 public Orange(Recorder recorder) { 389 super(recorder); 390 } 391 392 public void eat() { 393 recorder.record("Orange eaten"); 394 } 395 396 public int magic() { 397 return 11; 398 } 399 } 400 401 402 public void testRecursiveAggregation() 403 throws NotConcreteRegistrationException, AssignabilityRegistrationException, 404 DuplicateComponentKeyRegistrationException, PicoInitializationException { 405 DefaultPicoContainer pico = new DefaultPicoContainer.Default(); 406 pico.registerComponentByClass(Recorder.class); 407 pico.registerComponentByClass(AppleFactory.class); 408 pico.registerComponentByClass(OrangeFactory.class); 409 410 pico.instantiateComponents(); 411 412 // Get the proxy for AppleFactory and OrangeFactory 413 FoodFactory foodFactory = (FoodFactory) pico.getComponentMulticaster(); 414 415 int foodFactoryCode = foodFactory.hashCode(); 416 assertFalse("Should get a real hashCode", Integer.MIN_VALUE == foodFactoryCode); 417 418 // Get the proxied Food and eat it. Should eat the orange and apple in one go. 419 Food food = foodFactory.makeFood(); 420 food.eat(); 421 422 String s = food.toString(); 423 assertTrue("toString() should return the result from the invocation handler", s.indexOf("AggregatingInvocationHandler") != -1); 424 425 // Try to call a hashCode on a "recursive" proxy. 426 food.hashCode(); 427 428 // Try to call a method returning a primitive. 429 try { 430 food.magic(); 431 fail("Should fail because there is no sensible return value"); 432 } catch (UndeclaredThrowableException e) { 433 // That's expected, and ok. 434 } 435 436 // Get some booze. Should be ok since only one is Boozable 437 Boozable boozable = (Boozable) food; 438 assertEquals("Calvados", boozable.getBooze()); 439 440 // Test hashCode() and equals(Object) 441 List list = new ArrayList(); 442 list.add(food); 443 assertTrue(list.contains(food)); 444 assertEquals(food, food); 445 446 // Get the recorder so we can see if the apple and orange were actually eaten 447 Recorder recorder = (Recorder) pico.getComponent(Recorder.class); 448 assertTrue("Apple should have been eaten now. Recorded: " + recorder.thingsThatHappened, recorder.thingsThatHappened.contains("Apple eaten")); 449 assertTrue("Orange should have been eaten now. Recorded: " + recorder.thingsThatHappened, recorder.thingsThatHappened.contains("Orange eaten")); 450 451 } 452 453 // public static interface PeelableAndWashableContainer extends PeelableAndWashable, RegistrationPicoContainer { 454 // 455 // } 456 457 // public void testPeelableAndWashableContainer() throws NoPicoSuitableConstructorException, PicoRegistrationException, PicoStartException { 458 // 459 // PeelableAndWashableContainer pawContainer = (PeelableAndWashableContainer) 460 // new MorphingHierarchicalPicoContainer( 461 // new NullContainer(), 462 // new NullLifecycleManager(), 463 // new DefaultComponentFactory()) 464 // .as(PeelableAndWashableContainer.class); 465 // 466 // pawContainer.registerComponent(PeelableComponent.class); 467 // pawContainer.registerComponent(PeelableAndWashableComponent.class); 468 // 469 // pawContainer.instantiateComponents(); 470 // 471 // pawContainer.wash(); 472 // pawContainer.peel(); 473 // 474 // PeelableComponent pComp = (PeelableComponent) pawContainer.getComponent(PeelableComponent.class); 475 // PeelableAndWashableComponent peelNWash = (PeelableAndWashableComponent) pawContainer.getComponent(PeelableAndWashableComponent.class); 476 // 477 // assertTrue(pComp.wasPeeled); 478 // assertTrue(peelNWash.wasWashed); 479 // 480 // } 481 482 483 //TODO - move to AbstractComponentRegistryTestCase 484 public void testGetComponentSpecification() throws NotConcreteRegistrationException, DuplicateComponentKeyRegistrationException, AssignabilityRegistrationException, AmbiguousComponentResolutionException, PicoIntrospectionException { 485 DefaultComponentRegistry dcr = new DefaultComponentRegistry(); 486 DefaultPicoContainer pico = new DefaultPicoContainer.WithComponentRegistry(dcr); 487 488 assertNull(dcr.findImplementingComponentSpecification(Touchable.class)); 489 pico.registerComponentByClass(SimpleTouchable.class); 490 assertNotNull(dcr.findImplementingComponentSpecification(SimpleTouchable.class)); 491 assertNotNull(dcr.findImplementingComponentSpecification(Touchable.class)); 492 } 493 494 //TODO - move to ComponentSpecification testcase 495 public void testComponentSpecInstantiateComponentWithNoDependencies() throws PicoInitializationException { 496 ComponentSpecification componentSpec = new ComponentSpecification(new DefaultComponentFactory(), SimpleTouchable.class, SimpleTouchable.class, new Parameter[0]); 497 Object comp = componentSpec.instantiateComponent(null); 498 assertNotNull(comp); 499 assertTrue(comp instanceof SimpleTouchable); 500 } 501 502 503 //TODO move 504 public void testMultipleImplementationsAccessedThroughKey() 505 throws PicoInitializationException, PicoRegistrationException, PicoInvocationTargetInitializationException { 506 SimpleTouchable Touchable1 = new SimpleTouchable(); 507 SimpleTouchable Touchable2 = new SimpleTouchable(); 508 DefaultPicoContainer pico = new DefaultPicoContainer.Default(); 509 pico.registerComponent("Touchable1", Touchable1); 510 pico.registerComponent("Touchable2", Touchable2); 511 pico.registerComponent("fred1", DependsOnTouchable.class, new Parameter[]{new ComponentParameter("Touchable1")}); 512 pico.registerComponent("fred2", DependsOnTouchable.class, new Parameter[]{new ComponentParameter("Touchable2")}); 513 514 pico.instantiateComponents(); 515 516 DependsOnTouchable fred1 = (DependsOnTouchable) pico.getComponent("fred1"); 517 DependsOnTouchable fred2 = (DependsOnTouchable) pico.getComponent("fred2"); 518 519 assertFalse(fred1 == fred2); 520 assertSame(Touchable1, fred1.getTouchable()); 521 assertSame(Touchable2, fred2.getTouchable()); 522 } 523 524 //TODO - move 525 public void testRegistrationByName() throws Exception { 526 DefaultPicoContainer pico = new DefaultPicoContainer.Default(); 527 528 Webster one = new Webster(new ArrayList()); 529 Touchable two = new SimpleTouchable(); 530 531 pico.registerComponent("one", one); 532 pico.registerComponent("two", two); 533 534 pico.instantiateComponents(); 535 536 assertEquals("Wrong number of comps in the internals", 2, pico.getComponents().size()); 537 538 assertEquals("Looking up one Touchable", one, pico.getComponent("one")); 539 assertEquals("Looking up two Touchable", two, pico.getComponent("two")); 540 541 assertTrue("Object one the same", one == pico.getComponent("one")); 542 assertTrue("Object two the same", two == pico.getComponent("two")); 543 544 assertEquals("Lookup of unknown key should return null", null, pico.getComponent("unknown")); 545 } 546 547 public void testRegistrationByNameAndClassWithResolving() throws Exception { 548 DefaultPicoContainer pico = new DefaultPicoContainer.Default(); 549 550 pico.registerComponent(List.class, new ArrayList()); 551 pico.registerComponent("one", Webster.class); 552 pico.registerComponent("two", SimpleTouchable.class); 553 554 pico.instantiateComponents(); 555 556 assertEquals("Wrong number of comps in the internals", 3, pico.getComponents().size()); 557 558 assertTrue("Object one the same", pico.getComponent("one") != null); 559 assertTrue("Object two the same", pico.getComponent("two") != null); 560 561 assertEquals("Lookup of unknown key should return null", null, pico.getComponent("unknown")); 562 } 563 564 public void testRegistrationByInterfaceAndName() throws Exception { 565 DefaultComponentRegistry dcr = new DefaultComponentRegistry(); 566 DefaultPicoContainer pico = new DefaultPicoContainer.WithComponentRegistry(dcr); 567 568 Webster one = new Webster(new ArrayList()); 569 Webster two = new Webster(new ArrayList()); 570 571 pico.registerComponentByClass(DependsOnTouchable.class); 572 pico.registerComponent(Touchable.class, SimpleTouchable.class); 573 pico.registerComponent("one", one); 574 pico.registerComponent("two", two); 575 576 pico.instantiateComponents(); 577 578 assertEquals("Wrong number of comps in the internals", 4, pico.getComponents().size()); 579 580 assertTrue("There should have been a Fred in the internals", pico.hasComponent(DependsOnTouchable.class)); 581 assertTrue( 582 "There should have been a SimpleTouchable in the internals", 583 dcr.findImplementingComponent(SimpleTouchable.class) != null); 584 585 assertEquals("Looking up one Touchable", one, pico.getComponent("one")); 586 assertEquals("Looking up two Touchable", two, pico.getComponent("two")); 587 588 assertTrue("Object one the same", one == pico.getComponent("one")); 589 assertTrue("Object two the same", two == pico.getComponent("two")); 590 591 assertEquals("Lookup of unknown key should return null", null, pico.getComponent("unknown")); 592 } 593 594 public void testRegisterByNameResolvesToInterfaceRegisteredComponents() throws Exception { 595 // TODO we should add some kind of findImplementatingComponents() method to PicoContainer! 596 DefaultComponentRegistry dcr = new DefaultComponentRegistry(); 597 DefaultPicoContainer pico = new DefaultPicoContainer.WithComponentRegistry(dcr); 598 599 pico.registerComponent(Touchable.class, SimpleTouchable.class); 600 pico.registerComponent("fred", DependsOnTouchable.class); 601 pico.registerComponent("fred2", DependsOnTouchable.class); 602 603 pico.instantiateComponents(); 604 605 assertEquals("Wrong number of comps in the internals", 3, pico.getComponents().size()); 606 607 assertTrue("There should have been a Touchable in the internals", pico.hasComponent(Touchable.class)); 608 assertTrue( 609 "There should have been a SimpleTouchable in the internals", 610 dcr.findImplementingComponent(SimpleTouchable.class) != null); 611 612 DependsOnTouchable fred = (DependsOnTouchable) pico.getComponent("fred"); 613 DependsOnTouchable fred2 = (DependsOnTouchable) pico.getComponent("fred2"); 614 615 assertTrue("Found fred", fred != null); 616 assertTrue("Found fred2", fred2 != null); 617 618 // lets check that the Touchable's have been resolved 619 assertTrue("fred should have a Touchable", fred.getTouchable() != null); 620 assertTrue("fred2 should have a Touchable", fred2.getTouchable() != null); 621 622 assertEquals("Lookup of unknown key should return null", null, pico.getComponent("unknown")); 623 } 624 625 public void testUnmanagedCompsAreNotEligibleForComposite() throws Exception { 626 627 DefaultPicoContainer pico = new DefaultPicoContainer.Default(); 628 pico.registerComponent(Map.class, new HashMap()); 629 pico.instantiateComponents(); 630 631 try { 632 Map map = (Map) pico.getComponentMulticaster(); 633 fail("Unmanaged comps should nopt make it into the composite"); 634 } catch (ClassCastException e) { 635 // expected 636 } 637 } 638 639 public void testDuplicateRegistrationWithTypeAndObject() throws PicoInstantiationException, PicoRegistrationException, PicoIntrospectionException { 640 DefaultPicoContainer pico = new DefaultPicoContainer.Default(); 641 642 pico.registerComponentByClass(SimpleTouchable.class); 643 try { 644 pico.registerComponent(SimpleTouchable.class, new SimpleTouchable()); 645 fail("Should have barfed with dupe registration"); 646 } catch (DuplicateComponentKeyRegistrationException e) { 647 // expected 648 assertTrue(e.getDuplicateKey() == SimpleTouchable.class); 649 assertTrue(e.getMessage().indexOf(SimpleTouchable.class.getName()) > 0); 650 } 651 } 652 653 public static class DerivedTouchable extends SimpleTouchable { 654 public DerivedTouchable() { 655 } 656 } 657 658 public void testAmbiguousHierarchy() throws PicoRegistrationException, PicoInitializationException { 659 660 DefaultPicoContainer pico = new DefaultPicoContainer.Default(); 661 662 // Register two Touchables that Fred will be confused about 663 pico.registerComponentByClass(SimpleTouchable.class); 664 pico.registerComponentByClass(DerivedTouchable.class); 665 666 // Register a confused Fred 667 pico.registerComponentByClass(DependsOnTouchable.class); 668 669 try { 670 pico.instantiateComponents(); 671 fail("Fred should have been confused about the two Touchables"); 672 } catch (AmbiguousComponentResolutionException e) { 673 // expected 674 675 List ambiguous = Arrays.asList(e.getResultingKeys()); 676 assertTrue(ambiguous.contains(DerivedTouchable.class)); 677 assertTrue(ambiguous.contains(SimpleTouchable.class)); 678 assertTrue(e.getMessage().indexOf(SimpleTouchable.class.getName()) > 0); 679 assertTrue(e.getMessage().indexOf(DerivedTouchable.class.getName()) > 0); 680 } 681 } 682 683 public void testRegisterComponentWithObjectBadType() throws PicoIntrospectionException { 684 RegistrationPicoContainer pico = new DefaultPicoContainer.Default(); 685 686 try { 687 pico.registerComponent(Serializable.class, new Object()); 688 fail("Shouldn't be able to register an Object as Serializable"); 689 //TODO why? 690 } catch (PicoRegistrationException e) { 691 //TODO contains ? 692 693 } 694 695 } 696 697 public void testComponentRegistrationMismatch() throws PicoInstantiationException, PicoRegistrationException, PicoIntrospectionException { 698 RegistrationPicoContainer pico = new DefaultPicoContainer.Default(); 699 700 try { 701 pico.registerComponent(List.class, SimpleTouchable.class); 702 } catch (AssignabilityRegistrationException e) { 703 // not worded in message 704 assertTrue(e.getMessage().indexOf(List.class.getName()) > 0); 705 assertTrue(e.getMessage().indexOf(SimpleTouchable.class.getName()) > 0); 706 } 707 708 } 709 710 public void testMultipleArgumentConstructor() throws Throwable /* fixme */ { 711 DefaultPicoContainer pico = new DefaultPicoContainer.Default(); 712 713 pico.registerComponentByClass(DependsOnTouchable.class); 714 pico.registerComponent(Touchable.class, SimpleTouchable.class); 715 pico.registerComponentByClass(DependsOnTwoComponents.class); 716 717 pico.instantiateComponents(); 718 719 assertTrue("There should have been a DependsOnTwoComponents in the internals", pico.hasComponent(DependsOnTwoComponents.class)); 720 } 721 722 public void testTooManyContructors() throws PicoRegistrationException, PicoInitializationException { 723 724 RegistrationPicoContainer pico = new DefaultPicoContainer.Default(); 725 726 try { 727 pico.registerComponentByClass(Vector.class); 728 fail("Should fail because there are more than one constructors"); 729 } catch (NoPicoSuitableConstructorException e) { 730 // expected; 731 assertEquals("Should be right class", Vector.class, e.getForImplementationClass()); 732 } 733 734 } 735 736 public void testRegisterAbstractShouldFail() throws PicoRegistrationException, PicoIntrospectionException { 737 RegistrationPicoContainer pico = new DefaultPicoContainer.Default(); 738 739 try { 740 pico.registerComponentByClass(Runnable.class); 741 fail("Shouldn't be allowed to register abstract classes or interfaces."); 742 } catch (NotConcreteRegistrationException e) { 743 assertEquals(Runnable.class, e.getComponentImplementation()); 744 assertTrue(e.getMessage().indexOf(Runnable.class.getName()) > 0); 745 } 746 } 747 748 public void testWithComponentFactory() throws PicoRegistrationException, PicoInitializationException { 749 final SimpleTouchable Touchable = new SimpleTouchable(); 750 DefaultPicoContainer pc = new DefaultPicoContainer.WithComponentFactory(new ComponentFactory() { 751 public Object createComponent(ComponentSpecification componentSpec, Object[] args) { 752 return Touchable; 753 } 754 755 public Class[] getDependencies(Class componentImplementation) throws PicoIntrospectionException { 756 return new Class[0]; 757 } 758 }); 759 pc.registerComponentByClass(SimpleTouchable.class); 760 pc.instantiateComponents(); 761 assertEquals(pc.getComponent(SimpleTouchable.class), Touchable); 762 } 763 764 public static class Barney { 765 public Barney() { 766 throw new RuntimeException("Whoa!"); 767 } 768 } 769 770 public void testInvocationTargetException() throws PicoRegistrationException, PicoInitializationException { 771 DefaultPicoContainer pico = new DefaultPicoContainer.Default(); 772 pico.registerComponentByClass(Barney.class); 773 try { 774 pico.instantiateComponents(); 775 } catch (PicoInvocationTargetInitializationException e) { 776 assertEquals("Whoa!", e.getCause().getMessage()); 777 assertTrue(e.getMessage().indexOf("Whoa!") > 0); 778 } 779 } 780 781 interface Animal { 782 783 String getFood(); 784 } 785 786 public static class Dino implements Animal { 787 String food; 788 789 public Dino(String food) { 790 this.food = food; 791 } 792 793 public String getFood() { 794 return food; 795 } 796 } 797 798 public static class Dino2 extends Dino { 799 public Dino2(int number) { 800 super(String.valueOf(number)); 801 } 802 } 803 804 public static class Dino3 extends Dino { 805 public Dino3(String a, String b) { 806 super(a + b); 807 } 808 } 809 810 public static class Dino4 extends Dino { 811 public Dino4(String a, int n, String b, Touchable Touchable) { 812 super(a + n + b + " " + Touchable.getClass().getName()); 813 } 814 } 815 816 public void testParameterCanBePassedToConstructor() throws Exception { 817 DefaultPicoContainer pico = new DefaultPicoContainer.Default(); 818 pico.registerComponent(Animal.class, Dino.class); 819 pico.addParameterToComponent(Dino.class, String.class, "bones"); 820 pico.instantiateComponents(); 821 822 Animal animal = (Animal) pico.getComponent(Animal.class); 823 assertNotNull("Component not null", animal); 824 assertEquals("bones", animal.getFood()); 825 } 826 827 public void testParameterCanBePrimitive() throws Exception { 828 DefaultPicoContainer pico = new DefaultPicoContainer.Default(); 829 pico.registerComponent(Animal.class, Dino2.class); 830 pico.addParameterToComponent(Dino2.class, Integer.class, new Integer(22)); 831 pico.instantiateComponents(); 832 833 Animal animal = (Animal) pico.getComponent(Animal.class); 834 assertNotNull("Component not null", animal); 835 assertEquals("22", animal.getFood()); 836 } 837 838 public void testMultipleParametersCanBePassed() throws Exception { 839 DefaultPicoContainer pico = new DefaultPicoContainer.Default(); 840 pico.registerComponent(Animal.class, Dino3.class); 841 pico.addParameterToComponent(Dino3.class, String.class, "a"); 842 pico.addParameterToComponent(Dino3.class, String.class, "b"); 843 pico.instantiateComponents(); 844 845 Animal animal = (Animal) pico.getComponent(Animal.class); 846 assertNotNull("Component not null", animal); 847 assertEquals("ab", animal.getFood()); 848 849 } 850 851 public void testParametersCanBeMixedWithComponentsCanBePassed() throws Exception { 852 DefaultPicoContainer pico = new DefaultPicoContainer.Default(); 853 pico.registerComponent(Animal.class, Dino4.class); 854 pico.registerComponent(Touchable.class, SimpleTouchable.class); 855 pico.addParameterToComponent(Dino4.class, String.class, "a"); 856 pico.addParameterToComponent(Dino4.class, Integer.class, new Integer(3)); 857 pico.addParameterToComponent(Dino4.class, String.class, "b"); 858 pico.instantiateComponents(); 859 860 Animal animal = (Animal) pico.getComponent(Animal.class); 861 assertNotNull("Component not null", animal); 862 assertEquals("a3b org.picocontainer.testmodel.SimpleTouchable", animal.getFood()); 863 } 864 865 public static interface I { 866 } 867 868 public static class AA implements I { 869 public AA(I i) { 870 } 871 } 872 873 public static class BB implements I { 874 public BB(I i) { 875 } 876 } 877 878 public void testExtendAndDependOnSameType() throws PicoRegistrationException, PicoInitializationException { 879 DefaultPicoContainer pico = new DefaultPicoContainer.Default(); 880 881 pico.registerComponentByClass(AA.class); 882 pico.registerComponentByClass(BB.class); 883 884 try { 885 pico.instantiateComponents(); 886 fail("Should have barfed"); 887 } catch (AmbiguousComponentResolutionException e) { 888 // Neither can be instantiated without the other. 889 } 890 } 891 892 }

This page was automatically generated by Maven