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