/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/*
* WekaTestSuite.java
* Copyright (C) 2005 University of Waikato, Hamilton, New Zealand
*
*/
package weka.test;
import weka.core.ClassDiscovery;
import weka.gui.GenericPropertiesCreator;
import java.util.Collections;
import java.util.StringTokenizer;
import java.util.Vector;
import junit.framework.Test;
import junit.framework.TestSuite;
/**
* Extends the standard TestSuite class wtih some additional methods for
* automatic generation of a series of tests.
*
* @author FracPete (fracpete at waikato dot ac dot nz)
* @version $Revision: 1.5 $
* @see GenericPropertiesCreator
* @see ClassDiscovery
*/
public class WekaTestSuite
extends TestSuite {
/**
* checks whether the classname is a valid one, i.e., from a public class
*
* @param classname the classname to check
* @return whether the classname is a valid one
*/
protected static boolean isValidClassname(String classname) {
return (classname.indexOf("$") == -1);
}
/**
* determines all the classes derived from the given superclass in the
* specified packages
*
* @param superclass the class to find subclasses for
* @param pacakges the packages to search in for subclasses
* @return the classes that were found
*/
protected static Vector getClassnames(String superclass, Vector packages) {
Vector result;
Vector names;
int i;
int n;
result = new Vector();
for (i = 0; i < packages.size(); i++) {
names = ClassDiscovery.find(superclass, (String) packages.get(i));
for (n = 0; n < names.size(); n++) {
// skip non-public classes
if (isValidClassname((String) names.get(n)))
result.add(names.get(n));
}
}
return result;
}
/**
* returns a Vector with all the classnames of the specified property in
* the GenericPropertiesCreator.
*
* @param property the property to get the classnames for
* @return the classnames of the given property
* @see GenericPropertiesCreator
*/
protected static Vector getClassnames(String property) {
GenericPropertiesCreator gpc;
String classes;
Vector result;
StringTokenizer tok;
String classname;
result = new Vector();
try {
gpc = new GenericPropertiesCreator();
gpc.execute(false);
classes = gpc.getOutputProperties().getProperty(property);
tok = new StringTokenizer(classes, ",");
while (tok.hasMoreTokens()) {
classname = tok.nextToken();
// skip non-public classes
if (isValidClassname(classname))
result.add(classname);
}
}
catch (Exception e) {
e.printStackTrace();
}
return result;
}
/**
* generates a Test class name for a given "regular" class
*
* @param classname the class to generate the Test class name for
* @return the classname of the test
*/
protected static String getTestClassname(String classname) {
if (!classname.endsWith("Test"))
return classname + "Test";
else
return classname;
}
/**
* returns the test class if it exists, for the given class, otherwise
* null
*
* @param classname the class to retrieve the Test class for
* @return non-null, if the Test class exists
*/
protected static Class testClassFor(String classname) {
Class result;
result = null;
try {
result = Class.forName(getTestClassname(classname));
}
catch (Exception e) {
// ignore it
}
return result;
}
/**
* tries to find Test classes for all the given classnames, if successful
* they're added to the Test
*
* @param classnames the classnames to get
*/
protected static TestSuite addAll(Vector classnames) {
int i;
Class tc;
TestSuite result;
result = new TestSuite();
for (i = 0; i < classnames.size(); i++) {
tc = testClassFor((String) classnames.get(i));
if (tc != null)
result.addTest(new TestSuite(tc));
}
return result;
}
/**
* adds all Tests for classes that are available via the
* GenericPropertiesCreator's property to the Test and returns that
*
* @param property the GPC property to add all the classes to the Test
* @return the generated Test
* @see GenericPropertiesCreator
*/
public static TestSuite addAll(String property) {
return addAll(getClassnames(property));
}
/**
* adds all available Tests for a given superclass and the packages to
* check in
*
* @param superclass the superclass to find tests of subclasses for
* @param packages the packages (strings) to search in
* @return the generated Test
*/
public static TestSuite addAll(String superclass, Vector packages) {
return addAll(getClassnames(superclass, packages));
}
/**
* determines all the test classes that are missing for the given
* classnames.
*
* @param classnames the classnames that are to be checked
* @return the missing Test classes
*/
protected static Vector getMissing(Vector classnames) {
int i;
Vector result;
result = new Vector();
for (i = 0; i < classnames.size(); i++) {
if (testClassFor((String) classnames.get(i)) == null)
result.add(getTestClassname((String) classnames.get(i)));
}
return result;
}
/**
* determines all the test classes that are missing for the given
* GenericPropertiesCreator's property's elements
*
* @param property the GPC property to determine the missing Tests for
* @return the classnames of the missing Tests
*/
public static Vector getMissing(String property) {
return getMissing(getClassnames(property));
}
/**
* determines all the test classes of subclasses that are missing for the
* given superclass and packages to look in for
*
* @param superclass the superclass to check for tests of derived classes
* @param packages the packages to search in
* @return the classnames of the missing Tests
*/
public static Vector getMissing(String superclass, Vector packages) {
return getMissing(getClassnames(superclass, packages));
}
/**
* outputs the missing Test classes (if any) and returns the given TestSuite
*
* @param t the generated test suite, is only passed through
* @param missing the missing test classes, if any
* @return the previously generate test suite
*/
protected static Test suite(Test t, Vector missing) {
if (missing.size() > 0) {
Collections.sort(missing);
System.out.println("Missing Test classes:");
for (int i = 0; i < missing.size(); i++)
System.out.println("- " + missing.get(i));
System.out.println();
}
return t;
}
/**
* Generates a TestSuite for the given GenericPropertiesCreator property
* and returns it. Potentially missing test classes are output.
*
* @param property the GPC property to generate a test suite from
* @return the generated test suite
*/
public static Test suite(String property) {
return suite(addAll(property), getMissing(property));
}
/**
* Generates a TestSuite for all the Test class of subclasses of the given
* superclasses. The given package names are used in the search.
* Potentially missing test classes are output.
*
* @param superclass the class to generate the test suite for
* @param packages the packages to look for test classes
* @return the generated test suite
*/
public static Test suite(String superclass, Vector packages) {
return suite(addAll(superclass, packages), getMissing(superclass, packages));
}
}