Remove DrupalWebTestCase::getInfo(), and parse docblocks instead.

From: Damien Tournoud <damien@tournoud.net>


---

 block/block.test             |   28 +++++--------
 simpletest/simpletest.info   |    1 
 simpletest/simpletest.module |   92 ++++++++++++++++++++++++++----------------
 3 files changed, 71 insertions(+), 50 deletions(-)

diff --git modules/block/block.test modules/block/block.test
index f7a5c98..5be6950 100644
--- modules/block/block.test
+++ modules/block/block.test
@@ -1,17 +1,15 @@
 <?php
 // $Id: block.test,v 1.11 2009-02-11 03:38:46 webchick Exp $
 
+/**
+ * Add, edit and delete custom block. Configure and move a module-defined block.
+ *
+ * @test-name Block functionality
+ * @test-group Block
+ */
 class BlockTestCase extends DrupalWebTestCase {
   protected $regions;
 
-  function getInfo() {
-    return array(
-      'name' => t('Block functionality'),
-      'description' => t('Add, edit and delete custom block. Configure and move a module-defined block.'),
-      'group' => t('Block'),
-    );
-  }
-
   function setUp() {
     parent::setUp();
 
@@ -151,15 +149,13 @@ class BlockTestCase extends DrupalWebTestCase {
   }
 }
 
+/**
+ * Check the administer page for non default theme.
+ *
+ * @test-name Non default theme admin
+ * @test-group Block
+ */
 class NonDefaultBlockAdmin extends DrupalWebTestCase {
-  function getInfo() {
-    return array(
-      'name' => t('Non default theme admin'),
-      'description' => t('Check the administer page for non default theme.'),
-      'group' => t('Block'),
-    );
-  }
-
   /**
    * Test non-default theme admin.
    */
diff --git modules/simpletest/simpletest.info modules/simpletest/simpletest.info
index 778cb24..f613131 100644
--- modules/simpletest/simpletest.info
+++ modules/simpletest/simpletest.info
@@ -6,3 +6,4 @@ version = VERSION
 core = 7.x
 files[] = simpletest.module
 files[] = simpletest.install
+files[] = drupal_web_test_case.php
diff --git modules/simpletest/simpletest.module modules/simpletest/simpletest.module
index 2d552c4..35d7a55 100644
--- modules/simpletest/simpletest.module
+++ modules/simpletest/simpletest.module
@@ -89,7 +89,7 @@ function simpletest_test_form() {
     $header = array(t('Message'), t('Group'), t('Filename'), t('Line'), t('Function'), array('colspan' => 2, 'data' => t('Status')));
     while ($result = db_fetch_object($results)) {
       $class = $result->test_class;
-      $info = $uncategorized_tests[$class]->getInfo();
+      $info = $uncategorized_tests[$class];
       $group = $info['group'];
       $selected_tests[$group][$class] = TRUE;
       if (!isset($group_summary[$group])) {
@@ -130,7 +130,7 @@ function simpletest_test_form() {
     foreach ($form['results'] as $group => &$elements) {
       $group_ok = TRUE;
       foreach ($elements as $class => &$element) {
-        $info = $uncategorized_tests[$class]->getInfo();
+        $info = $uncategorized_tests[$class];
         $ok = $element['summary']['#fail'] + $element['summary']['#exception'] == 0;
         $element += array(
           '#type' => 'fieldset',
@@ -166,9 +166,7 @@ function simpletest_test_form() {
     $form['tests']['table'][$group_name] = array(
       '#collapsed' => TRUE,
     );
-    foreach ($test_group as $test) {
-      $test_info = $test->getInfo();
-      $test_class = get_class($test);
+    foreach ($test_group as $test_class => $test_info) {
       $is_selected = isset($selected_tests[$group_name][$test_class]);
       $form['tests']['table'][$group_name][$test_class] = array(
         '#type' => 'checkbox',
@@ -321,13 +319,10 @@ function _simpletest_format_summary_line($summary) {
  * Run selected tests.
  */
 function simpletest_test_form_submit($form, &$form_state) {
-  // Ensure that all classes are loaded before we create instances to get test information and run.
-  simpletest_get_all_tests();
-
   // Get list of tests.
   $tests_list = array();
   foreach ($form_state['values'] as $class_name => $value) {
-    if (class_exists($class_name) && $value === 1) {
+    if ($value === 1) {
       $tests_list[] = $class_name;
     }
   }
@@ -349,14 +344,13 @@ function simpletest_test_form_submit($form, &$form_state) {
  *   drupal being the default.
  */
 function simpletest_run_tests($test_list, $reporter = 'drupal') {
+  $all_tests = simpletest_get_all_tests();
+
   cache_clear_all();
   $test_id = db_insert('simpletest_test_id')->useDefaults(array('test_id'))->execute();
 
   // Get the info for the first test being run.
-  $first_test = array_shift($test_list);
-  $first_instance = new $first_test();
-  array_unshift($test_list, $first_test);
-  $info = $first_instance->getInfo();
+  $info = $all_tests[reset($test_list)];
 
   $batch = array(
     'title' => t('Running SimpleTests'),
@@ -384,7 +378,7 @@ function simpletest_run_tests($test_list, $reporter = 'drupal') {
  */
 function _simpletest_batch_operation($test_list_init, $test_id, &$context) {
   // Ensure that all classes are loaded before we unserialize some instances.
-  simpletest_get_all_tests();
+  $all_tests = simpletest_get_all_tests();
 
   // Get working values.
   if (!isset($context['sandbox']['max'])) {
@@ -402,10 +396,13 @@ function _simpletest_batch_operation($test_list_init, $test_id, &$context) {
 
   // Perform the next test.
   $test_class = array_shift($test_list);
+  $info = $all_tests[$test_class];
+
+  require_once DRUPAL_ROOT . '/' . drupal_get_path('module', 'simpletest') . '/drupal_web_test_case.php';
+  require_once DRUPAL_ROOT . '/' . $info['filename'];
   $test = new $test_class($test_id);
   $test->run();
   $size = count($test_list);
-  $info = $test->getInfo();
 
   // Gather results and compose the report.
   $test_results[$test_class] = $test->results;
@@ -451,9 +448,9 @@ function _simpletest_batch_finished($success, $results, $operations, $elapsed) {
  *   versions of the classes as the values.
  */
 function simpletest_get_all_tests() {
-  static $formatted_classes;
-  if (!isset($formatted_classes)) {
-    require_once DRUPAL_ROOT . '/' . drupal_get_path('module', 'simpletest') . '/drupal_web_test_case.php';
+  static $classes;
+  if (!isset($classes)) {
+    // list all possible files candidates.
     $files = array();
     foreach (array_keys(module_rebuild_cache()) as $module) {
       $module_path = drupal_get_path('module', $module);
@@ -470,23 +467,51 @@ function simpletest_get_all_tests() {
       }
     }
 
-    $existing_classes = get_declared_classes();
-    foreach ($files as $file) {
-      include_once DRUPAL_ROOT . '/' . $file;
+    drupal_function_exists('_registry_parse_file');
+
+    // Build the dependency graph.
+    $classes = array();
+    $dependency_graph = array();
+    foreach ($files as $filename) {
+      $resources = _registry_parse_file(file_get_contents($filename));
+      foreach ($resources['class'] as $class_info) {
+        if (!empty($class_info['extends'])) {
+          $class_info['filename'] = $filename;
+          $classes[$class_info['name']] = $class_info;
+          $dependency_graph[$class_info['extends']]['edges'][$class_info['name']] = TRUE;
+        }
+      }
     }
-    $classes = array_values(array_diff(get_declared_classes(), $existing_classes));
-    $formatted_classes = array();
-    foreach ($classes as $key => $class) {
-      if (method_exists($class, 'getInfo')) {
-        $formatted_classes[$class] = new $class;
+
+    if (!isset($dependency_graph['DrupalWebTestCase'])) {
+      $classes = array();
+    }
+
+    drupal_depth_first_search($dependency_graph);
+
+    foreach ($dependency_graph['DrupalWebTestCase']['paths'] as $class_name => $dummy) {
+      $class_info = $classes[$class_name];
+      $test_group = 'Default';
+      $test_name = $class_name;
+      if (isset($classes[$class_name]['doc']['elements'])) {
+        foreach ($classes[$class_name]['doc']['elements'] as $tag) {
+          if ($tag['tag'] == 'test-group') {
+            $test_group = $tag['text'];
+          }
+          else if ($tag['tag'] == 'test-name') {
+            $test_name = $tag['text'];
+          }
+        }
       }
+      $classes[$class_name] = array(
+        'name' => $test_name,
+        'description' => isset($class_info['doc']['summary']) ? $class_info['doc']['summary'] : '',
+        'group' => $test_group,
+        'filename' => $class_info['filename'],
+      );
     }
   }
-  if (count($formatted_classes) == 0) {
-    drupal_set_message('No test cases found.', 'error');
-    return FALSE;
-  }
-  return $formatted_classes;
+  return $classes;
 }
 
 /**
@@ -498,9 +523,8 @@ function simpletest_get_all_tests() {
  */
 function simpletest_categorize_tests($tests) {
   $groups = array();
-  foreach ($tests as $test => $instance) {
-    $info = $instance->getInfo();
-    $groups[$info['group']][$test] = $instance;
+  foreach ($tests as $class_name => $info) {
+    $groups[$info['group']][$class_name] = $info;
   }
   uksort($groups, 'strnatcasecmp');
   return $groups;
