/* * Copyright 2008 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.powermock.modules.junit3.internal.impl; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestResult; import junit.framework.TestSuite; import org.powermock.core.spi.PowerMockTestListener; import org.powermock.modules.junit3.internal.JUnit3TestSuiteChunker; import org.powermock.modules.junit3.internal.PowerMockJUnit3RunnerDelegate; import org.powermock.tests.utils.TestChunk; import org.powermock.tests.utils.impl.AbstractTestSuiteChunkerImpl; import org.powermock.tests.utils.impl.MockPolicyInitializerImpl; import java.lang.reflect.Constructor; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.util.Enumeration; import java.util.Iterator; import java.util.LinkedList; import java.util.List; public class JUnit3TestSuiteChunkerImpl extends AbstractTestSuiteChunkerImpl<PowerMockJUnit3RunnerDelegate> implements JUnit3TestSuiteChunker { private String name; public JUnit3TestSuiteChunkerImpl(Class<? extends TestCase>... testClasses) throws Exception { super(testClasses); try { for (Class<? extends TestCase> testClass : testClasses) { createTestDelegators(testClass, getTestChunksEntries(testClass)); } } catch (Exception e) { final Throwable cause = e.getCause(); if (cause instanceof Exception) { throw (Exception) cause; } else { throw new RuntimeException(cause); } } } public JUnit3TestSuiteChunkerImpl(String name, Class<? extends TestCase>... testClasses) throws Exception { this(testClasses); this.name = name; } @Override protected PowerMockJUnit3RunnerDelegate createDelegatorFromClassloader(ClassLoader classLoader, Class<?> testClass, final List<Method> methodsToTest) throws Exception { final Class<?> testClassLoadedByMockedClassLoader = Class.forName(testClass.getName(), false, classLoader); final Class<?> powerMockTestListenerArrayType = Class.forName(PowerMockTestListener[].class.getName(), false, classLoader); Class<?> delegateClass = Class.forName(PowerMockJUnit3RunnerDelegateImpl.class.getName(), false, classLoader); Constructor<?> con = delegateClass.getConstructor(Class.class, Method[].class, powerMockTestListenerArrayType); final PowerMockJUnit3RunnerDelegate newDelegate = (PowerMockJUnit3RunnerDelegate) con.newInstance( testClassLoadedByMockedClassLoader, methodsToTest.toArray(new Method[0]), getPowerMockTestListenersLoadedByASpecificClassLoader(testClass, classLoader)); newDelegate.setName(name); return newDelegate; } @Override protected void chunkClass(Class<?> testClass) throws Exception { if (!TestCase.class.isAssignableFrom(testClass)) { throw new IllegalArgumentException(testClass.getName() + " must be a subtype of " + TestCase.class.getName()); } super.chunkClass(testClass); } public int getTestCount() { if (testCount == NOT_INITIALIZED) { testCount = 0; for (PowerMockJUnit3RunnerDelegate delegate : delegates) { testCount += delegate.testCount(); } } return testCount; } public boolean shouldExecuteTestForMethod(Class<?> testClass, Method potentialTestMethod) { return potentialTestMethod.getName().startsWith("test") && Modifier.isPublic(potentialTestMethod.getModifiers()) && potentialTestMethod.getReturnType().equals(Void.TYPE); } public void addTest(Test test) throws Exception { if (test == null) { throw new IllegalArgumentException("test cannot be null"); } if (test instanceof TestCase) { // testSuiteDelegator.addTest(prepareTestCase((TestCase) test)); addTestClassToSuite(test.getClass()); } else if (test instanceof TestSuite) { final Enumeration<?> tests = ((TestSuite) test).tests(); while (tests.hasMoreElements()) { addTest((Test) tests.nextElement()); } } else { throw new IllegalArgumentException("The test type " + test.getClass().getName() + " is not supported. Only " + TestCase.class.getName() + " and " + TestSuite.class.getName() + " are supported."); } } public void addTestSuite(Class<? extends TestCase> testClass) throws Exception { addTestClassToSuite(testClass); } public int countTestCases() { int count = 0; for (PowerMockJUnit3RunnerDelegate delegate : delegates) { count += delegate.countTestCases(); } return count; } public void run(TestResult result) { final Iterator<TestChunk> iterator = getChunkIterator(); for (PowerMockJUnit3RunnerDelegate delegate : delegates) { TestChunk next = iterator.next(); final PowerMockJUnit3TestListener listener = new PowerMockJUnit3TestListener(next.getClassLoader()); result.addListener(listener); // Initialize mock policies for each test new MockPolicyInitializerImpl(delegate.getTestClass()).initialize(this.getClass().getClassLoader()); delegate.run(result); result.removeListener(listener); } } public void runTest(Test test, TestResult result) { final Iterator<TestChunk> iterator = getChunkIterator(); for (PowerMockJUnit3RunnerDelegate delegate : delegates) { TestChunk next = iterator.next(); final PowerMockJUnit3TestListener listener = new PowerMockJUnit3TestListener(next.getClassLoader()); result.addListener(listener); delegate.runTest(test, result); result.removeListener(listener); } } private Iterator<TestChunk> getChunkIterator() { List<TestChunk> entrySet = getTestChunks(); Iterator<TestChunk> iterator = entrySet.iterator(); if (delegates.size() != getChunkSize()) { throw new IllegalStateException("Internal error: There must be an equal number of suites and delegates."); } return iterator; } public Test testAt(int index) { return delegates.get(getDelegatorIndex(index)).testAt(getInternalTestIndex(index)); } public void addTestClassToSuite(Class<?> clazz) throws Exception { chunkClass(clazz); if (!delegatesCreatedForTheseClasses.contains(clazz)) { try { createTestDelegators(clazz, getTestChunksEntries(clazz)); } catch (Exception e) { throw new RuntimeException(e); } } } public Enumeration<?> tests() { final List<Object> tests = new LinkedList<Object>(); for (PowerMockJUnit3RunnerDelegate delegate : delegates) { final Enumeration<?> delegateTests = delegate.tests(); while (delegateTests.hasMoreElements()) { tests.add(delegateTests.nextElement()); } } Enumeration<?> allTests = new Enumeration<Object>() { private volatile int count = 0; public boolean hasMoreElements() { return count != tests.size(); } public Object nextElement() { return tests.get(count++); } }; return allTests; } }