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.defaults;
011
012 import org.jmock.Mock;
013 import org.jmock.MockObjectTestCase;
014 import org.jmock.core.Constraint;
015 import org.picocontainer.ComponentMonitor;
016 import org.picocontainer.ComponentMonitorStrategy;
017 import org.picocontainer.DefaultPicoContainer;
018 import org.picocontainer.injectors.ConstructorInjector;
019 import org.picocontainer.monitors.AbstractComponentMonitor;
020
021 import java.lang.reflect.Constructor;
022 import java.util.*;
023
024 /**
025 * @author Mauro Talevi
026 */
027 public class AbstractComponentMonitorTestCase extends MockObjectTestCase {
028
029 public void testDelegatingMonitorThrowsExpectionWhenConstructionWithNullDelegate(){
030 try {
031 new AbstractComponentMonitor(null);
032 fail("NPE expected");
033 } catch (NullPointerException e) {
034 assertEquals("NPE", "monitor", e.getMessage());
035 }
036 }
037
038 public void testDelegatingMonitorThrowsExpectionWhenChangingToNullMonitor(){
039 AbstractComponentMonitor dcm = new AbstractComponentMonitor();
040 try {
041 dcm.changeMonitor(null);
042 fail("NPE expected");
043 } catch (NullPointerException e) {
044 assertEquals("NPE", "monitor", e.getMessage());
045 }
046 }
047
048 public void testDelegatingMonitorCanChangeMonitorInDelegateThatDoesSupportMonitorStrategy() {
049 ComponentMonitor monitor = mockMonitorWithNoExpectedMethods();
050 AbstractComponentMonitor dcm = new AbstractComponentMonitor(mockMonitorThatSupportsStrategy(monitor));
051 dcm.changeMonitor(monitor);
052 assertEquals(monitor, dcm.currentMonitor());
053 dcm.instantiating(null, null, null);
054 }
055
056 public void testDelegatingMonitorChangesDelegateThatDoesNotSupportMonitorStrategy() {
057 ComponentMonitor delegate = mockMonitorWithNoExpectedMethods();
058 AbstractComponentMonitor dcm = new AbstractComponentMonitor(delegate);
059 ComponentMonitor monitor = mockMonitorWithNoExpectedMethods();
060 assertEquals(delegate, dcm.currentMonitor());
061 dcm.changeMonitor(monitor);
062 assertEquals(monitor, dcm.currentMonitor());
063 }
064
065 public void testDelegatingMonitorReturnsDelegateThatDoesNotSupportMonitorStrategy() {
066 ComponentMonitor delegate = mockMonitorWithNoExpectedMethods();
067 AbstractComponentMonitor dcm = new AbstractComponentMonitor(delegate);
068 assertEquals(delegate, dcm.currentMonitor());
069 }
070
071 private ComponentMonitor mockMonitorWithNoExpectedMethods() {
072 Mock mock = mock(ComponentMonitor.class);
073 return (ComponentMonitor)mock.proxy();
074 }
075
076 private ComponentMonitor mockMonitorThatSupportsStrategy(ComponentMonitor currentMonitor) {
077 Mock mock = mock(TestMonitorThatSupportsStrategy.class);
078 mock.expects(once()).method("changeMonitor").with(eq(currentMonitor));
079 mock.expects(once()).method("currentMonitor").withAnyArguments().will(returnValue(currentMonitor));
080 mock.expects(once()).method("instantiating").withAnyArguments();
081 return (ComponentMonitor)mock.proxy();
082 }
083
084 public void testMonitoringHappensBeforeAndAfterInstantiation() throws NoSuchMethodException {
085 final Vector ourIntendedInjectee0 = new Vector();
086 final String ourIntendedInjectee1 = "hullo";
087 DefaultPicoContainer parent = new DefaultPicoContainer();
088 Mock monitor = mock(ComponentMonitor.class);
089 DefaultPicoContainer child = new DefaultPicoContainer(new AbstractComponentMonitor((ComponentMonitor) monitor.proxy()), parent);
090
091 Constructor nacotCtor = NeedsACoupleOfThings.class.getConstructors()[0];
092 monitor.expects(once()).method("instantiating").with(same(child), isA(ConstructorInjector.class), eq(nacotCtor)).will(returnValue(nacotCtor));
093 Constraint durationIsGreaterThanOrEqualToZero = new Constraint() {
094 public boolean eval(Object o) {
095 Long duration = (Long)o;
096 return 0 <= duration;
097 }
098
099 public StringBuffer describeTo(StringBuffer stringBuffer) {
100 return stringBuffer.append("The endTime wasn't after the startTime");
101 }
102 };
103 Constraint isANACOTThatWozCreated = new Constraint() {
104 public boolean eval(Object o) {
105 return o instanceof NeedsACoupleOfThings;
106 }
107
108 public StringBuffer describeTo(StringBuffer stringBuffer) {
109 return stringBuffer.append("Should have been a hashmap");
110 }
111 };
112 Constraint collectionAndStringWereInjected = new Constraint() {
113 public boolean eval(Object o) {
114 Object[] ctorArgs = (Object[]) o;
115 return ctorArgs.length == 2 && ctorArgs[0] == ourIntendedInjectee0 && ctorArgs[1] == ourIntendedInjectee1;
116 }
117 public StringBuffer describeTo(StringBuffer stringBuffer) {
118 return stringBuffer.append("Should have injected our intended vector and string");
119 }
120 };
121 monitor.expects(once()).method("instantiated").with(new Constraint[] {same(child), isA(ConstructorInjector.class),eq(nacotCtor), isANACOTThatWozCreated, collectionAndStringWereInjected, durationIsGreaterThanOrEqualToZero});
122 parent.addComponent(ourIntendedInjectee0);
123 parent.addComponent(ourIntendedInjectee1);
124 child.addComponent(NeedsACoupleOfThings.class);
125 child.getComponent(NeedsACoupleOfThings.class);
126 }
127
128 public static class NeedsACoupleOfThings {
129 public NeedsACoupleOfThings(Collection collection, String string) {
130 }
131 }
132
133 public static interface TestMonitorThatSupportsStrategy extends ComponentMonitor, ComponentMonitorStrategy {
134 }
135 }