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