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 }