1. /*
  2. * Copyright 2000-2002,2004 The Apache Software Foundation
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. *
  16. */
  17. package org.apache.tools.ant.taskdefs.optional.junit;
  18. import java.io.File;
  19. import java.util.Enumeration;
  20. import java.util.Vector;
  21. import org.apache.tools.ant.DirectoryScanner;
  22. import org.apache.tools.ant.Project;
  23. import org.apache.tools.ant.types.FileSet;
  24. /**
  25. * <p> Create then run <code>JUnitTest</code>'s based on the list of files
  26. * given by the fileset attribute.
  27. *
  28. * <p> Every <code>.java</code> or <code>.class</code> file in the fileset is
  29. * assumed to be a testcase.
  30. * A <code>JUnitTest</code> is created for each of these named classes with
  31. * basic setup inherited from the parent <code>BatchTest</code>.
  32. *
  33. * @see JUnitTest
  34. */
  35. public final class BatchTest extends BaseTest {
  36. /** the reference to the project */
  37. private Project project;
  38. /** the list of filesets containing the testcase filename rules */
  39. private Vector filesets = new Vector();
  40. /**
  41. * create a new batchtest instance
  42. * @param project the project it depends on.
  43. */
  44. public BatchTest(Project project) {
  45. this.project = project;
  46. }
  47. /**
  48. * Add a new fileset instance to this batchtest. Whatever the fileset is,
  49. * only filename that are <tt>.java</tt> or <tt>.class</tt> will be
  50. * considered as 'candidates'.
  51. * @param fs the new fileset containing the rules to get the testcases.
  52. */
  53. public void addFileSet(FileSet fs) {
  54. filesets.addElement(fs);
  55. }
  56. /**
  57. * Return all <tt>JUnitTest</tt> instances obtain by applying the fileset rules.
  58. * @return an enumeration of all elements of this batchtest that are
  59. * a <tt>JUnitTest</tt> instance.
  60. */
  61. public final Enumeration elements() {
  62. JUnitTest[] tests = createAllJUnitTest();
  63. return Enumerations.fromArray(tests);
  64. }
  65. /**
  66. * Convenient method to merge the <tt>JUnitTest</tt>s of this batchtest
  67. * to a <tt>Vector</tt>.
  68. * @param v the vector to which should be added all individual tests of this
  69. * batch test.
  70. */
  71. final void addTestsTo(Vector v) {
  72. JUnitTest[] tests = createAllJUnitTest();
  73. v.ensureCapacity(v.size() + tests.length);
  74. for (int i = 0; i < tests.length; i++) {
  75. v.addElement(tests[i]);
  76. }
  77. }
  78. /**
  79. * Create all <tt>JUnitTest</tt>s based on the filesets. Each instance
  80. * is configured to match this instance properties.
  81. * @return the array of all <tt>JUnitTest</tt>s that belongs to this batch.
  82. */
  83. private JUnitTest[] createAllJUnitTest() {
  84. String[] filenames = getFilenames();
  85. JUnitTest[] tests = new JUnitTest[filenames.length];
  86. for (int i = 0; i < tests.length; i++) {
  87. String classname = javaToClass(filenames[i]);
  88. tests[i] = createJUnitTest(classname);
  89. }
  90. return tests;
  91. }
  92. /**
  93. * Iterate over all filesets and return the filename of all files
  94. * that end with <tt>.java</tt> or <tt>.class</tt>. This is to avoid
  95. * wrapping a <tt>JUnitTest</tt> over an xml file for example. A Testcase
  96. * is obviously a java file (compiled or not).
  97. * @return an array of filenames without their extension. As they should
  98. * normally be taken from their root, filenames should match their fully
  99. * qualified class name (If it is not the case it will fail when running the test).
  100. * For the class <tt>org/apache/Whatever.class</tt> it will return <tt>org/apache/Whatever</tt>.
  101. */
  102. private String[] getFilenames() {
  103. Vector v = new Vector();
  104. final int size = this.filesets.size();
  105. for (int j = 0; j < size; j++) {
  106. FileSet fs = (FileSet) filesets.elementAt(j);
  107. DirectoryScanner ds = fs.getDirectoryScanner(project);
  108. ds.scan();
  109. String[] f = ds.getIncludedFiles();
  110. for (int k = 0; k < f.length; k++) {
  111. String pathname = f[k];
  112. if (pathname.endsWith(".java")) {
  113. v.addElement(pathname.substring(0, pathname.length() - ".java".length()));
  114. } else if (pathname.endsWith(".class")) {
  115. v.addElement(pathname.substring(0, pathname.length() - ".class".length()));
  116. }
  117. }
  118. }
  119. String[] files = new String[v.size()];
  120. v.copyInto(files);
  121. return files;
  122. }
  123. /**
  124. * Convenient method to convert a pathname without extension to a
  125. * fully qualified classname. For example <tt>org/apache/Whatever</tt> will
  126. * be converted to <tt>org.apache.Whatever</tt>
  127. * @param filename the filename to "convert" to a classname.
  128. * @return the classname matching the filename.
  129. */
  130. public static final String javaToClass(String filename) {
  131. return filename.replace(File.separatorChar, '.');
  132. }
  133. /**
  134. * Create a <tt>JUnitTest</tt> that has the same property as this
  135. * <tt>BatchTest</tt> instance.
  136. * @param classname the name of the class that should be run as a
  137. * <tt>JUnitTest</tt>. It must be a fully qualified name.
  138. * @return the <tt>JUnitTest</tt> over the given classname.
  139. */
  140. private JUnitTest createJUnitTest(String classname) {
  141. JUnitTest test = new JUnitTest();
  142. test.setName(classname);
  143. test.setHaltonerror(this.haltOnError);
  144. test.setHaltonfailure(this.haltOnFail);
  145. test.setFiltertrace(this.filtertrace);
  146. test.setFork(this.fork);
  147. test.setIf(this.ifProperty);
  148. test.setUnless(this.unlessProperty);
  149. test.setTodir(this.destDir);
  150. test.setFailureProperty(failureProperty);
  151. test.setErrorProperty(errorProperty);
  152. Enumeration list = this.formatters.elements();
  153. while (list.hasMoreElements()) {
  154. test.addFormatter((FormatterElement) list.nextElement());
  155. }
  156. return test;
  157. }
  158. }