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.lifecycle;
009
010 import org.picocontainer.ComponentMonitor;
011 import org.picocontainer.Disposable;
012 import org.picocontainer.Startable;
013 import org.picocontainer.lifecycle.ReflectionLifecycleStrategy;
014
015 import org.jmock.Mock;
016 import org.jmock.MockObjectTestCase;
017 import org.jmock.core.Constraint;
018
019 import java.io.Serializable;
020 import java.lang.reflect.Method;
021
022 /**
023 * @author Paul Hammant
024 * @author Mauro Talevi
025 * @author Jörg Schaible
026 */
027 public class ReflectionLifecycleStrategyTestCase extends MockObjectTestCase {
028
029 private ReflectionLifecycleStrategy strategy;
030 private Mock componentMonitorMock;
031
032 public void setUp(){
033 componentMonitorMock = mock(ComponentMonitor.class);
034 strategy = new ReflectionLifecycleStrategy((ComponentMonitor)componentMonitorMock.proxy());
035 }
036
037 public void testStartable(){
038 Object startable = mockComponent(true, false);
039 strategy.start(startable);
040 strategy.stop(startable);
041 strategy.dispose(startable);
042 }
043
044 public void testDisposable(){
045 Object disposable = mockComponent(false, true);
046 strategy.start(disposable);
047 strategy.stop(disposable);
048 strategy.dispose(disposable);
049 }
050
051 public void testNotStartableNorDisposable(){
052 Object serializable = mock(Serializable.class);
053 assertFalse(strategy.hasLifecycle(serializable.getClass()));
054 strategy.start(serializable);
055 strategy.stop(serializable);
056 strategy.dispose(serializable);
057 }
058
059 public void testMonitorChanges() {
060 Mock componentMonitorMock2 = mock(ComponentMonitor.class);
061 Mock mock = mock(Disposable.class);
062 Object disposable = mock.proxy();
063 mock.expects(once()).method("dispose");
064 componentMonitorMock.expects(once()).method("invoking").with(NULL, NULL, method("dispose"), same(mock.proxy()));
065 componentMonitorMock.expects(once()).method("invoked").with(new Constraint[] {NULL, NULL, method("dispose"), same(mock.proxy()), ANYTHING});
066 strategy.dispose(disposable);
067 strategy.changeMonitor((ComponentMonitor)componentMonitorMock2.proxy());
068 mock.expects(once()).method("dispose");
069 componentMonitorMock2.expects(once()).method("invoking").with(NULL, NULL, method("dispose"), same(mock.proxy()));
070 componentMonitorMock2.expects(once()).method("invoked").with(new Constraint[] {NULL, NULL, method("dispose"), same(mock.proxy()), ANYTHING});
071 strategy.dispose(disposable);
072 }
073
074 static interface MyLifecylce {
075 void start();
076 void stop();
077 void dispose();
078 }
079
080 public void testWithDifferentTypes() {
081 Mock anotherStartableMock = mock(MyLifecylce.class);
082 anotherStartableMock.expects(once()).method("start");
083 anotherStartableMock.expects(once()).method("stop");
084 anotherStartableMock.expects(once()).method("dispose");
085 componentMonitorMock.expects(once()).method("invoking").with(NULL, NULL, method("start"), same(anotherStartableMock.proxy()));
086 componentMonitorMock.expects(once()).method("invoked").with(new Constraint[] {NULL, NULL, method("start"), same(anotherStartableMock.proxy()), ANYTHING});
087 componentMonitorMock.expects(once()).method("invoking").with(NULL, NULL, method("stop"), same(anotherStartableMock.proxy()));
088 componentMonitorMock.expects(once()).method("invoked").with(new Constraint[] {NULL, NULL, method("stop"), same(anotherStartableMock.proxy()), ANYTHING});
089 componentMonitorMock.expects(once()).method("invoking").with(NULL, NULL, method("dispose"), same(anotherStartableMock.proxy()));
090 componentMonitorMock.expects(once()).method("invoked").with(new Constraint[] {NULL, NULL, method("dispose"), same(anotherStartableMock.proxy()), ANYTHING});
091
092 Object startable = mockComponent(true, false);
093 strategy.start(startable);
094 strategy.stop(startable);
095 strategy.dispose(startable);
096 startable = anotherStartableMock.proxy();
097 strategy.start(startable);
098 strategy.stop(startable);
099 strategy.dispose(startable);
100 }
101
102 private Object mockComponent(boolean startable, boolean disposable) {
103 Mock mock = mock(Serializable.class);
104 if ( startable ) {
105 mock = mock(Startable.class);
106 mock.expects(atLeastOnce()).method("start");
107 mock.expects(atLeastOnce()).method("stop");
108 componentMonitorMock.expects(once()).method("invoking").with(NULL, NULL, method("start"), same(mock.proxy()));
109 componentMonitorMock.expects(once()).method("invoked").with(new Constraint[] {NULL, NULL, method("start"), same(mock.proxy()), ANYTHING});
110 componentMonitorMock.expects(once()).method("invoking").with(NULL, NULL, method("stop"), same(mock.proxy()));
111 componentMonitorMock.expects(once()).method("invoked").with(new Constraint[] {NULL, NULL, method("stop"), same(mock.proxy()), ANYTHING});
112 }
113 if ( disposable ) {
114 mock = mock(Disposable.class);
115 mock.expects(atLeastOnce()).method("dispose");
116 componentMonitorMock.expects(once()).method("invoking").with(NULL, NULL, method("dispose"), same(mock.proxy()));
117 componentMonitorMock.expects(once()).method("invoked").with(new Constraint[] {NULL, NULL, method("dispose"), same(mock.proxy()), ANYTHING});
118 }
119 return mock.proxy();
120 }
121
122 MethodNameIsEqual method(String name) {
123 return new MethodNameIsEqual(name);
124 }
125
126 static class MethodNameIsEqual implements Constraint {
127
128 private final String name;
129
130 public MethodNameIsEqual(String name) {
131 this.name = name;
132 }
133
134 public boolean eval(Object o) {
135 return o instanceof Method && ((Method)o).getName().equals(name);
136 }
137
138 public StringBuffer describeTo(StringBuffer buffer) {
139 buffer.append("a method with name <");
140 buffer.append(name);
141 return buffer.append('>');
142 }
143
144 }
145 }