package utjava;
import java.io.File;
import java.io.FileFilter;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.*;
//--------------------------------------------
public class ut
{
//Use this section to configure ut:
public static String cUTFileSuffix = "";
public static String cUTClassNamePrefix = "test";
public static String cUTMethodPrefix = "test";
//configuration section done
private static Statistics stats = new Statistics();
private static ArrayList files = new ArrayList();
//--------------------------------------------
public static void main(String args[])
{
Init(args);
Run();
stats.dump();
System.exit(stats.numerrors + stats.numexcps);
}
//--------------------------------------------
//-- UnitTest methods should call this routine to check UT conditions
public static void utassert(boolean actual)
{
utassert(Boolean.toString(actual), "true");
}
public static void utassert(int actual, int expected)
{
utassert(Integer.toString(actual), Integer.toString(expected));
}
public static void utassert(String actual, String expected)
{
stats.numasserts++;
if (expected.compareTo(actual) == 0) return ;
stats.numerrors++;
System.out.println("utassert: actual='" + actual + "' expected='" + expected + "'");
// (new UTAssert()).printStackTrace();
// System.out.println("");
}
//--------------------------------------------
//-- private from here on
//--------------------------------------------
//--------------------------------------------
//-- this is used to get the stacktrace to have a nice exception name
private static class UTAssert extends Exception
{
//we want just the name
}
//--------------------------------------------
static void Init(String args[])
{
File afile = new File(checkArguments(args));
if (!afile.isDirectory())
files.add(afile.getName());
else
getFileList(afile);
}
//--------------------------------------------
static void getFileList(File rootdir)
{
Stack dirs = new Stack();
dirs.push(rootdir);
while (!dirs.empty())
{
File dir = (File) dirs.pop();
File tests[] = dir.listFiles(new isMatch());
for (int i = 0; i < tests.length; ++i)
{
if (tests[i].isDirectory())
dirs.push(tests[i]);
else if (dir.getName().equals("."))
files.add(tests[i].getName());
else
files.add(dir.getName() + "." + tests[i].getName());
}
}
}
//--------------------------------------------
static void Run()
{
for (int i = 0; i < files.size(); ++i)
{
InvokeUnitTests((String)files.get(i));
}
}
private static void usage()
{
System.out.println("usage: java utjava.ut [options] <dir_where_ut_class_files_are>");
System.out.println(" Options are:");
System.out.println(" -fs:sss file name suffix, sss is the file name suffix");
System.out.println(" -cp:sss class name prefix, sss is the class name prefix");
System.out.println(" -mp:sss method name prefix, sss is the method name prefix");
System.exit(1);
}
//--------------------------------------------
private static String checkArguments(String args[])
{
boolean error = false;
if (args.length < 1)
{
System.out.println("missing directory");
error = true;
}
String dir = null;
for (int i = 0; i < args.length; ++i)
{
if (args[i].startsWith("-fs:"))
{
cUTFileSuffix = args[i].substring(4);
System.out.println("File name suffix : " + cUTFileSuffix);
}
else if (args[i].startsWith("-cp:"))
{
cUTClassNamePrefix = args[i].substring(4);
System.out.println("Class name prefix: " + cUTClassNamePrefix);
}
else if (args[i].startsWith("-mp:"))
{
cUTMethodPrefix = args[i].substring(4);
System.out.println("Method prefix : " + cUTMethodPrefix);
}
else
{
if (args[i].startsWith("-"))
{
System.out.println("unknown switch: " + args[i]);
error = true;
}
else if (dir != null)
{
System.out.println("unknown arg: " + args[i]);
error = true;
}
else
dir = args[i];
}
}
if (error)
usage();
return dir;
}
//--------------------------------------------
//-- filter out non-UT files.
private static class isMatch implements FileFilter
{
public boolean accept(File f)
{
return f.isDirectory() ||
(f.getName().endsWith(ut.cUTFileSuffix + ".class") &&
f.getName().startsWith(ut.cUTClassNamePrefix));
}
}
//--------------------------------------------
//-- keep track of what happened
static class Statistics
{
public int numclassfiles;
public int numclasses;
public int numtests;
public int numasserts;
public int numerrors;
public int numexcps;
//--------------------------------------------
public Statistics()
{
numclassfiles = 0;
numclasses = 0;
numtests = 0;
numasserts = 0;
numerrors = 0;
numexcps = 0;
}
//--------------------------------------------
public void dump()
{
System.out.println("");
System.out.println("Number of ut class files: " + numclassfiles);
System.out.println("Number of ut classes : " + numclasses);
System.out.println("Number of unit tests : " + numtests);
System.out.println("Number of utassert calls: " + numasserts);
System.out.println("Number of errors : " + numerrors);
System.out.println("Number of exceptions : " + numexcps);
if (numerrors != 0 || numexcps != 0)
System.out.println("************* FAILED *** FAILED *** FAILED *************");
}
}
//--------------------------------------------
public static void InvokeUnitTests(String origname)
{
stats.numclassfiles++;
String classname = stripExtension(origname);
if (!isATestClass(classname)) return ;
stats.numclasses++;
try
{
//get methods for the current test
Class testc;
try
{
testc = Class.forName(classname);
}
catch (ClassNotFoundException cnfe)
{
//class probably is not part of a package. try again.
int dot = classname.indexOf('.');
if (dot != - 1)
classname = classname.substring(dot + 1);
testc = Class.forName(classname);
}
if (!isClassOK(testc)) return ;
Object testo = testc.newInstance();
Method m[] = testc.getDeclaredMethods();
for (int j = 0; j < m.length; ++j)
{
UnitTest unittest = new UnitTest(classname, testo, m[j]);
if (!unittest.isOKUnitTest()) continue;
unittest.Invoke();
}
}
catch (Exception excp)
{
//an error occurred loading the class or constructing an instance of it
System.out.println("InvokeUnitTests: " + excp.getMessage());
excp.printStackTrace();
}
}
private static boolean isATestClass(String classname)
{
if (classname.indexOf('$') != -1) return false;
String name;
int dot = classname.lastIndexOf('.');
if (dot != -1)
name = classname.substring(dot+1);
else
name = classname;
return name.startsWith(ut.cUTClassNamePrefix);
}
private static boolean isClassOK(Class testc)
{
int modifiers = testc.getModifiers();
return Modifier.isPublic(modifiers) &&
!Modifier.isStatic(modifiers);
}
//--------------------------------------------
private static String stripExtension(String origname)
{
int dot = origname.lastIndexOf('.');
if (dot == - 1)
return origname;
else
return origname.substring(0, dot);
}
//--------------------------------------------
//-- runs the UT
private static class UnitTest
{
private String classname;
private Object testo;
private Method testm;
//--------------------------------------------
public UnitTest(String name, Object o, Method m)
{
classname = name;
testo = o;
testm = m;
}
//--------------------------------------------
//-- invoke the UT, catch any errors
private void Invoke()
{
stats.numtests++;
try
{
testm.invoke(testo, null);
}
catch (Throwable th)
{
stats.numexcps++;
System.out.println("-------- Exception thrown: class is " + classname
+ "." + testm.getName()
+ "(): " + th.getMessage());
th.printStackTrace();
System.out.println("");
}
}
//--------------------------------------------
//-- it's a valid unit test if it's signature looks like:
//-- void testxx()
//-- where xx is an arbitrary, perhaps empty string
private boolean isOKUnitTest()
{
int modifiers = testm.getModifiers();
return
testm.getName().startsWith(ut.cUTMethodPrefix) && //correct prefix
testm.getParameterTypes().length == 0 && //no parameters
testm.getReturnType().getName().equals("void") && //void return
Modifier.isPublic(modifiers) &&
!Modifier.isStatic(modifiers);
}
}
}
|