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