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