001// Licensed under the Apache License, Version 2.0 (the "License");
002// you may not use this file except in compliance with the License.
003// You may obtain a copy of the License at
004//
005// http://www.apache.org/licenses/LICENSE-2.0
006//
007// Unless required by applicable law or agreed to in writing, software
008// distributed under the License is distributed on an "AS IS" BASIS,
009// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
010// See the License for the specific language governing permissions and
011// limitations under the License.
012
013package org.apache.tapestry5.ioc.junit;
014
015import org.apache.tapestry5.ioc.annotations.Inject;
016import org.apache.tapestry5.ioc.def.ModuleDef;
017import org.junit.runner.Description;
018import org.junit.runner.Result;
019import org.junit.runner.notification.Failure;
020import org.junit.runner.notification.RunListener;
021import org.junit.runner.notification.RunNotifier;
022import org.junit.runner.notification.StoppedByUserException;
023import org.junit.runners.BlockJUnit4ClassRunner;
024import org.junit.runners.model.InitializationError;
025import org.junit.runners.model.Statement;
026
027/**
028 *
029 * A JUnit4ClassRunner to help with Tapestry IOC integration tests. The test
030 * runner requires a registry configuration to be defined in a {@link Registry}
031 * annotation. A {@link RegistryShutdownType} can be specified to configure the
032 * lifecycle of the test registry and it's services
033 *
034 * 
035 *
036 * {@link org.apache.tapestry5.ioc.junit.ModuleDef}s can be added to the
037 * {@link org.apache.tapestry5.ioc.Registry} by annotating a factory method(s)
038 * with {@link ModuleDef}. These {@link ModuleDef} factory methods must be
039 * <ul>
040 * <li>public</li>
041 * <li>static</li>
042 * <li>take zero arguments</li>
043 * <li>return a subclass of {@link org.apache.tapestry5.ioc.junit.ModuleDef}</li>
044 * </ul>
045 *
046 * 
047 *
048 * Any services defined in the registry can be {@link Inject}ed into the test
049 * class to be used during testing.
050 *
051 */
052public class TapestryIOCJUnit4ClassRunner extends BlockJUnit4ClassRunner {
053        private final TestRegistryManager registryManager;
054
055        public TapestryIOCJUnit4ClassRunner(Class<?> type) throws InitializationError {
056                super(type);
057                this.registryManager = new TestRegistryManager(type);
058        }
059
060        @Override
061        public void run(RunNotifier notifier) {
062                RunNotifier wrapper = new RegistryManagerRunNotifier(registryManager, notifier);
063                super.run(wrapper);
064        }
065
066        @Override
067        protected Statement withAfterClasses(Statement statement) {
068                final Statement superStatement = super.withAfterClasses(statement);
069                return new Statement() {
070                        @Override
071                        public void evaluate() throws Throwable {
072                                superStatement.evaluate();
073                                registryManager.afterTestClass();
074                        }
075                };
076        }
077
078        @Override
079        protected Object createTest() throws Exception {
080                org.apache.tapestry5.ioc.Registry registry = registryManager.getOrCreateRegistry();
081                return registry.autobuild(getTestClass().getJavaClass());
082        }
083
084        public static class RegistryManagerRunNotifier extends RunNotifier {
085                private final RunNotifier delegate;
086                private final TestRegistryManager registryManager;
087
088                public RegistryManagerRunNotifier(TestRegistryManager registryManager, RunNotifier delegate) {
089                        super();
090                        this.delegate = delegate;
091                        this.registryManager = registryManager;
092                }
093                
094                @Override
095                public void addListener(RunListener listener) {
096                        delegate.addListener(listener);
097                }
098
099                @Override
100                public void removeListener(RunListener listener) {
101                        delegate.removeListener(listener);
102                }
103
104                @Override
105                public void fireTestRunStarted(Description description) {
106                        delegate.fireTestRunStarted(description);
107                }
108
109                @Override
110                public void fireTestRunFinished(Result result) {
111                        delegate.fireTestRunFinished(result);
112                }
113
114                @Override
115                public void fireTestStarted(Description description) throws StoppedByUserException {
116                        delegate.fireTestStarted(description);
117                }
118
119                @Override
120                public void fireTestFailure(Failure failure) {
121                        delegate.fireTestFailure(failure);
122                }
123
124                @Override
125                public void fireTestAssumptionFailed(Failure failure) {
126                        delegate.fireTestAssumptionFailed(failure);
127                }
128
129                @Override
130                public void fireTestIgnored(Description description) {
131                        delegate.fireTestIgnored(description);
132                }
133
134                @Override
135                public void fireTestFinished(Description description) {
136                        registryManager.afterTestMethod();
137                        delegate.fireTestFinished(description);
138                }
139
140                @Override
141                public void pleaseStop() {
142                        delegate.pleaseStop();
143                }
144
145                @Override
146                public void addFirstListener(RunListener listener) {
147                        delegate.addFirstListener(listener);
148                }
149        }
150}