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