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 }