blob: b2953134b77a1ee5efe7e0d0c96c7469ef6c08bf [file] [log] [blame]
/*
* Copyright 2000-2009 JetBrains s.r.o.
*
* 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 com.intellij.junit3;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestResult;
import junit.framework.TestSuite;
import junit.runner.BaseTestRunner;
import java.io.BufferedReader;
import java.io.FileReader;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.text.MessageFormat;
import java.util.ResourceBundle;
import java.util.Vector;
public class TestRunnerUtil {
/** @noinspection HardCodedStringLiteral*/
private static final ResourceBundle ourBundle = ResourceBundle.getBundle("RuntimeBundle");
public static Test getTestSuite(JUnit3IdeaTestRunner runner, String[] suiteClassNames){
if (suiteClassNames.length == 0) {
return null;
}
Vector result = new Vector();
for (int i = 0; i < suiteClassNames.length; i++) {
String suiteClassName = suiteClassNames[i];
Test test;
if (suiteClassName.charAt(0) == '@') {
// all tests in the package specified
String[] classNames;
String suiteName;
try {
BufferedReader reader = new BufferedReader(new FileReader(suiteClassName.substring(1)));
Vector vector;
try {
suiteName = reader.readLine();
reader.readLine(); //category
vector = new Vector();
String line;
while ((line = reader.readLine()) != null) {
vector.addElement(line);
}
}
finally {
reader.close();
}
// toArray cannot be used here because the class must be compilable with 1.1
classNames = new String[vector.size()];
for (int j = 0; j < classNames.length; j++) {
classNames[j] = (String)vector.elementAt(j);
}
}
catch (Exception e) {
runner.runFailed(MessageFormat.format(ourBundle.getString("junit.runner.error"), new Object[] {e.toString()}));
return null;
}
test = new TestAllInPackage2(runner, suiteName, classNames);
}
else {
test = createClassOrMethodSuite(runner, suiteClassName);
if (test == null) return null;
}
result.addElement(test);
}
if (result.size() == 1) {
return (Test)result.elementAt(0);
}
else {
TestSuite suite = new TestSuite();
for (int i = 0; i < result.size(); i++) {
final Test test = (Test)result.elementAt(i);
suite.addTest(test);
}
return suite;
}
}
public static Test createClassOrMethodSuite(JUnit3IdeaTestRunner runner, String suiteClassName) {
String methodName = null;
int index = suiteClassName.indexOf(',');
if (index != -1) {
methodName = suiteClassName.substring(index + 1);
suiteClassName = suiteClassName.substring(0, index);
}
Class testClass = loadTestClass(runner, suiteClassName);
if (testClass == null) return null;
Test test = null;
if (methodName == null) {
if (test == null) {
try {
Method suiteMethod = testClass.getMethod(BaseTestRunner.SUITE_METHODNAME, new Class[0]);
if (!Modifier.isStatic(suiteMethod.getModifiers())) {
String message = MessageFormat.format(ourBundle.getString("junit.suite.must.be.static"), new Object[]{testClass.getName()});
System.err.println(message);
//runFailed(message);
return null;
}
try {
//noinspection SSBasedInspection
test = (Test)suiteMethod.invoke(null, new Class[0]); // static method
if (test == null) {
return new FailedTestCase(testClass, BaseTestRunner.SUITE_METHODNAME,
MessageFormat.format(ourBundle.getString("junit.failed.to.invoke.suite"), new Object[]{"method " + suiteClassName + ".suite() evaluates to null"}),
null);
}
test = new SuiteMethodWrapper(test, suiteClassName);
}
catch (final InvocationTargetException e) {
final String message = MessageFormat.format(ourBundle.getString("junit.failed.to.invoke.suite"), new Object[]{testClass + " " + e.getTargetException().toString()});
//System.err.println(message);
//runner.runFailed(message);
runner.clearStatus();
return new FailedTestCase(testClass, BaseTestRunner.SUITE_METHODNAME, message, e);
}
catch (IllegalAccessException e) {
String message = MessageFormat.format(ourBundle.getString("junit.failed.to.invoke.suite"), new Object[]{testClass + " " + e.toString()});
//System.err.println(message);
//runner.runFailed(message);
return new FailedTestCase(testClass, BaseTestRunner.SUITE_METHODNAME, message, e);
}
}
catch (Throwable e) {
// try to extract a test suite automatically
runner.clearStatus();
test = new TestSuite(testClass);
}
}
}
else {
test = createMethodSuite(runner, testClass, methodName);
}
return test;
}
private static Class loadTestClass(JUnit3IdeaTestRunner runner, String suiteClassName) {
try {
return Class.forName(suiteClassName, false, TestRunnerUtil.class.getClassLoader());
}
catch (ClassNotFoundException e) {
String clazz = e.getMessage();
if (clazz == null) {
clazz = suiteClassName;
}
runner.runFailed(MessageFormat.format(ourBundle.getString("junit.class.not.found"), new Object[] {clazz}));
}
catch (Exception e) {
runner.runFailed(MessageFormat.format(ourBundle.getString("junit.cannot.instantiate.tests"), new Object[]{e.toString()}));
}
return null;
}
private static Test createMethodSuite(JUnit3IdeaTestRunner runner, Class testClass, String methodName) {
runner.clearStatus();
try {
Constructor constructor = testClass.getConstructor(new Class[]{String.class});
return (Test)constructor.newInstance(new Object[]{methodName});
}
catch (NoSuchMethodException e) {
try {
Constructor constructor = testClass.getConstructor(new Class[0]);
TestCase test = (TestCase)constructor.newInstance(new Object[0]);
test.setName(methodName);
return test;
}
catch(ClassCastException e1) {
boolean methodExists;
try {
//noinspection SSBasedInspection
testClass.getMethod(methodName, new Class[0]);
methodExists = true;
}
catch (NoSuchMethodException e2) {
methodExists = false;
}
if (!methodExists) {
String error = MessageFormat.format(ourBundle.getString("junit.method.not.found"), new Object[]{methodName});
String message = MessageFormat.format(ourBundle.getString("junit.cannot.instantiate.tests"), new Object[]{error});
return new FailedTestCase(testClass, methodName, message, null);
}
runner.runFailed(MessageFormat.format(ourBundle.getString("junit.class.not.derived"), new Object[]{testClass.getName()}));
return null;
}
catch (Exception e1) {
String message = MessageFormat.format(ourBundle.getString("junit.cannot.instantiate.tests"), new Object[]{e1.toString()});
return new FailedTestCase(testClass, methodName, message, e1);
}
}
catch (Throwable e) {
String message = MessageFormat.format(ourBundle.getString("junit.cannot.instantiate.tests"), new Object[]{e.toString()});
return new FailedTestCase(testClass, methodName, message, e);
}
}
public static String testsFoundInPackageMesage(int testCount, String name) {
return MessageFormat.format(ourBundle.getString("tests.found.in.package"), new Object[]{new Integer(testCount), name});
}
public static class FailedTestCase extends TestCase {
private final String myMethodName;
private final String myMessage;
private final Throwable myThrowable;
public FailedTestCase(final Class testClass, final String methodName, final String message, final Throwable e) {
super(testClass.getName());
myMethodName = methodName;
myMessage = message;
myThrowable = e;
}
public String getMethodName() {
return myMethodName;
}
public String getMessage() {
return myMessage;
}
protected void runTest() throws Throwable {
try {
//noinspection Since15
throw new RuntimeException(myMessage, myThrowable);
}
catch (NoSuchMethodError e) {
throw new RuntimeException(myMessage);
}
}
}
public static class SuiteMethodWrapper implements Test {
private final Test mySuite;
private final String myClassName;
public SuiteMethodWrapper(Test suite, String className) {
mySuite = suite;
myClassName = className;
}
public String getClassName() {
return myClassName;
}
public int countTestCases() {
return mySuite.countTestCases();
}
public void run(TestResult result) {
mySuite.run(result);
}
public Test getSuite() {
return mySuite;
}
}
}