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