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.behaviors;
009
010 import static org.junit.Assert.assertEquals;
011 import static org.junit.Assert.assertNotNull;
012 import static org.junit.Assert.assertSame;
013 import static org.junit.Assert.fail;
014 import static org.picocontainer.tck.MockFactory.mockeryWithCountingNamingScheme;
015
016 import org.jmock.Expectations;
017 import org.jmock.Mockery;
018 import org.jmock.integration.junit4.JMock;
019 import org.junit.Test;
020 import org.junit.runner.RunWith;
021 import org.picocontainer.ComponentAdapter;
022 import org.picocontainer.DefaultPicoContainer;
023 import org.picocontainer.LifecycleStrategy;
024 import org.picocontainer.MutablePicoContainer;
025 import org.picocontainer.PicoContainer;
026 import org.picocontainer.testmodel.SimpleTouchable;
027 import org.picocontainer.testmodel.Touchable;
028
029
030
031 /**
032 * @author Mauro Talevi
033 */
034 @RunWith(JMock.class)
035 public class CachedTestCase {
036
037 private Mockery mockery = mockeryWithCountingNamingScheme();
038
039 @Test public void testComponentIsNotStartedWhenCachedAndCanBeStarted() {
040 Cached adapter = new Cached(
041 mockComponentAdapterSupportingLifecycleStrategy(true, false, false));
042 PicoContainer pico = new DefaultPicoContainer();
043 adapter.getComponentInstance(pico);
044 adapter.start(pico);
045 }
046
047 @Test public void testComponentCanBeStartedAgainAfterBeingStopped() {
048 Cached adapter = new Cached(
049 mockComponentAdapterSupportingLifecycleStrategy(true, true, false));
050 PicoContainer pico = new DefaultPicoContainer();
051 adapter.start(pico);
052 Object instanceAfterFirstStart = adapter.getComponentInstance(pico);
053 adapter.stop(pico);
054 adapter.start(pico);
055 Object instanceAfterSecondStart = adapter.getComponentInstance(pico);
056 assertSame(instanceAfterFirstStart, instanceAfterSecondStart);
057 }
058
059 @Test public void testComponentCannotBeStartedIfDisposed() {
060 Cached adapter = new Cached(
061 mockComponentAdapterSupportingLifecycleStrategy(false, false, true));
062 PicoContainer pico = new DefaultPicoContainer();
063 adapter.dispose(pico);
064 try {
065 adapter.start(pico);
066 fail("IllegalStateException expected");
067 } catch (Exception e) {
068 assertEquals("Already disposed", e.getMessage());
069 }
070 }
071
072 @Test public void testComponentCannotBeStartedIfAlreadyStarted() {
073 Cached adapter = new Cached(
074 mockComponentAdapterSupportingLifecycleStrategy(true, false, false));
075 PicoContainer pico = new DefaultPicoContainer();
076 adapter.start(pico);
077 try {
078 adapter.start(pico);
079 fail("IllegalStateException expected");
080 } catch (Exception e) {
081 assertEquals("Already started", e.getMessage());
082 }
083 }
084
085 @Test public void testComponentCannotBeStoppeddIfDisposed() {
086 Cached adapter = new Cached(
087 mockComponentAdapterSupportingLifecycleStrategy(false, false, true));
088 PicoContainer pico = new DefaultPicoContainer();
089 adapter.dispose(pico);
090 try {
091 adapter.stop(pico);
092 fail("IllegalStateException expected");
093 } catch (Exception e) {
094 assertEquals("Already disposed", e.getMessage());
095 }
096 }
097
098 @Test public void testComponentCannotBeStoppedIfNotStarted() {
099 Cached adapter = new Cached(
100 mockComponentAdapterSupportingLifecycleStrategy(true, true, false));
101 PicoContainer pico = new DefaultPicoContainer();
102 adapter.start(pico);
103 adapter.stop(pico);
104 try {
105 adapter.stop(pico);
106 fail("IllegalStateException expected");
107 } catch (Exception e) {
108 assertEquals("Not started", e.getMessage());
109 }
110 }
111
112 @Test public void testComponentCannotBeDisposedIfAlreadyDisposed() {
113 Cached adapter = new Cached(
114 mockComponentAdapterSupportingLifecycleStrategy(true, true, true));
115 PicoContainer pico = new DefaultPicoContainer();
116 adapter.start(pico);
117 adapter.stop(pico);
118 adapter.dispose(pico);
119 try {
120 adapter.dispose(pico);
121 fail("IllegalStateException expected");
122 } catch (Exception e) {
123 assertEquals("Already disposed", e.getMessage());
124 }
125 }
126
127 @Test public void testComponentIsStoppedAndDisposedIfStartedWhenFlushed() {
128 Cached adapter = new Cached(
129 mockComponentAdapterSupportingLifecycleStrategy(true, true, true));
130 PicoContainer pico = new DefaultPicoContainer();
131 adapter.start(pico);
132 adapter.flush();
133 }
134
135 @Test public void testComponentIsNotStoppedAndDisposedWhenFlushedIfNotStarted() {
136 Cached adapter = new Cached(
137 mockComponentAdapterSupportingLifecycleStrategy(false, false, false));
138 adapter.flush();
139 }
140
141 @Test public void testComponentIsNotStoppedAndDisposedWhenFlushedIfDelegateDoesNotSupportLifecycle() {
142 Cached adapter = new Cached(
143 mockComponentAdapterNotSupportingLifecycleStrategy());
144 adapter.flush();
145 }
146
147 @Test public void testLifecycleIsIgnoredIfDelegateDoesNotSupportIt() {
148 Cached adapter = new Cached(
149 mockComponentAdapterNotSupportingLifecycleStrategy());
150 PicoContainer pico = new DefaultPicoContainer();
151 adapter.start(pico);
152 adapter.stop(pico);
153 adapter.dispose(pico);
154 }
155
156 @Test public void testCanStopAComponentThatWasNeverStartedBecauseItHasNoLifecycle() {
157 MutablePicoContainer pico = new DefaultPicoContainer();
158
159 pico.addComponent(StringBuffer.class);
160
161 pico.start();
162
163 assertNotNull(pico.getComponent(StringBuffer.class));
164
165 pico.stop();
166 pico.dispose();
167 }
168
169 private ComponentAdapter mockComponentAdapterNotSupportingLifecycleStrategy() {
170 return mockery.mock(ComponentAdapter.class);
171 }
172
173 private ComponentAdapter mockComponentAdapterSupportingLifecycleStrategy(
174 final boolean start, final boolean stop, final boolean dispose) {
175 final boolean hasLifecycle = start || stop || dispose;
176 final ComponentAdapterSupportingLifecycleStrategy ca = mockery.mock(ComponentAdapterSupportingLifecycleStrategy.class);
177 mockery.checking(new Expectations(){{
178 if (start) {
179 atLeast(1).of(ca).start(with(any(Touchable.class)));
180 }
181 if (stop) {
182 one(ca).stop(with(any(Touchable.class)));
183 }
184 if (dispose) {
185 one(ca).dispose(with(any(Touchable.class)));
186 }
187 if (hasLifecycle) {
188 one(ca).getComponentInstance(with(any(PicoContainer.class)), with(same(ComponentAdapter.NOTHING.class)));
189 will(returnValue(new SimpleTouchable()));
190 }
191 one(ca).getComponentImplementation();
192 will(returnValue(SimpleTouchable.class));
193 one(ca).hasLifecycle(with(same(SimpleTouchable.class)));
194 will(returnValue(hasLifecycle));
195 }});
196 return ca;
197 }
198
199 public static interface ComponentAdapterSupportingLifecycleStrategy extends ComponentAdapter,
200 LifecycleStrategy {
201 }
202 }