PageRenderTime 27ms CodeModel.GetById 34ms RepoModel.GetById 0ms app.codeStats 0ms

/test/org/jruby/test/TestUnitTestSuite.java

https://github.com/rkh/jruby
Java | 237 lines | 187 code | 34 blank | 16 comment | 22 complexity | 806128834540f428008e312ffe680350 MD5 | raw file
  1. /*
  2. * TestUnitTestSuite.java
  3. * JUnit based test
  4. *
  5. * Created on January 15, 2007, 4:06 PM
  6. */
  7. package org.jruby.test;
  8. import java.io.BufferedReader;
  9. import java.io.ByteArrayInputStream;
  10. import java.io.ByteArrayOutputStream;
  11. import java.io.File;
  12. import java.io.FileInputStream;
  13. import java.io.FileNotFoundException;
  14. import java.io.FileReader;
  15. import java.io.IOException;
  16. import java.io.InputStreamReader;
  17. import java.io.PrintStream;
  18. import java.util.ArrayList;
  19. import java.util.Iterator;
  20. import java.util.List;
  21. import java.util.regex.Matcher;
  22. import java.util.regex.Pattern;
  23. import junit.framework.TestCase;
  24. import junit.framework.TestSuite;
  25. import org.jruby.Ruby;
  26. import org.jruby.RubyArray;
  27. import org.jruby.exceptions.RaiseException;
  28. /**
  29. *
  30. * @author headius
  31. */
  32. public class TestUnitTestSuite extends TestSuite {
  33. private static final String TEST_DIR = "test";
  34. private static final String REGEXP_TEST_CASE_SUBCLASS = "^\\s*class\\s+([^\\s]+)\\s*<.*TestCase\\s*$";
  35. private static final Pattern PATTERN_TEST_CASE_SUBCLASS = Pattern.compile(REGEXP_TEST_CASE_SUBCLASS);
  36. /**
  37. * suite method automatically generated by JUnit module
  38. */
  39. public TestUnitTestSuite(String testIndex) throws Exception {
  40. File testDir;
  41. if (System.getProperty("basedir") != null) {
  42. testDir = new File(System.getProperty("basedir"), "target/test-classes/" + TEST_DIR);
  43. } else {
  44. testDir = new File(TEST_DIR);
  45. }
  46. File testIndexFile = new File(testDir, testIndex);
  47. if (!testIndexFile.canRead()) {
  48. // Since we don't have any other error reporting mechanism, we
  49. // add the error message as an always-failing test to the test suite.
  50. addTest(new FailingTest("TestUnitTestSuite",
  51. "Couldn't locate " + testIndex +
  52. ". Make sure you run the tests from the base " +
  53. "directory of the JRuby sourcecode."));
  54. return;
  55. }
  56. BufferedReader testFiles =
  57. new BufferedReader(new InputStreamReader(new FileInputStream(testIndexFile)));
  58. String line;
  59. Interpreter[] ints = new Interpreter[8];
  60. for (int i = 0; (line = testFiles.readLine()) != null; i++) {
  61. line = line.trim();
  62. if (line.startsWith("#") || line.length() == 0) {
  63. continue;
  64. }
  65. if (ints[i % ints.length] == null) {
  66. ints[i % ints.length] = new Interpreter();
  67. }
  68. addTest(createTest(line, testDir, ints[i % ints.length]));
  69. }
  70. }
  71. protected TestCase createTest(String line, File testDir, Interpreter interpreter) {
  72. return new ScriptTest(line, testDir, interpreter);
  73. }
  74. protected static class Interpreter {
  75. ByteArrayInputStream in;
  76. ByteArrayOutputStream out;
  77. ByteArrayOutputStream err;
  78. PrintStream printOut;
  79. PrintStream printErr;
  80. Ruby runtime;
  81. public Interpreter() {
  82. in = new ByteArrayInputStream(new byte[0]);
  83. out = new ByteArrayOutputStream();
  84. err = new ByteArrayOutputStream();
  85. printOut = new PrintStream(out);
  86. printErr = new PrintStream(err);
  87. runtime = Ruby.newInstance(in, printOut, printErr);
  88. ArrayList loadPath = new ArrayList();
  89. loadPath.add("test/externals/bfts");
  90. loadPath.add("test/externals/ruby_test/lib");
  91. runtime.getLoadService().init(loadPath);
  92. runtime.defineGlobalConstant("ARGV", runtime.newArray());
  93. }
  94. public void setUp() {
  95. runtime.setCurrentDirectory(System.getProperty("user.dir"));
  96. }
  97. public void tearDown() {
  98. in.reset();
  99. out.reset();
  100. err.reset();
  101. }
  102. }
  103. protected class ScriptTest extends TestCase {
  104. private final String filename;
  105. private final File testDir;
  106. private final Interpreter interpreter;
  107. public ScriptTest(String filename, File dir, Interpreter interpreter) {
  108. super(filename);
  109. this.filename = filename;
  110. this.testDir = dir;
  111. this.interpreter = interpreter;
  112. }
  113. @Override
  114. protected void setUp() throws Exception {
  115. interpreter.setUp();
  116. }
  117. @Override
  118. protected void tearDown() throws Exception {
  119. interpreter.tearDown();
  120. }
  121. protected String generateTestScript(String scriptName, String testClass) {
  122. StringBuffer script = new StringBuffer();
  123. script.append("require 'test/junit_testrunner.rb'\n");
  124. script.append("require '" + scriptName + "'\n");
  125. script.append("runner = Test::Unit::UI::JUnit::TestRunner.new(" + testClass + ")\n");
  126. script.append("runner.start\n");
  127. script.append("runner.faults\n");
  128. return script.toString();
  129. }
  130. private String scriptName() {
  131. return new File(testDir, filename).getPath();
  132. }
  133. private String pretty(List list) {
  134. StringBuffer prettyOut = new StringBuffer();
  135. for (Iterator iter = list.iterator(); iter.hasNext();) {
  136. prettyOut.append(iter.next().toString());
  137. }
  138. return prettyOut.toString();
  139. }
  140. private List<String> getTestClassNamesFromReadingTestScript(String filename) {
  141. List<String> testClassNames = new ArrayList<String>();
  142. File f = new File(TEST_DIR + "/" + filename + ".rb");
  143. BufferedReader reader = null;
  144. try {
  145. reader = new BufferedReader(new FileReader(f));
  146. while (true) {
  147. String line = reader.readLine();
  148. if (line == null) break;
  149. Matcher m = PATTERN_TEST_CASE_SUBCLASS.matcher(line);
  150. if (m.find())
  151. {
  152. testClassNames.add(m.group(1));
  153. }
  154. }
  155. if (!testClassNames.isEmpty()) {
  156. return testClassNames;
  157. }
  158. } catch (FileNotFoundException e) {
  159. throw new RuntimeException(e);
  160. } catch (IOException e) {
  161. throw new RuntimeException(e);
  162. }
  163. finally {
  164. if (reader != null) {
  165. try {
  166. reader.close();
  167. } catch (IOException e) {
  168. throw new RuntimeException("Could not close reader!", e);
  169. }
  170. }
  171. }
  172. throw new RuntimeException("No *TestCase derivative found in '" + filename + ".rb'!");
  173. }
  174. @Override
  175. public void runTest() throws Throwable {
  176. List<String> testClassNames = getTestClassNamesFromReadingTestScript(filename);
  177. // there might be more test classes in a single file, so we iterate over them
  178. for (String testClass : testClassNames) {
  179. try {
  180. synchronized(interpreter) {
  181. RubyArray faults = (RubyArray) interpreter.runtime.executeScript(generateTestScript(scriptName(), testClass), scriptName() + "_generated_test.rb");
  182. if (!faults.isEmpty()) {
  183. StringBuffer faultString = new StringBuffer("Faults encountered running " + scriptName() + ", complete output follows:\n");
  184. for (Iterator iter = faults.iterator(); iter.hasNext();) {
  185. String fault = iter.next().toString();
  186. faultString.append(fault).append("\n");
  187. }
  188. System.out.write(interpreter.out.toByteArray());
  189. System.err.write(interpreter.err.toByteArray());
  190. fail(faultString.toString());
  191. }
  192. }
  193. } catch (RaiseException re) {
  194. synchronized (interpreter) {
  195. System.out.write(interpreter.out.toByteArray());
  196. System.err.write(interpreter.err.toByteArray());
  197. }
  198. fail("Faults encountered running " + scriptName() + ", complete output follows:\n" + re.getException().message + "\n" + pretty(((RubyArray)re.getException().backtrace()).getList()));
  199. }
  200. }
  201. }
  202. }
  203. }