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