From 7e6fdd8540f0bddb68cc303ae769f043a6aea16d Mon Sep 17 00:00:00 2001
From: Angie Byron <webchick@24967.no-reply.drupal.org>
Date: Mon, 14 Dec 2009 19:24:10 +0000
Subject: [PATCH] #560646 by carlos8f and chx: Make SimpleTest catch Fatal PHP
 errors.

---
 modules/simpletest/drupal_web_test_case.php | 37 +++++++++++++++++++--
 1 file changed, 34 insertions(+), 3 deletions(-)

diff --git a/modules/simpletest/drupal_web_test_case.php b/modules/simpletest/drupal_web_test_case.php
index 646eb64b4c00..3c4a2396c241 100644
--- a/modules/simpletest/drupal_web_test_case.php
+++ b/modules/simpletest/drupal_web_test_case.php
@@ -148,7 +148,11 @@ protected function assert($status, $message = '', $group = 'Other', array $calle
    * the method behaves just like DrupalTestCase::assert() in terms of storing
    * the assertion.
    *
+   * @return
+   *   Message ID of the stored assertion.
+   *
    * @see DrupalTestCase::assert()
+   * @see DrupalTestCase::deleteAssert()
    */
   public static function insertAssert($test_id, $test_class, $status, $message = '', $group = 'Other', array $caller = array()) {
     // Convert boolean status to string status.
@@ -173,11 +177,27 @@ public static function insertAssert($test_id, $test_class, $status, $message = '
       'file' => $caller['file'],
     );
 
-    db_insert('simpletest')
+    return db_insert('simpletest')
       ->fields($assertion)
       ->execute();
   }
 
+  /**
+   * Delete an assertion record by message ID.
+   * 
+   * @param $message_id
+   *   Message ID of the assertion to delete.
+   * @return
+   *   TRUE if the assertion was deleted, FALSE otherwise.
+   * 
+   * @see DrupalTestCase::insertAssert()
+   */
+  public static function deleteAssert($message_id) {
+    return (bool) db_delete('simpletest')
+      ->condition('message_id', $message_id)
+      ->execute();
+  }
+
   /**
    * Cycles through backtrace until the first non-assertion method is found.
    *
@@ -402,11 +422,20 @@ public function run() {
     }
 
     set_error_handler(array($this, 'errorHandler'));
-    $methods = array();
+    $class = get_class($this);
     // Iterate through all the methods in this class.
-    foreach (get_class_methods(get_class($this)) as $method) {
+    foreach (get_class_methods($class) as $method) {
       // If the current method starts with "test", run it - it's a test.
       if (strtolower(substr($method, 0, 4)) == 'test') {
+        // Insert a fail record. This will be deleted on completion to ensure
+        // that testing completed.
+        $method_info = new ReflectionMethod($class, $method);
+        $caller = array(
+          'file' => $method_info->getFileName(),
+          'line' => $method_info->getStartLine(),
+          'function' => $class . '->' . $method . '()',
+        );
+        $completion_check_id = DrupalTestCase::insertAssert($this->testId, $class, FALSE, t('The test did not complete due to a fatal error.'), 'Completion check', $caller);
         $this->setUp();
         try {
           $this->$method();
@@ -416,6 +445,8 @@ public function run() {
           $this->exceptionHandler($e);
         }
         $this->tearDown();
+        // Remove the completion check record.
+        DrupalTestCase::deleteAssert($completion_check_id);
       }
     }
     // Clear out the error messages and restore error handler.
-- 
GitLab