import java.lang.Class; import java.lang.reflect.Constructor; import java.lang.reflect.Method; import java.util.Random; import java.util.Vector; /** * A class that helps us test unary integer methods. Written as an * example for the take home in CS223. * * @author Samuel A. Rebelsky */ public class UnaryIntegerMethodTester { // +--------+------------------------------------------------------------ // | Fields | // +--------+ /** * The class that we're testing. */ Class c; /** * The nullary constructor for that class. */ Constructor cons; /** * All the unary methods in that class. */ Method[] unaries; /** * A helpful random-number generator */ Random rng; // +--------------+------------------------------------------------------ // | Constructors | // +--------------+ /** * Create a new tester for class _c. Verify that class * _c has a nullary constructor. * * @exception NoNullaryConstructorException * When there is no nullary constructor. * @exception NoSuchMethodException * When c lacks a unary integer method. */ public UnaryIntegerMethodTester(Class _c) throws NoNullaryConstructorException, NoSuchMethodException { this.c = _c; // Verify that it has a constructor. Note that // getConstructor will throw a NoSuchMethodException // if it fails. try { this.cons = this.c.getConstructor(null); } catch (Exception e) { throw new NoNullaryConstructorException(); } // Shove all the unary methods in Vector v; Vector v = new Vector(); Method[] methods = this.c.getMethods(); for (int i = 0; i < methods.length; i++) { Class[] params = methods[i].getParameterTypes(); if ((params.length == 1) && (params[0].equals(Integer.TYPE))) v.add(methods[i]); } // for // Sanity check: Are there any unary methods? if (v.size() == 0) throw new NoSuchMethodException("no unary methods"); // Copy those methods into an array. this.unaries = (Method[]) v.toArray(new Method[0]); // Get a random number generator; this.rng = new Random(); } // UnaryIntegerMethodTester(Class) // +---------+----------------------------------------------------------- // | Methods | // +---------+ /** * Print all of the unary methods to standard output. */ public void printMethods() { for (int i = 0; i < this.unaries.length; i++) System.out.println(this.unaries[i].toString()); } // printUnaryMethods() /** * Conduct n tests with randomly-generated numbers. */ public boolean randomTest(int n) { Object base = new Object(); try { base = this.cons.newInstance(null); } catch (Exception e) { // Should never happen. } boolean passed = true; for (int i = 0; i < n; i++) { Object[] args= new Object[1]; args[0] = new Integer(rng.nextInt()); for (int j = 0; j < this.unaries.length; j++) { try { this.unaries[j].invoke(base, args); } catch (Exception e) { passed = false; System.out.println(e); e.printStackTrace(System.out); } // catch } // for j } // for i return passed; } // randomTest(int) // +------+-------------------------------------------------------------- // | Main | // +------+ /** * Test all the classes specified on the command line. */ public static void main(String[] args) { for (int i = 0; i < args.length; i++) { System.out.println("*** Testing class " + args[i] + " ***"); try { Class c = Class.forName(args[i]); try { UnaryIntegerMethodTester tester = new UnaryIntegerMethodTester(c); // Print the methods System.out.println("Methods:"); tester.printMethods(); // Try some random tests System.out.println("Random tests:"); if (tester.randomTest(5)) { System.out.println("Passed."); } } catch (NoNullaryConstructorException nnme) { System.out.println(args[i] + " lacks a nullary constructor"); } catch (NoSuchMethodException nsme) { System.out.println(args[i] + " lacks unary integer methods"); } } catch (Exception e) { System.out.println("No such class: " + e.toString() + "."); e.printStackTrace(System.out); } catch (NoClassDefFoundError nncdfe) { System.out.println("No such class: " + nncdfe.toString() + "."); } System.out.println(); } // for } // main(String[]) } // class UnaryIntegerMethodTester