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    package org.picocontainer.lifecycle;
009    
010    import static org.junit.Assert.assertEquals;
011    import static org.junit.Assert.assertTrue;
012    import static org.junit.Assert.fail;
013    import org.junit.Ignore;
014    import static org.picocontainer.Characteristics.CACHE;
015    import static org.picocontainer.tck.MockFactory.mockeryWithCountingNamingScheme;
016    
017    import java.io.Serializable;
018    
019    import org.jmock.Expectations;
020    import org.jmock.Mockery;
021    import org.jmock.integration.junit4.JMock;
022    import org.junit.Before;
023    import org.junit.Test;
024    import org.junit.runner.RunWith;
025    import org.picocontainer.DefaultPicoContainer;
026    import org.picocontainer.Disposable;
027    import org.picocontainer.PicoLifecycleException;
028    import org.picocontainer.Startable;
029    import org.picocontainer.containers.EmptyPicoContainer;
030    import org.picocontainer.monitors.NullComponentMonitor;
031    
032    /**
033     * 
034     * @author Mauro Talevi
035     */
036    @SuppressWarnings("serial")
037    @RunWith(JMock.class)
038    public class StartableLifecycleStrategyTestCase {
039    
040            private Mockery mockery = mockeryWithCountingNamingScheme();
041            
042        private StartableLifecycleStrategy startableLifecycle;
043    
044        @Before
045        public void setUp(){
046            startableLifecycle = new StartableLifecycleStrategy(new NullComponentMonitor());
047        }
048    
049        @Test public void testStartable(){
050            Object startable = mockComponent(true, false);
051            startableLifecycle.start(startable);
052            startableLifecycle.stop(startable);
053        }
054    
055        @Test public void testDisposable(){
056            Object startable = mockComponent(false, true);
057            startableLifecycle.dispose(startable);
058        }
059    
060        @Test public void testSerializable(){
061            Object serializable = mockComponent(false, false);
062            startableLifecycle.start(serializable);
063            startableLifecycle.stop(serializable);
064            startableLifecycle.dispose(serializable);
065        }
066        
067        private Object mockComponent(boolean startable, boolean disposeable) {
068            if ( startable ) {
069                     final Startable mock = mockery.mock(Startable.class);
070                     mockery.checking(new Expectations() {{
071                     one(mock).start(); 
072                     one(mock).stop(); 
073                 }});
074                     return mock;
075            }
076            if ( disposeable ) {
077             final Disposable mock = mockery.mock(Disposable.class);
078             mockery.checking(new Expectations() {{
079                 one(mock).dispose(); 
080             }});
081             return mock;
082            }
083            return mockery.mock(Serializable.class);
084        }
085    
086    
087    
088        public static class ThirdPartyStartableComponent2 implements ThirdPartyStartable {
089            public void sstart() {
090                throw new UnsupportedOperationException();
091            }
092            public void sstop() {
093            }
094    
095            public void ddispose() {
096            }
097        }
098    
099        public static class ThirdPartyStartableComponent3 implements ThirdPartyStartable {
100            public void sstart() throws Exception {
101                throw new Exception("whoaa!");
102            }
103            public void sstop() {
104            }
105    
106            public void ddispose() {
107            }
108        }
109    
110        @Test public void testThirdPartyStartableAndDisposable() {
111            DefaultPicoContainer pico = new DefaultPicoContainer(new MyStartableLifecycleStrategy(), new EmptyPicoContainer());
112            StringBuilder sb = new StringBuilder();
113            pico.addComponent(sb);
114            pico.as(CACHE).addComponent(ThirdPartyStartableComponent.class);
115            pico.start();
116            pico.stop();
117            pico.dispose();
118            assertEquals("<>!", sb.toString());
119    
120        }
121    
122        @Test public void testLateAdditionofStartableAlsoStarted() {
123            DefaultPicoContainer pico = new DefaultPicoContainer(new MyStartableLifecycleStrategy(), new EmptyPicoContainer());
124            StringBuilder sb = new StringBuilder();
125            pico.addComponent(sb);
126            pico.as(CACHE).addComponent(NonStartable.class);
127            pico.start();
128            assertEquals("", sb.toString());
129            pico.as(CACHE).addComponent(ThirdPartyStartableComponent.class);
130            assertEquals("<", sb.toString());
131            pico.stop();
132            pico.dispose();
133            assertEquals("<>!", sb.toString());
134        }
135    
136        public static class NonStartable {
137    
138        }
139    
140        @Test public void testMixOfThirdPartyAndBuiltInStartableAndDisposable() {
141            DefaultPicoContainer pico = new DefaultPicoContainer(new CompositeLifecycleStrategy(
142                        new MyStartableLifecycleStrategy(),
143                        new StartableLifecycleStrategy(new NullComponentMonitor())),
144                    new EmptyPicoContainer());
145            StringBuilder sb = new StringBuilder();
146            pico.addComponent(sb);
147            pico.as(CACHE).addComponent(ThirdPartyStartableComponent.class);
148            pico.as(CACHE).addComponent(BuiltInStartableComponent.class);
149            pico.start();
150            pico.stop();
151            pico.dispose();
152            assertEquals("<<>>!!", sb.toString());
153        }
154    
155        @Test public void testThirdPartyStartableCanNoteLifecycleRuntimeException() {
156            DefaultPicoContainer pico = new DefaultPicoContainer(new MyStartableLifecycleStrategy(), new EmptyPicoContainer());
157            pico.as(CACHE).addComponent(ThirdPartyStartableComponent2.class);
158            try {
159                pico.start();
160                fail("should have barfed");
161            } catch (PicoLifecycleException e) {
162                assertTrue(e.getCause() instanceof UnsupportedOperationException);
163                assertTrue(e.getInstance() instanceof ThirdPartyStartableComponent2);
164                assertEquals("sstart", e.getMethod().getName());
165                // expected
166            }
167    
168        }
169    
170        @Test public void testThirdPartyStartableCanNoteLifecycleException() {
171            DefaultPicoContainer pico = new DefaultPicoContainer(new MyStartableLifecycleStrategy(), new EmptyPicoContainer());
172            pico.as(CACHE).addComponent(ThirdPartyStartableComponent3.class);
173            try {
174                pico.start();
175                fail("should have barfed");
176            } catch (PicoLifecycleException e) {
177                Throwable throwable = e.getCause();
178                assertTrue(throwable instanceof Exception);
179                String s = throwable.getMessage();
180                assertEquals("whoaa!", s);
181                assertTrue(e.getInstance() instanceof ThirdPartyStartableComponent3);
182                assertEquals("sstart", e.getMethod().getName());
183                // expected
184            }
185    
186        }
187    
188    }