    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    }