Index: modules/simpletest/simpletest.module =================================================================== RCS file: /cvs/drupal/drupal/modules/simpletest/simpletest.module,v retrieving revision 1.64 diff -u -r1.64 simpletest.module --- modules/simpletest/simpletest.module 13 Aug 2009 11:31:26 -0000 1.64 +++ modules/simpletest/simpletest.module 15 Aug 2009 04:04:35 -0000 @@ -95,11 +95,16 @@ } function _simpletest_format_summary_line($summary) { - return t('@pass, @fail, and @exception', array( + $args = array( '@pass' => format_plural(isset($summary['#pass']) ? $summary['#pass'] : 0, '1 pass', '@count passes'), '@fail' => format_plural(isset($summary['#fail']) ? $summary['#fail'] : 0, '1 fail', '@count fails'), '@exception' => format_plural(isset($summary['#exception']) ? $summary['#exception'] : 0, '1 exception', '@count exceptions'), - )); + ); + if (!$summary['#debug']) { + return t('@pass, @fail, and @exception', $args); + } + $args['@debug'] = format_plural(isset($summary['#debug']) ? $summary['#debug'] : 0, '1 debug message', '@count debug messages'); + return t('@pass, @fail, @exception, and @debug', $args); } /** @@ -155,7 +160,7 @@ // First iteration: initialize working values. $test_list = $test_list_init; $context['sandbox']['max'] = count($test_list); - $test_results = array('#pass' => 0, '#fail' => 0, '#exception' => 0); + $test_results = array('#pass' => 0, '#fail' => 0, '#exception' => 0, '#debug' => 0); } else { // Nth iteration: get the current values where we last stored them. Index: modules/simpletest/drupal_web_test_case.php =================================================================== RCS file: /cvs/drupal/drupal/modules/simpletest/drupal_web_test_case.php,v retrieving revision 1.134 diff -u -r1.134 drupal_web_test_case.php --- modules/simpletest/drupal_web_test_case.php 5 Aug 2009 15:58:35 -0000 1.134 +++ modules/simpletest/drupal_web_test_case.php 15 Aug 2009 04:04:35 -0000 @@ -42,6 +42,7 @@ '#pass' => 0, '#fail' => 0, '#exception' => 0, + '#debug' => 0, ); /** @@ -376,6 +377,12 @@ * FALSE. */ protected function error($message = '', $group = 'Other', array $caller = NULL) { + if ($group == 'User notice') { + // Since 'User notice' is set by trigger_error() which is used for debug + // set the message to a status of 'debug'. + return $this->assert('debug', $message, 'Debug', $caller); + } + return $this->assert('exception', $message, $group, $caller); } Index: modules/simpletest/simpletest.pages.inc =================================================================== RCS file: /cvs/drupal/drupal/modules/simpletest/simpletest.pages.inc,v retrieving revision 1.12 diff -u -r1.12 simpletest.pages.inc --- modules/simpletest/simpletest.pages.inc 13 Aug 2009 11:31:26 -0000 1.12 +++ modules/simpletest/simpletest.pages.inc 15 Aug 2009 04:04:35 -0000 @@ -226,6 +226,7 @@ '#pass' => 0, '#fail' => 0, '#exception' => 0, + '#debug' => 0, ); // Cycle through each test group. @@ -264,14 +265,14 @@ $form['result']['summary']['#' . $assertion->status]++; } $form['result']['results'][$group]['table'] = array( - '#theme' => 'table', - '#header' => $header, + '#theme' => 'table', + '#header' => $header, '#rows' => $rows, ); // Set summary information. $group_summary['#ok'] = $group_summary['#fail'] + $group_summary['#exception'] == 0; - $form['result']['results'][$group]['#collapsed'] = $group_summary['#ok']; + $form['result']['results'][$group]['#collapsed'] = $group_summary['#ok'] && !$group_summary['#debug']; // Store test group (class) as for use in filter. $filter[$group_summary['#ok'] ? 'pass' : 'fail'][] = $group; @@ -404,6 +405,7 @@ 'pass' => theme('image', 'misc/watchdog-ok.png'), 'fail' => theme('image', 'misc/watchdog-error.png'), 'exception' => theme('image', 'misc/watchdog-warning.png'), + 'debug' => theme('image', 'misc/watchdog-warning.png'), ); } if (isset($map[$status])) { Index: modules/simpletest/simpletest.test =================================================================== RCS file: /cvs/drupal/drupal/modules/simpletest/simpletest.test,v retrieving revision 1.28 diff -u -r1.28 simpletest.test --- modules/simpletest/simpletest.test 13 Aug 2009 11:31:26 -0000 1.28 +++ modules/simpletest/simpletest.test 15 Aug 2009 04:04:35 -0000 @@ -121,6 +121,8 @@ // Generates a warning inside a PHP function. array_key_exists(NULL, NULL); + + debug('Foo', 'Debug'); } /** @@ -151,6 +153,10 @@ // the function name 'array_key_exists'. $this->assertAssertion('array_key_exists', 'Warning', 'Fail', 'simpletest.test', 'SimpleTestFunctionalTest->stubTest()'); + $this->assertAssertion("Debug: 'Foo'", 'Debug', 'Fail', 'simpletest.test', 'SimpleTestFunctionalTest->stubTest()'); + + $this->assertEqual('6 passes, 2 fails, 2 exceptions, and 1 debug message', $this->childTestResults['summary'], 'Stub test summary is correct'); + $this->test_ids[] = $test_id = $this->getTestIdFromResults(); $this->assertTrue($test_id, t('Found test ID in results.')); } @@ -202,7 +208,7 @@ if ($this->parse()) { if ($fieldset = $this->getResultFieldSet()) { // Code assumes this is the only test in group. - $results['summary'] = $this->asText($fieldset->div); + $results['summary'] = $this->asText($fieldset->div[1]); $results['name'] = $this->asText($fieldset->legend); $results['assertions'] = array(); Index: modules/simpletest/tests/common.test =================================================================== RCS file: /cvs/drupal/drupal/modules/simpletest/tests/common.test,v retrieving revision 1.59 diff -u -r1.59 common.test --- modules/simpletest/tests/common.test 14 Aug 2009 16:15:38 -0000 1.59 +++ modules/simpletest/tests/common.test 15 Aug 2009 04:04:35 -0000 @@ -1054,7 +1054,7 @@ if (count($this->collectedErrors) == 3) { $this->assertError($this->collectedErrors[0], 'Notice', 'error_test_generate_warnings()', 'error_test.module', 'Undefined variable: bananas'); $this->assertError($this->collectedErrors[1], 'Warning', 'error_test_generate_warnings()', 'error_test.module', 'Division by zero'); - $this->assertError($this->collectedErrors[2], 'User notice', 'error_test_generate_warnings()', 'error_test.module', 'Drupal is awesome'); + $this->assertError($this->collectedErrors[2], 'User warning', 'error_test_generate_warnings()', 'error_test.module', 'Drupal is awesome'); } else { // Give back the errors to the log report. Index: modules/simpletest/tests/error.test =================================================================== RCS file: /cvs/drupal/drupal/modules/simpletest/tests/error.test,v retrieving revision 1.4 diff -u -r1.4 error.test --- modules/simpletest/tests/error.test 13 Jul 2009 21:51:41 -0000 1.4 +++ modules/simpletest/tests/error.test 15 Aug 2009 04:04:35 -0000 @@ -36,7 +36,7 @@ '%file' => realpath('modules/simpletest/tests/error_test.module'), ); $error_user_notice = array( - '%type' => 'User notice', + '%type' => 'User warning', '%message' => 'Drupal is awesome', '%function' => 'error_test_generate_warnings()', '%line' => 48, Index: modules/simpletest/tests/error_test.module =================================================================== RCS file: /cvs/drupal/drupal/modules/simpletest/tests/error_test.module,v retrieving revision 1.3 diff -u -r1.3 error_test.module --- modules/simpletest/tests/error_test.module 30 May 2009 11:17:32 -0000 1.3 +++ modules/simpletest/tests/error_test.module 15 Aug 2009 04:04:35 -0000 @@ -45,7 +45,7 @@ // This will generate a warning. $awesomely_big = 1/0; // This will generate a user error. - trigger_error("Drupal is awesome", E_USER_NOTICE); + trigger_error("Drupal is awesome", E_USER_WARNING); return ""; } Index: includes/common.inc =================================================================== RCS file: /cvs/drupal/drupal/includes/common.inc,v retrieving revision 1.960 diff -u -r1.960 common.inc --- includes/common.inc 14 Aug 2009 16:15:38 -0000 1.960 +++ includes/common.inc 15 Aug 2009 04:04:35 -0000 @@ -873,7 +873,16 @@ $error_level = variable_get('error_level', ERROR_REPORTING_DISPLAY_ALL); $display_error = $error_level == ERROR_REPORTING_DISPLAY_ALL || ($error_level == ERROR_REPORTING_DISPLAY_SOME && $error['%type'] != 'Notice'); if ($display_error || (defined('MAINTENANCE_MODE') && MAINTENANCE_MODE == 'update')) { - drupal_set_message(t('%type: %message in %function (line %line of %file).', $error), 'error'); + $class = 'error'; + + // If error type is 'User notice' then treat it as debug information + // instead of an error message, see dd(). + if ($error['%type'] == 'User notice') { + $error['%type'] = 'Debug'; + $class = 'status'; + } + + drupal_set_message(t('%type: %message in %function (line %line of %file).', $error), $class); } if ($fatal) { @@ -895,9 +904,11 @@ * An associative array with keys 'file', 'line' and 'function'. */ function _drupal_get_last_caller($backtrace) { - // Errors that occur inside PHP internal functions - // do not generate information about file and line. - while ($backtrace && !isset($backtrace[0]['line'])) { + // Errors that occur inside PHP internal functions do not generate + // information about file and line. Ignore black listed functions. + $blacklist = array('debug'); + while (($backtrace && !isset($backtrace[0]['line'])) || + (isset($backtrace[1]['function']) && in_array($backtrace[1]['function'], $blacklist))) { array_shift($backtrace); } @@ -2333,14 +2344,14 @@ * In other words, if the timeout is the default 30 seconds, and 25 seconds * into script execution a call such as set_time_limit(20) is made, the * script will run for a total of 45 seconds before timing out. - * + * * It also means that it is possible to decrease the total time limit if * the sum of the new time limit and the current time spent running the * script is inferior to the original time limit. It is inherent to the way * set_time_limit() works, it should rather be called with an appropriate * value every time you need to allocate a certain amount of time * to execute a task than only once at the beginning of the script. - * + * * Before calling set_time_limit(), we check if this function is available * because it could be disabled by the server administrator. We also hide all * the errors that could occur when calling set_time_limit(), because it is @@ -4930,6 +4941,27 @@ } /** + * Debug function used for outputting debug information. + * + * The debug information is passed on to trigger_error() after being converted + * to a string using _drupal_debug_message(). + * + * @param $data + * Data to be output. + * @param $label + * Label to prefix the data. + * @param $print_r + * Flag to switch between print_r() and var_export() for data conversion to + * string. Set $print_r to TRUE when dealing with a recursive data structure + * as var_export() will generate an error. + */ +function debug($data, $label = NULL, $print_r = FALSE) { + // Print $data contents to string. + $string = $print_r ? print_r($data, TRUE) : var_export($data, TRUE); + trigger_error(trim($label ? "$label: $string" : $string)); +} + +/** * Parse a dependency for comparison by drupal_check_incompatibility(). * * @param $dependency