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.issues;
011    
012    import static org.junit.Assert.assertNotNull;
013    import static org.picocontainer.tck.MockFactory.mockeryWithCountingNamingScheme;
014    
015    import java.lang.reflect.Constructor;
016    import java.lang.reflect.Method;
017    
018    import org.hamcrest.Description;
019    import org.jmock.Expectations;
020    import org.jmock.Mockery;
021    import org.jmock.api.Action;
022    import org.jmock.api.Invocation;
023    import org.jmock.integration.junit4.JMock;
024    import org.junit.Test;
025    import org.junit.runner.RunWith;
026    import org.picocontainer.Characteristics;
027    import org.picocontainer.ComponentAdapter;
028    import org.picocontainer.ComponentMonitor;
029    import org.picocontainer.DefaultPicoContainer;
030    import org.picocontainer.DefaultPicoContainerTestCase;
031    import org.picocontainer.PicoContainer;
032    import org.picocontainer.Startable;
033    import org.picocontainer.Behavior;
034    import org.picocontainer.injectors.AbstractInjector;
035    
036    @RunWith(JMock.class)
037    public class Issue0265TestCase {
038    
039            private Mockery mockery = mockeryWithCountingNamingScheme();
040    
041        @Test public void testCanReallyChangeMonitor() throws SecurityException, NoSuchMethodException {
042            final Method start = Startable.class.getMethod("start");
043            final Method stop = Startable.class.getMethod("stop");
044            final ComponentMonitor monitor1 = mockery.mock(ComponentMonitor.class, "Monitor1");
045            final ComponentMonitor monitor2 = mockery.mock(ComponentMonitor.class, "Monitor2");
046            DefaultPicoContainer pico = new DefaultPicoContainer(monitor1);
047            mockery.checking(new Expectations(){{
048                one(monitor1).newBehavior(with(any(Behavior.class)));
049                will(returnParameterAction(0));
050                one(monitor1).newInjector(with(any(AbstractInjector.class)));
051                will(returnParameterAction(0));
052                one(monitor1).instantiating(with(any(PicoContainer.class)), with(any(ComponentAdapter.class)), with(any(Constructor.class)));
053                will(returnValue(DefaultPicoContainerTestCase.MyStartable.class.getConstructor()));
054                one(monitor1).instantiated(with(any(PicoContainer.class)), with(any(ComponentAdapter.class)), with(any(Constructor.class)), 
055                            with(any(Object.class)), with(any(Object[].class)), with(any(Long.class)));
056                one(monitor1).invoking(with(any(PicoContainer.class)), with(any(ComponentAdapter.class)), with(equal(start)), 
057                            with(any(Object.class)), with(any(Object[].class)));
058                one(monitor1).invoked(with(any(PicoContainer.class)), with(any(ComponentAdapter.class)), with(equal(start)), 
059                            with(any(Object.class)), with(any(Long.class)), with(any(Object[].class)), with(same(null)));
060                one(monitor1).invoking(with(any(PicoContainer.class)), with(any(ComponentAdapter.class)), with(equal(stop)), 
061                            with(any(Object.class)), with(any(Object[].class)));
062                one(monitor1).invoked(with(any(PicoContainer.class)), with(any(ComponentAdapter.class)), with(equal(stop)), 
063                            with(any(Object.class)), with(any(Long.class)), with(any(Object[].class)), with(same(null)));
064            }});
065            pico.as(Characteristics.CACHE).addComponent(DefaultPicoContainerTestCase.MyStartable.class);
066            pico.start();
067            pico.stop();
068            Startable startable = pico.getComponent(DefaultPicoContainerTestCase.MyStartable.class);
069            assertNotNull(startable);
070            pico.changeMonitor(monitor2);
071            mockery.checking(new Expectations(){{
072                one(monitor2).invoking(with(any(PicoContainer.class)), with(any(ComponentAdapter.class)), with(equal(start)),
073                            with(any(Object.class)), with(any(Object[].class)));
074                one(monitor2).invoked(with(any(PicoContainer.class)), with(any(ComponentAdapter.class)), with(equal(start)), 
075                            with(any(Object.class)), with(any(Long.class)), with(any(Object[].class)), with(same(null)));
076                one(monitor2).invoking(with(any(PicoContainer.class)), with(any(ComponentAdapter.class)), with(equal(stop)), 
077                            with(any(Object.class)), with(any(Object[].class)));
078                one(monitor2).invoked(with(any(PicoContainer.class)), with(any(ComponentAdapter.class)), with(equal(stop)), 
079                            with(any(Object.class)), with(any(Long.class)), with(any(Object[].class)), with(same(null)));
080            }});
081            pico.start();
082            pico.stop();
083        }
084    
085        public static Action returnParameterAction(int param) {
086            return new ReturnParameterAction(param);
087        }
088    
089        public static class ReturnParameterAction implements Action {
090            private final int parameter;
091    
092            public ReturnParameterAction(int parameter) {
093                this.parameter = parameter;
094            }
095    
096            public void describeTo(Description description) {
097                description.appendText("returns param[")
098                        .appendValue(parameter)
099                        .appendText("]");
100            }
101    
102            public Object invoke(Invocation invocation) {
103                return invocation.getParameter(parameter);
104            }
105        }
106    
107    
108    }