    1   /* AltTestSuite.java
    2    *
    3    * Created on Feb 20, 2007
    4    *
    5    * Copyright (C) 2007 Internet Archive.
    6    *
    7    * This file is part of the Heritrix web crawler (crawler.archive.org).
    8    *
    9    * Heritrix is free software; you can redistribute it and/or modify
    10   * it under the terms of the GNU Lesser Public License as published by
    11   * the Free Software Foundation; either version 2.1 of the License, or
    12   * any later version.
    13   *
    14   * Heritrix is distributed in the hope that it will be useful,
    15   * but WITHOUT ANY WARRANTY; without even the implied warranty of
    16   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    17   * GNU Lesser Public License for more details.
    18   *
    19   * You should have received a copy of the GNU Lesser Public License
    20   * along with Heritrix; if not, write to the Free Software
    21   * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    22   */
    23  package org.archive.crawler.selftest;
    24
    25  import java.lang.reflect.Method;
    26  import java.lang.reflect.Modifier;
    27  import java.util.Vector;
    28
    29  import junit.framework.Test;
    30  import junit.framework.TestSuite;
    31
    32  /***
    33   * Variant TestSuite that can build tests including methods with an alternate
    34   * prefix (other than 'test'). Copies code from TestSuite because necessary
    35   * methods to change are private rather than protected.
    36   *
    37   * @author gojomo
    38   * @version $Id: MaxLinkHopsSelfTest.java 4667 2006-09-26 20:38:48 +0000 (Tue, 26 Sep 2006) paul_jack $
    39   */
    40  public class AltTestSuite extends TestSuite {
    41      /*** a method prefix other than 'test' that is also recognized as tests */
    42      String altPrefix;
    43
    44      /***
    45       * Constructs a TestSuite from the given class. Copied from superclass so
    46       * that local alternate addTestMethod() will be visible, which in turn uses
    47       * an isTestMethod() that accepts methods with the altPrefix in addition
    48       * to 'test'.
    49       * @param theClass Class from which to build suite
    50       * @param prefix alternate method prefix to also find test methods
    51       */
    52       public AltTestSuite(final Class theClass, String prefix) {
    53          this.altPrefix = prefix;
    54          setName(theClass.getName());
    55          try {
    56              getTestConstructor(theClass); // Avoid generating multiple error messages
    57          } catch (NoSuchMethodException e) {
    58              addTest(warning("Class "+theClass.getName()+" has no public constructor TestCase(String name) or TestCase()"));
    59              return;
    60          }
    61
    62          if (!Modifier.isPublic(theClass.getModifiers())) {
    63              addTest(warning("Class "+theClass.getName()+" is not public"));
    64              return;
    65          }
    66
    67          Class superClass= theClass;
    68          Vector names= new Vector();
    69          while (Test.class.isAssignableFrom(superClass)) {
    70              Method[] methods= superClass.getDeclaredMethods();
    71              for (int i= 0; i < methods.length; i++) {
    72                  addTestMethod(methods[i], names, theClass);
    73              }
    74              superClass= superClass.getSuperclass();
    75          }
    76          if (testCount() == 0)
    77              addTest(warning("No tests found in "+theClass.getName()));
    78      }
    79
    80      // copied from superclass
    81      private void addTestMethod(Method m, Vector names, Class theClass) {
    82          String name= m.getName();
    83          if (names.contains(name))
    84              return;
    85          if (! isPublicTestMethod(m)) {
    86              if (isTestMethod(m))
    87                  addTest(warning("Test method isn't public: "+m.getName()));
    88              return;
    89          }
    90          names.addElement(name);
    91          addTest(createTest(theClass, name));
    92      }
    93
    94      // copied from superclass
    95      private boolean isPublicTestMethod(Method m) {
    96          return isTestMethod(m) && Modifier.isPublic(m.getModifiers());
    97       }
    98
    99      // copied & extended from superclass
    100     private boolean isTestMethod(Method m) {
    101         String name= m.getName();
    102         Class[] parameters= m.getParameterTypes();
    103         Class returnType= m.getReturnType();
    104         return parameters.length == 0
    105             && (name.startsWith("test")||name.startsWith(altPrefix))
    106             && returnType.equals(Void.TYPE);
    107      }
    108 }